Diff for /xfs-linux/linux-2.6/xfs_file.c between versions 1.158 and 1.159

version 1.158, 2007/09/12 16:25:51 version 1.159, 2007/12/06 15:07:39
Line 219  xfs_vm_fault( Line 219  xfs_vm_fault(
 }  }
 #endif /* HAVE_DMAPI */  #endif /* HAVE_DMAPI */
   
   /*
    * Unfortunately we can't just use the clean and simple readdir implementation
    * below, because nfs might call back into ->lookup from the filldir callback
    * and that will deadlock the low-level btree code.
    *
    * Hopefully we'll find a better workaround that allows to use the optimal
    * version at least for local readdirs for 2.6.25.
    */
   #if 0
 STATIC int  STATIC int
 xfs_file_readdir(  xfs_file_readdir(
         struct file     *filp,          struct file     *filp,
Line 250  xfs_file_readdir( Line 259  xfs_file_readdir(
                 return -error;                  return -error;
         return 0;          return 0;
 }  }
   #else
   
   struct hack_dirent {
           int             namlen;
           loff_t          offset;
           u64             ino;
           unsigned int    d_type;
           char            name[];
   };
   
   struct hack_callback {
           char            *dirent;
           size_t          len;
           size_t          used;
   };
   
   STATIC int
   xfs_hack_filldir(
           void            *__buf,
           const char      *name,
           int             namlen,
           loff_t          offset,
           u64             ino,
           unsigned int    d_type)
   {
           struct hack_callback *buf = __buf;
           struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used);
   
           if (buf->used + sizeof(struct hack_dirent) + namlen > buf->len)
                   return -EINVAL;
   
           de->namlen = namlen;
           de->offset = offset;
           de->ino = ino;
           de->d_type = d_type;
           memcpy(de->name, name, namlen);
           buf->used += sizeof(struct hack_dirent) + namlen;
           return 0;
   }
   
   STATIC int
   xfs_file_readdir(
           struct file     *filp,
           void            *dirent,
           filldir_t       filldir)
   {
           struct inode    *inode = filp->f_path.dentry->d_inode;
           xfs_inode_t     *ip = XFS_I(inode);
           struct hack_callback buf;
           struct hack_dirent *de;
           int             error;
           loff_t          size;
           int             eof = 0;
           xfs_off_t       start_offset, curr_offset, offset;
   
           /*
            * Try fairly hard to get memory
            */
           buf.len = PAGE_CACHE_SIZE;
           do {
                   buf.dirent = kmalloc(buf.len, GFP_KERNEL);
                   if (buf.dirent)
                           break;
                   buf.len >>= 1;
           } while (buf.len >= 1024);
   
           if (!buf.dirent)
                   return -ENOMEM;
   
           curr_offset = filp->f_pos;
           if (curr_offset == 0x7fffffff)
                   offset = 0xffffffff;
           else
                   offset = filp->f_pos;
   
           while (!eof) {
                   int reclen;
                   start_offset = offset;
   
                   buf.used = 0;
                   error = -xfs_readdir(ip, &buf, buf.len, &offset,
                                        xfs_hack_filldir);
                   if (error || offset == start_offset) {
                           size = 0;
                           break;
                   }
   
                   size = buf.used;
                   de = (struct hack_dirent *)buf.dirent;
                   while (size > 0) {
                           if (filldir(dirent, de->name, de->namlen,
                                           curr_offset & 0x7fffffff,
                                           de->ino, de->d_type)) {
                                   goto done;
                           }
   
                           reclen = sizeof(struct hack_dirent) + de->namlen;
                           size -= reclen;
                           curr_offset = de->offset /* & 0x7fffffff */;
                           de = (struct hack_dirent *)((char *)de + reclen);
                   }
           }
   
    done:
           if (!error) {
                   if (size == 0)
                           filp->f_pos = offset & 0x7fffffff;
                   else if (de)
                           filp->f_pos = curr_offset;
           }
   
           kfree(buf.dirent);
           return error;
   }
   #endif
   
 STATIC int  STATIC int
 xfs_file_mmap(  xfs_file_mmap(

Removed from v.1.158  
changed lines
  Added in v.1.159


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>