diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-17 18:02:17 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:46 -0400 |
| commit | 6f7f231e7b4f819b912f848a33d946b54261483d (patch) | |
| tree | f0df510a7dc54deb8f864d10a5d8ca0dc4c1772a | |
| parent | 8f29843a5187983965f1da07b8ebe5a1eb3f2a4a (diff) | |
[readdir] convert f2fs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/cramfs/inode.c | 21 | ||||
| -rw-r--r-- | fs/f2fs/dir.c | 36 |
2 files changed, 22 insertions, 35 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 35b1c7bd18b7..e501ac3a49ff 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
| @@ -349,18 +349,17 @@ static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 349 | /* | 349 | /* |
| 350 | * Read a cramfs directory entry. | 350 | * Read a cramfs directory entry. |
| 351 | */ | 351 | */ |
| 352 | static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 352 | static int cramfs_readdir(struct file *file, struct dir_context *ctx) |
| 353 | { | 353 | { |
| 354 | struct inode *inode = file_inode(filp); | 354 | struct inode *inode = file_inode(file); |
| 355 | struct super_block *sb = inode->i_sb; | 355 | struct super_block *sb = inode->i_sb; |
| 356 | char *buf; | 356 | char *buf; |
| 357 | unsigned int offset; | 357 | unsigned int offset; |
| 358 | int copied; | ||
| 359 | 358 | ||
| 360 | /* Offset within the thing. */ | 359 | /* Offset within the thing. */ |
| 361 | offset = filp->f_pos; | 360 | if (ctx->pos >= inode->i_size) |
| 362 | if (offset >= inode->i_size) | ||
| 363 | return 0; | 361 | return 0; |
| 362 | offset = ctx->pos; | ||
| 364 | /* Directory entries are always 4-byte aligned */ | 363 | /* Directory entries are always 4-byte aligned */ |
| 365 | if (offset & 3) | 364 | if (offset & 3) |
| 366 | return -EINVAL; | 365 | return -EINVAL; |
| @@ -369,14 +368,13 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 369 | if (!buf) | 368 | if (!buf) |
| 370 | return -ENOMEM; | 369 | return -ENOMEM; |
| 371 | 370 | ||
| 372 | copied = 0; | ||
| 373 | while (offset < inode->i_size) { | 371 | while (offset < inode->i_size) { |
| 374 | struct cramfs_inode *de; | 372 | struct cramfs_inode *de; |
| 375 | unsigned long nextoffset; | 373 | unsigned long nextoffset; |
| 376 | char *name; | 374 | char *name; |
| 377 | ino_t ino; | 375 | ino_t ino; |
| 378 | umode_t mode; | 376 | umode_t mode; |
| 379 | int namelen, error; | 377 | int namelen; |
| 380 | 378 | ||
| 381 | mutex_lock(&read_mutex); | 379 | mutex_lock(&read_mutex); |
| 382 | de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); | 380 | de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); |
| @@ -402,13 +400,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 402 | break; | 400 | break; |
| 403 | namelen--; | 401 | namelen--; |
| 404 | } | 402 | } |
| 405 | error = filldir(dirent, buf, namelen, offset, ino, mode >> 12); | 403 | if (!dir_emit(ctx, buf, namelen, ino, mode >> 12)) |
| 406 | if (error) | ||
| 407 | break; | 404 | break; |
| 408 | 405 | ||
| 409 | offset = nextoffset; | 406 | ctx->pos = offset = nextoffset; |
| 410 | filp->f_pos = offset; | ||
| 411 | copied++; | ||
| 412 | } | 407 | } |
| 413 | kfree(buf); | 408 | kfree(buf); |
| 414 | return 0; | 409 | return 0; |
| @@ -547,7 +542,7 @@ static const struct address_space_operations cramfs_aops = { | |||
| 547 | static const struct file_operations cramfs_directory_operations = { | 542 | static const struct file_operations cramfs_directory_operations = { |
| 548 | .llseek = generic_file_llseek, | 543 | .llseek = generic_file_llseek, |
| 549 | .read = generic_read_dir, | 544 | .read = generic_read_dir, |
| 550 | .readdir = cramfs_readdir, | 545 | .iterate = cramfs_readdir, |
| 551 | }; | 546 | }; |
| 552 | 547 | ||
| 553 | static const struct inode_operations cramfs_dir_inode_operations = { | 548 | static const struct inode_operations cramfs_dir_inode_operations = { |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 1ac6b93036b7..600bb5efe603 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
| @@ -591,24 +591,19 @@ bool f2fs_empty_dir(struct inode *dir) | |||
| 591 | return true; | 591 | return true; |
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) | 594 | static int f2fs_readdir(struct file *file, struct dir_context *ctx) |
| 595 | { | 595 | { |
| 596 | unsigned long pos = file->f_pos; | ||
| 597 | struct inode *inode = file_inode(file); | 596 | struct inode *inode = file_inode(file); |
| 598 | unsigned long npages = dir_blocks(inode); | 597 | unsigned long npages = dir_blocks(inode); |
| 599 | unsigned char *types = NULL; | ||
| 600 | unsigned int bit_pos = 0, start_bit_pos = 0; | 598 | unsigned int bit_pos = 0, start_bit_pos = 0; |
| 601 | int over = 0; | ||
| 602 | struct f2fs_dentry_block *dentry_blk = NULL; | 599 | struct f2fs_dentry_block *dentry_blk = NULL; |
| 603 | struct f2fs_dir_entry *de = NULL; | 600 | struct f2fs_dir_entry *de = NULL; |
| 604 | struct page *dentry_page = NULL; | 601 | struct page *dentry_page = NULL; |
| 605 | unsigned int n = 0; | 602 | unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); |
| 606 | unsigned char d_type = DT_UNKNOWN; | 603 | unsigned char d_type = DT_UNKNOWN; |
| 607 | int slots; | 604 | int slots; |
| 608 | 605 | ||
| 609 | types = f2fs_filetype_table; | 606 | bit_pos = ((unsigned long)ctx->pos % NR_DENTRY_IN_BLOCK); |
| 610 | bit_pos = (pos % NR_DENTRY_IN_BLOCK); | ||
| 611 | n = (pos / NR_DENTRY_IN_BLOCK); | ||
| 612 | 607 | ||
| 613 | for ( ; n < npages; n++) { | 608 | for ( ; n < npages; n++) { |
| 614 | dentry_page = get_lock_data_page(inode, n); | 609 | dentry_page = get_lock_data_page(inode, n); |
| @@ -618,31 +613,28 @@ static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
| 618 | start_bit_pos = bit_pos; | 613 | start_bit_pos = bit_pos; |
| 619 | dentry_blk = kmap(dentry_page); | 614 | dentry_blk = kmap(dentry_page); |
| 620 | while (bit_pos < NR_DENTRY_IN_BLOCK) { | 615 | while (bit_pos < NR_DENTRY_IN_BLOCK) { |
| 621 | d_type = DT_UNKNOWN; | ||
| 622 | bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, | 616 | bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, |
| 623 | NR_DENTRY_IN_BLOCK, | 617 | NR_DENTRY_IN_BLOCK, |
| 624 | bit_pos); | 618 | bit_pos); |
| 625 | if (bit_pos >= NR_DENTRY_IN_BLOCK) | 619 | if (bit_pos >= NR_DENTRY_IN_BLOCK) |
| 626 | break; | 620 | break; |
| 627 | 621 | ||
| 622 | ctx->pos += bit_pos - start_bit_pos; | ||
| 628 | de = &dentry_blk->dentry[bit_pos]; | 623 | de = &dentry_blk->dentry[bit_pos]; |
| 629 | if (types && de->file_type < F2FS_FT_MAX) | 624 | if (de->file_type < F2FS_FT_MAX) |
| 630 | d_type = types[de->file_type]; | 625 | d_type = f2fs_filetype_table[de->file_type]; |
| 631 | 626 | else | |
| 632 | over = filldir(dirent, | 627 | d_type = DT_UNKNOWN; |
| 633 | dentry_blk->filename[bit_pos], | 628 | if (!dir_emit(ctx, |
| 634 | le16_to_cpu(de->name_len), | 629 | dentry_blk->filename[bit_pos], |
| 635 | (n * NR_DENTRY_IN_BLOCK) + bit_pos, | 630 | le16_to_cpu(de->name_len), |
| 636 | le32_to_cpu(de->ino), d_type); | 631 | le32_to_cpu(de->ino), d_type)) |
| 637 | if (over) { | ||
| 638 | file->f_pos += bit_pos - start_bit_pos; | ||
| 639 | goto success; | 632 | goto success; |
| 640 | } | ||
| 641 | slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); | 633 | slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); |
| 642 | bit_pos += slots; | 634 | bit_pos += slots; |
| 643 | } | 635 | } |
| 644 | bit_pos = 0; | 636 | bit_pos = 0; |
| 645 | file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK; | 637 | ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK; |
| 646 | kunmap(dentry_page); | 638 | kunmap(dentry_page); |
| 647 | f2fs_put_page(dentry_page, 1); | 639 | f2fs_put_page(dentry_page, 1); |
| 648 | dentry_page = NULL; | 640 | dentry_page = NULL; |
| @@ -659,7 +651,7 @@ success: | |||
| 659 | const struct file_operations f2fs_dir_operations = { | 651 | const struct file_operations f2fs_dir_operations = { |
| 660 | .llseek = generic_file_llseek, | 652 | .llseek = generic_file_llseek, |
| 661 | .read = generic_read_dir, | 653 | .read = generic_read_dir, |
| 662 | .readdir = f2fs_readdir, | 654 | .iterate = f2fs_readdir, |
| 663 | .fsync = f2fs_sync_file, | 655 | .fsync = f2fs_sync_file, |
| 664 | .unlocked_ioctl = f2fs_ioctl, | 656 | .unlocked_ioctl = f2fs_ioctl, |
| 665 | }; | 657 | }; |
