diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-17 17:06:34 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:43 -0400 |
commit | 46d0733801e631b9b5b65323507b06fb3809df4c (patch) | |
tree | 26d9a8a3c5378a6d54478c3f4b4c5c9e0a1a9db5 | |
parent | 070a0ebf42e15c9c595fc2ceac06100d60ced8f0 (diff) |
[readdir] convert logfs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/logfs/dir.c | 49 |
1 files changed, 15 insertions, 34 deletions
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index b82751082112..6bdc347008f5 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -281,17 +281,23 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
281 | 281 | ||
282 | /* FIXME: readdir currently has it's own dir_walk code. I don't see a good | 282 | /* FIXME: readdir currently has it's own dir_walk code. I don't see a good |
283 | * way to combine the two copies */ | 283 | * way to combine the two copies */ |
284 | #define IMPLICIT_NODES 2 | 284 | static int logfs_readdir(struct file *file, struct dir_context *ctx) |
285 | static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir) | ||
286 | { | 285 | { |
287 | struct inode *dir = file_inode(file); | 286 | struct inode *dir = file_inode(file); |
288 | loff_t pos = file->f_pos - IMPLICIT_NODES; | 287 | loff_t pos; |
289 | struct page *page; | 288 | struct page *page; |
290 | struct logfs_disk_dentry *dd; | 289 | struct logfs_disk_dentry *dd; |
291 | int full; | ||
292 | 290 | ||
291 | if (ctx->pos < 0) | ||
292 | return -EINVAL; | ||
293 | |||
294 | if (!dir_emit_dots(file, ctx)) | ||
295 | return 0; | ||
296 | |||
297 | pos = ctx->pos - 2; | ||
293 | BUG_ON(pos < 0); | 298 | BUG_ON(pos < 0); |
294 | for (;; pos++) { | 299 | for (;; pos++, ctx->pos++) { |
300 | bool full; | ||
295 | if (beyond_eof(dir, pos)) | 301 | if (beyond_eof(dir, pos)) |
296 | break; | 302 | break; |
297 | if (!logfs_exist_block(dir, pos)) { | 303 | if (!logfs_exist_block(dir, pos)) { |
@@ -306,42 +312,17 @@ static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir) | |||
306 | dd = kmap(page); | 312 | dd = kmap(page); |
307 | BUG_ON(dd->namelen == 0); | 313 | BUG_ON(dd->namelen == 0); |
308 | 314 | ||
309 | full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen), | 315 | full = !dir_emit(ctx, (char *)dd->name, |
310 | pos, be64_to_cpu(dd->ino), dd->type); | 316 | be16_to_cpu(dd->namelen), |
317 | be64_to_cpu(dd->ino), dd->type); | ||
311 | kunmap(page); | 318 | kunmap(page); |
312 | page_cache_release(page); | 319 | page_cache_release(page); |
313 | if (full) | 320 | if (full) |
314 | break; | 321 | break; |
315 | } | 322 | } |
316 | |||
317 | file->f_pos = pos + IMPLICIT_NODES; | ||
318 | return 0; | 323 | return 0; |
319 | } | 324 | } |
320 | 325 | ||
321 | static int logfs_readdir(struct file *file, void *buf, filldir_t filldir) | ||
322 | { | ||
323 | struct inode *inode = file_inode(file); | ||
324 | ino_t pino = parent_ino(file->f_dentry); | ||
325 | int err; | ||
326 | |||
327 | if (file->f_pos < 0) | ||
328 | return -EINVAL; | ||
329 | |||
330 | if (file->f_pos == 0) { | ||
331 | if (filldir(buf, ".", 1, 1, inode->i_ino, DT_DIR) < 0) | ||
332 | return 0; | ||
333 | file->f_pos++; | ||
334 | } | ||
335 | if (file->f_pos == 1) { | ||
336 | if (filldir(buf, "..", 2, 2, pino, DT_DIR) < 0) | ||
337 | return 0; | ||
338 | file->f_pos++; | ||
339 | } | ||
340 | |||
341 | err = __logfs_readdir(file, buf, filldir); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name) | 326 | static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name) |
346 | { | 327 | { |
347 | dd->namelen = cpu_to_be16(name->len); | 328 | dd->namelen = cpu_to_be16(name->len); |
@@ -814,7 +795,7 @@ const struct inode_operations logfs_dir_iops = { | |||
814 | const struct file_operations logfs_dir_fops = { | 795 | const struct file_operations logfs_dir_fops = { |
815 | .fsync = logfs_fsync, | 796 | .fsync = logfs_fsync, |
816 | .unlocked_ioctl = logfs_ioctl, | 797 | .unlocked_ioctl = logfs_ioctl, |
817 | .readdir = logfs_readdir, | 798 | .iterate = logfs_readdir, |
818 | .read = generic_read_dir, | 799 | .read = generic_read_dir, |
819 | .llseek = default_llseek, | 800 | .llseek = default_llseek, |
820 | }; | 801 | }; |