summaryrefslogtreecommitdiffstats
path: root/fs/coda
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-22 21:15:30 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:03 -0400
commite924f251264bec0b73c32f15ed27a7fbb9912beb (patch)
treed93c096ac0152fc8094734a0ac8a38b1d9bf7ccc /fs/coda
parent3704412bdbf37ec836152f571ac74fe72220c05a (diff)
[readdir] convert coda
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/coda')
-rw-r--r--fs/coda/dir.c77
1 files changed, 19 insertions, 58 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index fc66861b3598..87e0ee9f4465 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -43,15 +43,14 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
43 struct inode *new_inode, struct dentry *new_dentry); 43 struct inode *new_inode, struct dentry *new_dentry);
44 44
45/* dir file-ops */ 45/* dir file-ops */
46static int coda_readdir(struct file *file, void *buf, filldir_t filldir); 46static int coda_readdir(struct file *file, struct dir_context *ctx);
47 47
48/* dentry ops */ 48/* dentry ops */
49static int coda_dentry_revalidate(struct dentry *de, unsigned int flags); 49static int coda_dentry_revalidate(struct dentry *de, unsigned int flags);
50static int coda_dentry_delete(const struct dentry *); 50static int coda_dentry_delete(const struct dentry *);
51 51
52/* support routines */ 52/* support routines */
53static int coda_venus_readdir(struct file *coda_file, void *buf, 53static int coda_venus_readdir(struct file *, struct dir_context *);
54 filldir_t filldir);
55 54
56/* same as fs/bad_inode.c */ 55/* same as fs/bad_inode.c */
57static int coda_return_EIO(void) 56static int coda_return_EIO(void)
@@ -85,7 +84,7 @@ const struct inode_operations coda_dir_inode_operations =
85const struct file_operations coda_dir_operations = { 84const struct file_operations coda_dir_operations = {
86 .llseek = generic_file_llseek, 85 .llseek = generic_file_llseek,
87 .read = generic_read_dir, 86 .read = generic_read_dir,
88 .readdir = coda_readdir, 87 .iterate = coda_readdir,
89 .open = coda_open, 88 .open = coda_open,
90 .release = coda_release, 89 .release = coda_release,
91 .fsync = coda_fsync, 90 .fsync = coda_fsync,
@@ -378,7 +377,7 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
378 377
379 378
380/* file operations for directories */ 379/* file operations for directories */
381static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir) 380static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
382{ 381{
383 struct coda_file_info *cfi; 382 struct coda_file_info *cfi;
384 struct file *host_file; 383 struct file *host_file;
@@ -391,28 +390,8 @@ static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)
391 if (!host_file->f_op) 390 if (!host_file->f_op)
392 return -ENOTDIR; 391 return -ENOTDIR;
393 392
394 if (host_file->f_op->readdir) { 393 if (host_file->f_op->iterate) {
395 /* potemkin case: we were handed a directory inode.
396 * We can't use vfs_readdir because we have to keep the file
397 * position in sync between the coda_file and the host_file.
398 * and as such we need grab the inode mutex. */
399 struct inode *host_inode = file_inode(host_file); 394 struct inode *host_inode = file_inode(host_file);
400
401 mutex_lock(&host_inode->i_mutex);
402 host_file->f_pos = coda_file->f_pos;
403
404 ret = -ENOENT;
405 if (!IS_DEADDIR(host_inode)) {
406 ret = host_file->f_op->readdir(host_file, buf, filldir);
407 file_accessed(host_file);
408 }
409
410 coda_file->f_pos = host_file->f_pos;
411 mutex_unlock(&host_inode->i_mutex);
412 } else if (host_file->f_op->iterate) {
413 struct inode *host_inode = file_inode(host_file);
414 struct dir_context *ctx = buf;
415
416 mutex_lock(&host_inode->i_mutex); 395 mutex_lock(&host_inode->i_mutex);
417 ret = -ENOENT; 396 ret = -ENOENT;
418 if (!IS_DEADDIR(host_inode)) { 397 if (!IS_DEADDIR(host_inode)) {
@@ -420,12 +399,10 @@ static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)
420 file_accessed(host_file); 399 file_accessed(host_file);
421 } 400 }
422 mutex_unlock(&host_inode->i_mutex); 401 mutex_unlock(&host_inode->i_mutex);
423 402 return ret;
424 coda_file->f_pos = ctx->pos; 403 }
425 } else /* Venus: we must read Venus dirents from a file */ 404 /* Venus: we must read Venus dirents from a file */
426 ret = coda_venus_readdir(coda_file, buf, filldir); 405 return coda_venus_readdir(coda_file, ctx);
427
428 return ret;
429} 406}
430 407
431static inline unsigned int CDT2DT(unsigned char cdt) 408static inline unsigned int CDT2DT(unsigned char cdt)
@@ -448,10 +425,8 @@ static inline unsigned int CDT2DT(unsigned char cdt)
448} 425}
449 426
450/* support routines */ 427/* support routines */
451static int coda_venus_readdir(struct file *coda_file, void *buf, 428static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
452 filldir_t filldir)
453{ 429{
454 int result = 0; /* # of entries returned */
455 struct coda_file_info *cfi; 430 struct coda_file_info *cfi;
456 struct coda_inode_info *cii; 431 struct coda_inode_info *cii;
457 struct file *host_file; 432 struct file *host_file;
@@ -473,23 +448,12 @@ static int coda_venus_readdir(struct file *coda_file, void *buf,
473 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL); 448 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
474 if (!vdir) return -ENOMEM; 449 if (!vdir) return -ENOMEM;
475 450
476 if (coda_file->f_pos == 0) { 451 if (!dir_emit_dots(coda_file, ctx))
477 ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR); 452 goto out;
478 if (ret < 0) 453
479 goto out;
480 result++;
481 coda_file->f_pos++;
482 }
483 if (coda_file->f_pos == 1) {
484 ret = filldir(buf, "..", 2, 1, parent_ino(de), DT_DIR);
485 if (ret < 0)
486 goto out;
487 result++;
488 coda_file->f_pos++;
489 }
490 while (1) { 454 while (1) {
491 /* read entries from the directory file */ 455 /* read entries from the directory file */
492 ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir, 456 ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir,
493 sizeof(*vdir)); 457 sizeof(*vdir));
494 if (ret < 0) { 458 if (ret < 0) {
495 printk(KERN_ERR "coda readdir: read dir %s failed %d\n", 459 printk(KERN_ERR "coda readdir: read dir %s failed %d\n",
@@ -518,7 +482,7 @@ static int coda_venus_readdir(struct file *coda_file, void *buf,
518 482
519 /* Make sure we skip '.' and '..', we already got those */ 483 /* Make sure we skip '.' and '..', we already got those */
520 if (name.name[0] == '.' && (name.len == 1 || 484 if (name.name[0] == '.' && (name.len == 1 ||
521 (vdir->d_name[1] == '.' && name.len == 2))) 485 (name.name[1] == '.' && name.len == 2)))
522 vdir->d_fileno = name.len = 0; 486 vdir->d_fileno = name.len = 0;
523 487
524 /* skip null entries */ 488 /* skip null entries */
@@ -531,19 +495,16 @@ static int coda_venus_readdir(struct file *coda_file, void *buf,
531 if (!ino) ino = vdir->d_fileno; 495 if (!ino) ino = vdir->d_fileno;
532 496
533 type = CDT2DT(vdir->d_type); 497 type = CDT2DT(vdir->d_type);
534 ret = filldir(buf, name.name, name.len, 498 if (!dir_emit(ctx, name.name, name.len, ino, type))
535 coda_file->f_pos, ino, type); 499 break;
536 /* failure means no space for filling in this round */
537 if (ret < 0) break;
538 result++;
539 } 500 }
540 /* we'll always have progress because d_reclen is unsigned and 501 /* we'll always have progress because d_reclen is unsigned and
541 * we've already established it is non-zero. */ 502 * we've already established it is non-zero. */
542 coda_file->f_pos += vdir->d_reclen; 503 ctx->pos += vdir->d_reclen;
543 } 504 }
544out: 505out:
545 kfree(vdir); 506 kfree(vdir);
546 return result ? result : ret; 507 return 0;
547} 508}
548 509
549/* called when a cache lookup succeeds */ 510/* called when a cache lookup succeeds */