aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-15 20:23:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:46:48 -0400
commit5f99f4e79abc64ed9d93a4b0158b21c64ff7f478 (patch)
treebb76629861592bee919344521fb2d55ce866a17f /fs
parent80886298c07234331458e963b5f9f57c68edd700 (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.c4
-rw-r--r--fs/libfs.c80
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
138int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) 138int 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