Commit 5f99f4e79abc64ed9d93a4b0158b21c64ff7f478
1 parent
80886298c0
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
[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
fs/autofs4/root.c
... | ... | @@ -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 |
fs/libfs.c
... | ... | @@ -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 |
include/linux/fs.h
... | ... | @@ -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 */ |