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

index 7aabc6ad4e9bbda4cec09f30545f7d828b0c431a..64e5323cbbb014c4c2240c733d667b2e704bcdcc 100644 (file)
@@ -1532,84 +1532,66 @@ static inline unsigned char dt_type(struct configfs_dirent *sd)
        return (sd->s_mode >> 12) & 15;
 }
 
-static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
+static int configfs_readdir(struct file *file, struct dir_context *ctx)
 {
-       struct dentry *dentry = filp->f_path.dentry;
+       struct dentry *dentry = file->f_path.dentry;
        struct super_block *sb = dentry->d_sb;
        struct configfs_dirent * parent_sd = dentry->d_fsdata;
-       struct configfs_dirent *cursor = filp->private_data;
+       struct configfs_dirent *cursor = file->private_data;
        struct list_head *p, *q = &cursor->s_sibling;
        ino_t ino = 0;
-       int i = filp->f_pos;
 
-       switch (i) {
-               case 0:
-                       ino = dentry->d_inode->i_ino;
-                       if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
-                               break;
-                       filp->f_pos++;
-                       i++;
-                       /* fallthrough */
-               case 1:
-                       ino = parent_ino(dentry);
-                       if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
-                               break;
-                       filp->f_pos++;
-                       i++;
-                       /* fallthrough */
-               default:
-                       if (filp->f_pos == 2) {
-                               spin_lock(&configfs_dirent_lock);
-                               list_move(q, &parent_sd->s_children);
-                               spin_unlock(&configfs_dirent_lock);
-                       }
-                       for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
-                               struct configfs_dirent *next;
-                               const char * name;
-                               int len;
-                               struct inode *inode = NULL;
+       if (!dir_emit_dots(file, ctx))
+               return 0;
+       if (ctx->pos == 2) {
+               spin_lock(&configfs_dirent_lock);
+               list_move(q, &parent_sd->s_children);
+               spin_unlock(&configfs_dirent_lock);
+       }
+       for (p = q->next; p != &parent_sd->s_children; p = p->next) {
+               struct configfs_dirent *next;
+               const char *name;
+               int len;
+               struct inode *inode = NULL;
+
+               next = list_entry(p, struct configfs_dirent, s_sibling);
+               if (!next->s_element)
+                       continue;
 
-                               next = list_entry(p, struct configfs_dirent,
-                                                  s_sibling);
-                               if (!next->s_element)
-                                       continue;
-
-                               name = configfs_get_name(next);
-                               len = strlen(name);
-
-                               /*
-                                * We'll have a dentry and an inode for
-                                * PINNED items and for open attribute
-                                * files.  We lock here to prevent a race
-                                * with configfs_d_iput() clearing
-                                * s_dentry before calling iput().
-                                *
-                                * Why do we go to the trouble?  If
-                                * someone has an attribute file open,
-                                * the inode number should match until
-                                * they close it.  Beyond that, we don't
-                                * care.
-                                */
-                               spin_lock(&configfs_dirent_lock);
-                               dentry = next->s_dentry;
-                               if (dentry)
-                                       inode = dentry->d_inode;
-                               if (inode)
-                                       ino = inode->i_ino;
-                               spin_unlock(&configfs_dirent_lock);
-                               if (!inode)
-                                       ino = iunique(sb, 2);
+               name = configfs_get_name(next);
+               len = strlen(name);
+
+               /*
+                * We'll have a dentry and an inode for
+                * PINNED items and for open attribute
+                * files.  We lock here to prevent a race
+                * with configfs_d_iput() clearing
+                * s_dentry before calling iput().
+                *
+                * Why do we go to the trouble?  If
+                * someone has an attribute file open,
+                * the inode number should match until
+                * they close it.  Beyond that, we don't
+                * care.
+                */
+               spin_lock(&configfs_dirent_lock);
+               dentry = next->s_dentry;
+               if (dentry)
+                       inode = dentry->d_inode;
+               if (inode)
+                       ino = inode->i_ino;
+               spin_unlock(&configfs_dirent_lock);
+               if (!inode)
+                       ino = iunique(sb, 2);
 
-                               if (filldir(dirent, name, len, filp->f_pos, ino,
-                                                dt_type(next)) < 0)
-                                       return 0;
+               if (!dir_emit(ctx, name, len, ino, dt_type(next)))
+                       return 0;
 
-                               spin_lock(&configfs_dirent_lock);
-                               list_move(q, p);
-                               spin_unlock(&configfs_dirent_lock);
-                               p = q;
-                               filp->f_pos++;
-                       }
+               spin_lock(&configfs_dirent_lock);
+               list_move(q, p);
+               spin_unlock(&configfs_dirent_lock);
+               p = q;
+               ctx->pos++;
        }
        return 0;
 }
@@ -1661,7 +1643,7 @@ const struct file_operations configfs_dir_operations = {
        .release        = configfs_dir_close,
        .llseek         = configfs_dir_lseek,
        .read           = generic_read_dir,
-       .readdir        = configfs_readdir,
+       .iterate        = configfs_readdir,
 };
 
 int configfs_register_subsystem(struct configfs_subsystem *subsys)