diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-15 20:23:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:46:48 -0400 |
commit | 5f99f4e79abc64ed9d93a4b0158b21c64ff7f478 (patch) | |
tree | bb76629861592bee919344521fb2d55ce866a17f /fs | |
parent | 80886298c07234331458e963b5f9f57c68edd700 (diff) |
[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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/autofs4/root.c | 4 | ||||
-rw-r--r-- | fs/libfs.c | 80 |
2 files changed, 32 insertions, 52 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 085da86e07c2..ca8e55548d98 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -41,7 +41,7 @@ const struct file_operations autofs4_root_operations = { | |||
41 | .open = dcache_dir_open, | 41 | .open = dcache_dir_open, |
42 | .release = dcache_dir_close, | 42 | .release = dcache_dir_close, |
43 | .read = generic_read_dir, | 43 | .read = generic_read_dir, |
44 | .readdir = dcache_readdir, | 44 | .iterate = dcache_readdir, |
45 | .llseek = dcache_dir_lseek, | 45 | .llseek = dcache_dir_lseek, |
46 | .unlocked_ioctl = autofs4_root_ioctl, | 46 | .unlocked_ioctl = autofs4_root_ioctl, |
47 | #ifdef CONFIG_COMPAT | 47 | #ifdef CONFIG_COMPAT |
@@ -53,7 +53,7 @@ const struct file_operations autofs4_dir_operations = { | |||
53 | .open = autofs4_dir_open, | 53 | .open = autofs4_dir_open, |
54 | .release = dcache_dir_close, | 54 | .release = dcache_dir_close, |
55 | .read = generic_read_dir, | 55 | .read = generic_read_dir, |
56 | .readdir = dcache_readdir, | 56 | .iterate = dcache_readdir, |
57 | .llseek = dcache_dir_lseek, | 57 | .llseek = dcache_dir_lseek, |
58 | }; | 58 | }; |
59 | 59 | ||
diff --git a/fs/libfs.c b/fs/libfs.c index 916da8c4158b..c3a0837fb861 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -135,60 +135,40 @@ static inline unsigned char dt_type(struct inode *inode) | |||
135 | * both impossible due to the lock on directory. | 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; | 140 | struct dentry *dentry = file->f_path.dentry; |
141 | struct dentry *cursor = filp->private_data; | 141 | struct dentry *cursor = file->private_data; |
142 | struct list_head *p, *q = &cursor->d_u.d_child; | 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) { | 144 | if (!dir_emit_dots(file, ctx)) |
147 | case 0: | 145 | return 0; |
148 | ino = dentry->d_inode->i_ino; | 146 | spin_lock(&dentry->d_lock); |
149 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) | 147 | if (ctx->pos == 2) |
150 | break; | 148 | list_move(q, &dentry->d_subdirs); |
151 | filp->f_pos++; | 149 | |
152 | i++; | 150 | for (p = q->next; p != &dentry->d_subdirs; p = p->next) { |
153 | /* fallthrough */ | 151 | struct dentry *next = list_entry(p, struct dentry, d_u.d_child); |
154 | case 1: | 152 | spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); |
155 | ino = parent_ino(dentry); | 153 | if (!simple_positive(next)) { |
156 | if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) | 154 | spin_unlock(&next->d_lock); |
157 | break; | 155 | continue; |
158 | filp->f_pos++; | 156 | } |
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); | ||
165 | |||
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 | } | ||
174 | 157 | ||
175 | spin_unlock(&next->d_lock); | 158 | spin_unlock(&next->d_lock); |
176 | spin_unlock(&dentry->d_lock); | 159 | spin_unlock(&dentry->d_lock); |
177 | if (filldir(dirent, next->d_name.name, | 160 | if (!dir_emit(ctx, next->d_name.name, next->d_name.len, |
178 | next->d_name.len, filp->f_pos, | 161 | next->d_inode->i_ino, dt_type(next->d_inode))) |
179 | next->d_inode->i_ino, | 162 | return 0; |
180 | dt_type(next->d_inode)) < 0) | 163 | spin_lock(&dentry->d_lock); |
181 | return 0; | 164 | spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); |
182 | spin_lock(&dentry->d_lock); | 165 | /* next is still alive */ |
183 | spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); | 166 | list_move(q, p); |
184 | /* next is still alive */ | 167 | spin_unlock(&next->d_lock); |
185 | list_move(q, p); | 168 | p = q; |
186 | spin_unlock(&next->d_lock); | 169 | ctx->pos++; |
187 | p = q; | ||
188 | filp->f_pos++; | ||
189 | } | ||
190 | spin_unlock(&dentry->d_lock); | ||
191 | } | 170 | } |
171 | spin_unlock(&dentry->d_lock); | ||
192 | return 0; | 172 | return 0; |
193 | } | 173 | } |
194 | 174 | ||
@@ -202,7 +182,7 @@ const struct file_operations simple_dir_operations = { | |||
202 | .release = dcache_dir_close, | 182 | .release = dcache_dir_close, |
203 | .llseek = dcache_dir_lseek, | 183 | .llseek = dcache_dir_lseek, |
204 | .read = generic_read_dir, | 184 | .read = generic_read_dir, |
205 | .readdir = dcache_readdir, | 185 | .iterate = dcache_readdir, |
206 | .fsync = noop_fsync, | 186 | .fsync = noop_fsync, |
207 | }; | 187 | }; |
208 | 188 | ||