[readdir] convert ubifs
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 16 May 2013 05:14:46 +0000 (01:14 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 29 Jun 2013 08:56:25 +0000 (12:56 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ubifs/dir.c

index 605af51..6b4947f 100644 (file)
@@ -346,19 +346,18 @@ static unsigned int vfs_dent_type(uint8_t type)
  * This means that UBIFS cannot support NFS which requires full
  * 'seekdir()'/'telldir()' support.
  */
-static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
+static int ubifs_readdir(struct file *file, struct dir_context *ctx)
 {
-       int err, over = 0;
-       loff_t pos = file->f_pos;
+       int err;
        struct qstr nm;
        union ubifs_key key;
        struct ubifs_dent_node *dent;
        struct inode *dir = file_inode(file);
        struct ubifs_info *c = dir->i_sb->s_fs_info;
 
-       dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos);
+       dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
 
-       if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
+       if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2)
                /*
                 * The directory was seek'ed to a senseless position or there
                 * are no more entries.
@@ -384,19 +383,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
        file->f_version = 1;
 
        /* File positions 0 and 1 correspond to "." and ".." */
-       if (pos == 0) {
-               ubifs_assert(!file->private_data);
-               over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
-               if (over)
-                       return 0;
-               file->f_pos = pos = 1;
-       }
-
-       if (pos == 1) {
+       if (ctx->pos < 2) {
                ubifs_assert(!file->private_data);
-               over = filldir(dirent, "..", 2, 1,
-                              parent_ino(file->f_path.dentry), DT_DIR);
-               if (over)
+               if (!dir_emit_dots(file, ctx))
                        return 0;
 
                /* Find the first entry in TNC and save it */
@@ -408,7 +397,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
                        goto out;
                }
 
-               file->f_pos = pos = key_hash_flash(c, &dent->key);
+               ctx->pos = key_hash_flash(c, &dent->key);
                file->private_data = dent;
        }
 
@@ -416,16 +405,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
        if (!dent) {
                /*
                 * The directory was seek'ed to and is now readdir'ed.
-                * Find the entry corresponding to @pos or the closest one.
+                * Find the entry corresponding to @ctx->pos or the closest one.
                 */
-               dent_key_init_hash(c, &key, dir->i_ino, pos);
+               dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
                nm.name = NULL;
                dent = ubifs_tnc_next_ent(c, &key, &nm);
                if (IS_ERR(dent)) {
                        err = PTR_ERR(dent);
                        goto out;
                }
-               file->f_pos = pos = key_hash_flash(c, &dent->key);
+               ctx->pos = key_hash_flash(c, &dent->key);
                file->private_data = dent;
        }
 
@@ -437,10 +426,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
                             ubifs_inode(dir)->creat_sqnum);
 
                nm.len = le16_to_cpu(dent->nlen);
-               over = filldir(dirent, dent->name, nm.len, pos,
+               if (!dir_emit(ctx, dent->name, nm.len,
                               le64_to_cpu(dent->inum),
-                              vfs_dent_type(dent->type));
-               if (over)
+                              vfs_dent_type(dent->type)))
                        return 0;
 
                /* Switch to the next entry */
@@ -453,17 +441,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
                }
 
                kfree(file->private_data);
-               file->f_pos = pos = key_hash_flash(c, &dent->key);
+               ctx->pos = key_hash_flash(c, &dent->key);
                file->private_data = dent;
                cond_resched();
-
-               if (file->f_version == 0)
-                       /*
-                        * The file was seek'ed meanwhile, lets return and start
-                        * reading direntries from the new position on the next
-                        * invocation.
-                        */
-                       return 0;
        }
 
 out:
@@ -475,15 +455,10 @@ out:
        kfree(file->private_data);
        file->private_data = NULL;
        /* 2 is a special value indicating that there are no more direntries */
-       file->f_pos = 2;
+       ctx->pos = 2;
        return 0;
 }
 
-static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
-{
-       return generic_file_llseek(file, offset, whence);
-}
-
 /* Free saved readdir() state when the directory is closed */
 static int ubifs_dir_release(struct inode *dir, struct file *file)
 {
@@ -1201,10 +1176,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
 };
 
 const struct file_operations ubifs_dir_operations = {
-       .llseek         = ubifs_dir_llseek,
+       .llseek         = generic_file_llseek,
        .release        = ubifs_dir_release,
        .read           = generic_read_dir,
-       .readdir        = ubifs_readdir,
+       .iterate        = ubifs_readdir,
        .fsync          = ubifs_fsync,
        .unlocked_ioctl = ubifs_ioctl,
 #ifdef CONFIG_COMPAT