aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-17 17:06:34 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:43 -0400
commit46d0733801e631b9b5b65323507b06fb3809df4c (patch)
tree26d9a8a3c5378a6d54478c3f4b4c5c9e0a1a9db5
parent070a0ebf42e15c9c595fc2ceac06100d60ced8f0 (diff)
[readdir] convert logfs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/logfs/dir.c49
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 284static int logfs_readdir(struct file *file, struct dir_context *ctx)
285static 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
321static 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
345static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name) 326static 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 = {
814const struct file_operations logfs_dir_fops = { 795const 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};