Commit 5f99f4e79abc64ed9d93a4b0158b21c64ff7f478

Authored by Al Viro
1 parent 80886298c0

[readdir] switch dcache_readdir() users to ->iterate()

new helpers - dir_emit_dot(file, ctx, dentry), dir_emit_dotdot(file, ctx),
dir_emit_dots(file, ctx).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 4 changed files with 65 additions and 60 deletions Side-by-side Diff

arch/powerpc/platforms/cell/spufs/inode.c
... ... @@ -238,7 +238,7 @@
238 238 .release = spufs_dir_close,
239 239 .llseek = dcache_dir_lseek,
240 240 .read = generic_read_dir,
241   - .readdir = dcache_readdir,
  241 + .iterate = dcache_readdir,
242 242 .fsync = noop_fsync,
243 243 };
244 244 EXPORT_SYMBOL_GPL(spufs_context_fops);
... ... @@ -41,7 +41,7 @@
41 41 .open = dcache_dir_open,
42 42 .release = dcache_dir_close,
43 43 .read = generic_read_dir,
44   - .readdir = dcache_readdir,
  44 + .iterate = dcache_readdir,
45 45 .llseek = dcache_dir_lseek,
46 46 .unlocked_ioctl = autofs4_root_ioctl,
47 47 #ifdef CONFIG_COMPAT
... ... @@ -53,7 +53,7 @@
53 53 .open = autofs4_dir_open,
54 54 .release = dcache_dir_close,
55 55 .read = generic_read_dir,
56   - .readdir = dcache_readdir,
  56 + .iterate = dcache_readdir,
57 57 .llseek = dcache_dir_lseek,
58 58 };
59 59  
... ... @@ -135,60 +135,40 @@
135 135 * both impossible due to the lock on directory.
136 136 */
137 137  
138   -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
  138 +int dcache_readdir(struct file *file, struct dir_context *ctx)
139 139 {
140   - struct dentry *dentry = filp->f_path.dentry;
141   - struct dentry *cursor = filp->private_data;
  140 + struct dentry *dentry = file->f_path.dentry;
  141 + struct dentry *cursor = file->private_data;
142 142 struct list_head *p, *q = &cursor->d_u.d_child;
143   - ino_t ino;
144   - int i = filp->f_pos;
145 143  
146   - switch (i) {
147   - case 0:
148   - ino = dentry->d_inode->i_ino;
149   - if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
150   - break;
151   - filp->f_pos++;
152   - i++;
153   - /* fallthrough */
154   - case 1:
155   - ino = parent_ino(dentry);
156   - if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
157   - break;
158   - filp->f_pos++;
159   - i++;
160   - /* fallthrough */
161   - default:
162   - spin_lock(&dentry->d_lock);
163   - if (filp->f_pos == 2)
164   - list_move(q, &dentry->d_subdirs);
  144 + if (!dir_emit_dots(file, ctx))
  145 + return 0;
  146 + spin_lock(&dentry->d_lock);
  147 + if (ctx->pos == 2)
  148 + list_move(q, &dentry->d_subdirs);
165 149  
166   - for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
167   - struct dentry *next;
168   - next = list_entry(p, struct dentry, d_u.d_child);
169   - spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
170   - if (!simple_positive(next)) {
171   - spin_unlock(&next->d_lock);
172   - continue;
173   - }
  150 + for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
  151 + struct dentry *next = list_entry(p, struct dentry, d_u.d_child);
  152 + spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
  153 + if (!simple_positive(next)) {
  154 + spin_unlock(&next->d_lock);
  155 + continue;
  156 + }
174 157  
175   - spin_unlock(&next->d_lock);
176   - spin_unlock(&dentry->d_lock);
177   - if (filldir(dirent, next->d_name.name,
178   - next->d_name.len, filp->f_pos,
179   - next->d_inode->i_ino,
180   - dt_type(next->d_inode)) < 0)
181   - return 0;
182   - spin_lock(&dentry->d_lock);
183   - spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
184   - /* next is still alive */
185   - list_move(q, p);
186   - spin_unlock(&next->d_lock);
187   - p = q;
188   - filp->f_pos++;
189   - }
190   - spin_unlock(&dentry->d_lock);
  158 + spin_unlock(&next->d_lock);
  159 + spin_unlock(&dentry->d_lock);
  160 + if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
  161 + next->d_inode->i_ino, dt_type(next->d_inode)))
  162 + return 0;
  163 + spin_lock(&dentry->d_lock);
  164 + spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
  165 + /* next is still alive */
  166 + list_move(q, p);
  167 + spin_unlock(&next->d_lock);
  168 + p = q;
  169 + ctx->pos++;
191 170 }
  171 + spin_unlock(&dentry->d_lock);
192 172 return 0;
193 173 }
194 174  
... ... @@ -202,7 +182,7 @@
202 182 .release = dcache_dir_close,
203 183 .llseek = dcache_dir_lseek,
204 184 .read = generic_read_dir,
205   - .readdir = dcache_readdir,
  185 + .iterate = dcache_readdir,
206 186 .fsync = noop_fsync,
207 187 };
208 188  
... ... @@ -1511,12 +1511,6 @@
1511 1511 loff_t pos;
1512 1512 };
1513 1513  
1514   -static inline bool dir_emit(struct dir_context *ctx,
1515   - const char *name, int namelen,
1516   - u64 ino, unsigned type)
1517   -{
1518   - return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0;
1519   -}
1520 1514 struct block_device_operations;
1521 1515  
1522 1516 /* These macros are for out of kernel modules to test that
... ... @@ -2537,7 +2531,7 @@
2537 2531 extern int dcache_dir_open(struct inode *, struct file *);
2538 2532 extern int dcache_dir_close(struct inode *, struct file *);
2539 2533 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
2540   -extern int dcache_readdir(struct file *, void *, filldir_t);
  2534 +extern int dcache_readdir(struct file *, struct dir_context *);
2541 2535 extern int simple_setattr(struct dentry *, struct iattr *);
2542 2536 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
2543 2537 extern int simple_statfs(struct dentry *, struct kstatfs *);
... ... @@ -2699,6 +2693,37 @@
2699 2693 {
2700 2694 if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & MS_NOSEC))
2701 2695 inode->i_flags |= S_NOSEC;
  2696 +}
  2697 +
  2698 +static inline bool dir_emit(struct dir_context *ctx,
  2699 + const char *name, int namelen,
  2700 + u64 ino, unsigned type)
  2701 +{
  2702 + return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0;
  2703 +}
  2704 +static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx)
  2705 +{
  2706 + return ctx->actor(ctx, ".", 1, ctx->pos,
  2707 + file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0;
  2708 +}
  2709 +static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx)
  2710 +{
  2711 + return ctx->actor(ctx, "..", 2, ctx->pos,
  2712 + parent_ino(file->f_path.dentry), DT_DIR) == 0;
  2713 +}
  2714 +static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx)
  2715 +{
  2716 + if (ctx->pos == 0) {
  2717 + if (!dir_emit_dot(file, ctx))
  2718 + return false;
  2719 + ctx->pos = 1;
  2720 + }
  2721 + if (ctx->pos == 1) {
  2722 + if (!dir_emit_dotdot(file, ctx))
  2723 + return false;
  2724 + ctx->pos = 2;
  2725 + }
  2726 + return true;
2702 2727 }
2703 2728  
2704 2729 #endif /* _LINUX_FS_H */