[readdir] convert ntfs
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 18 May 2013 01:22:31 +0000 (21:22 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 29 Jun 2013 08:56:48 +0000 (12:56 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ntfs/dir.c

index aa411c3f20e932e39eefeaf2cb6b4435a7a1aeaa..9e38dafa3bc78ec71acc7acec733d9cd52c4f40a 100644 (file)
@@ -1004,13 +1004,11 @@ dir_err_out:
 /**
  * ntfs_filldir - ntfs specific filldir method
  * @vol:       current ntfs volume
- * @fpos:      position in the directory
  * @ndir:      ntfs inode of current directory
  * @ia_page:   page in which the index allocation buffer @ie is in resides
  * @ie:                current index entry
  * @name:      buffer to use for the converted name
- * @dirent:    vfs filldir callback context
- * @filldir:   vfs filldir callback
+ * @actor:     what to feed the entries to
  *
  * Convert the Unicode @name to the loaded NLS and pass it to the @filldir
  * callback.
@@ -1024,12 +1022,12 @@ dir_err_out:
  * retake the lock if we are returning a non-zero value as ntfs_readdir()
  * would need to drop the lock immediately anyway.
  */
-static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
+static inline int ntfs_filldir(ntfs_volume *vol,
                ntfs_inode *ndir, struct page *ia_page, INDEX_ENTRY *ie,
-               u8 *name, void *dirent, filldir_t filldir)
+               u8 *name, struct dir_context *actor)
 {
        unsigned long mref;
-       int name_len, rc;
+       int name_len;
        unsigned dt_type;
        FILE_NAME_TYPE_FLAGS name_type;
 
@@ -1068,13 +1066,14 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
        if (ia_page)
                unlock_page(ia_page);
        ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode "
-                       "0x%lx, DT_%s.", name, name_len, fpos, mref,
+                       "0x%lx, DT_%s.", name, name_len, actor->pos, mref,
                        dt_type == DT_DIR ? "DIR" : "REG");
-       rc = filldir(dirent, name, name_len, fpos, mref, dt_type);
+       if (!dir_emit(actor, name, name_len, mref, dt_type))
+               return 1;
        /* Relock the page but not if we are aborting ->readdir. */
-       if (!rc && ia_page)
+       if (ia_page)
                lock_page(ia_page);
-       return rc;
+       return 0;
 }
 
 /*
@@ -1097,11 +1096,11 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
  *            removes them again after the write is complete after which it 
  *            unlocks the page.
  */
-static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int ntfs_readdir(struct file *file, struct dir_context *actor)
 {
        s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;
-       loff_t fpos, i_size;
-       struct inode *bmp_vi, *vdir = file_inode(filp);
+       loff_t i_size;
+       struct inode *bmp_vi, *vdir = file_inode(file);
        struct super_block *sb = vdir->i_sb;
        ntfs_inode *ndir = NTFS_I(vdir);
        ntfs_volume *vol = NTFS_SB(sb);
@@ -1116,33 +1115,16 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        u8 *kaddr, *bmp, *index_end;
        ntfs_attr_search_ctx *ctx;
 
-       fpos = filp->f_pos;
        ntfs_debug("Entering for inode 0x%lx, fpos 0x%llx.",
-                       vdir->i_ino, fpos);
+                       vdir->i_ino, actor->pos);
        rc = err = 0;
        /* Are we at end of dir yet? */
        i_size = i_size_read(vdir);
-       if (fpos >= i_size + vol->mft_record_size)
-               goto done;
+       if (actor->pos >= i_size + vol->mft_record_size)
+               return 0;
        /* Emulate . and .. for all directories. */
-       if (!fpos) {
-               ntfs_debug("Calling filldir for . with len 1, fpos 0x0, "
-                               "inode 0x%lx, DT_DIR.", vdir->i_ino);
-               rc = filldir(dirent, ".", 1, fpos, vdir->i_ino, DT_DIR);
-               if (rc)
-                       goto done;
-               fpos++;
-       }
-       if (fpos == 1) {
-               ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, "
-                               "inode 0x%lx, DT_DIR.",
-                               (unsigned long)parent_ino(filp->f_path.dentry));
-               rc = filldir(dirent, "..", 2, fpos,
-                               parent_ino(filp->f_path.dentry), DT_DIR);
-               if (rc)
-                       goto done;
-               fpos++;
-       }
+       if (!dir_emit_dots(file, actor))
+               return 0;
        m = NULL;
        ctx = NULL;
        /*
@@ -1155,7 +1137,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                goto err_out;
        }
        /* Are we jumping straight into the index allocation attribute? */
-       if (fpos >= vol->mft_record_size)
+       if (actor->pos >= vol->mft_record_size)
                goto skip_index_root;
        /* Get hold of the mft record for the directory. */
        m = map_mft_record(ndir);
@@ -1170,7 +1152,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                goto err_out;
        }
        /* Get the offset into the index root attribute. */
-       ir_pos = (s64)fpos;
+       ir_pos = (s64)actor->pos;
        /* Find the index root attribute in the mft record. */
        err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
                        0, ctx);
@@ -1226,10 +1208,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                if (ir_pos > (u8*)ie - (u8*)ir)
                        continue;
                /* Advance the position even if going to skip the entry. */
-               fpos = (u8*)ie - (u8*)ir;
+               actor->pos = (u8*)ie - (u8*)ir;
                /* Submit the name to the filldir callback. */
-               rc = ntfs_filldir(vol, fpos, ndir, NULL, ie, name, dirent,
-                               filldir);
+               rc = ntfs_filldir(vol, ndir, NULL, ie, name, actor);
                if (rc) {
                        kfree(ir);
                        goto abort;
@@ -1242,12 +1223,12 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (!NInoIndexAllocPresent(ndir))
                goto EOD;
        /* Advance fpos to the beginning of the index allocation. */
-       fpos = vol->mft_record_size;
+       actor->pos = vol->mft_record_size;
 skip_index_root:
        kaddr = NULL;
        prev_ia_pos = -1LL;
        /* Get the offset into the index allocation attribute. */
-       ia_pos = (s64)fpos - vol->mft_record_size;
+       ia_pos = (s64)actor->pos - vol->mft_record_size;
        ia_mapping = vdir->i_mapping;
        ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino);
        bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4);
@@ -1409,7 +1390,7 @@ find_next_index_buffer:
                if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
                        continue;
                /* Advance the position even if going to skip the entry. */
-               fpos = (u8*)ie - (u8*)ia +
+               actor->pos = (u8*)ie - (u8*)ia +
                                (sle64_to_cpu(ia->index_block_vcn) <<
                                ndir->itype.index.vcn_size_bits) +
                                vol->mft_record_size;
@@ -1419,8 +1400,7 @@ find_next_index_buffer:
                 * before returning, unless a non-zero value is returned in
                 * which case the page is left unlocked.
                 */
-               rc = ntfs_filldir(vol, fpos, ndir, ia_page, ie, name, dirent,
-                               filldir);
+               rc = ntfs_filldir(vol, ndir, ia_page, ie, name, actor);
                if (rc) {
                        /* @ia_page is already unlocked in this case. */
                        ntfs_unmap_page(ia_page);
@@ -1439,18 +1419,9 @@ unm_EOD:
        iput(bmp_vi);
 EOD:
        /* We are finished, set fpos to EOD. */
-       fpos = i_size + vol->mft_record_size;
+       actor->pos = i_size + vol->mft_record_size;
 abort:
        kfree(name);
-done:
-#ifdef DEBUG
-       if (!rc)
-               ntfs_debug("EOD, fpos 0x%llx, returning 0.", fpos);
-       else
-               ntfs_debug("filldir returned %i, fpos 0x%llx, returning 0.",
-                               rc, fpos);
-#endif
-       filp->f_pos = fpos;
        return 0;
 err_out:
        if (bmp_page) {
@@ -1471,7 +1442,6 @@ iput_err_out:
        if (!err)
                err = -EIO;
        ntfs_debug("Failed. Returning error code %i.", -err);
-       filp->f_pos = fpos;
        return err;
 }
 
@@ -1571,7 +1541,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
 const struct file_operations ntfs_dir_ops = {
        .llseek         = generic_file_llseek,  /* Seek inside directory. */
        .read           = generic_read_dir,     /* Return -EISDIR. */
-       .readdir        = ntfs_readdir,         /* Read directory contents. */
+       .iterate        = ntfs_readdir,         /* Read directory contents. */
 #ifdef NTFS_RW
        .fsync          = ntfs_dir_fsync,       /* Sync a directory to disk. */
        /*.aio_fsync    = ,*/                   /* Sync all outstanding async