aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/dir.c')
-rw-r--r--fs/f2fs/dir.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 4f21452f929d..9d1cd423450d 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -606,24 +606,19 @@ bool f2fs_empty_dir(struct inode *dir)
606 return true; 606 return true;
607} 607}
608 608
609static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) 609static int f2fs_readdir(struct file *file, struct dir_context *ctx)
610{ 610{
611 unsigned long pos = file->f_pos;
612 struct inode *inode = file_inode(file); 611 struct inode *inode = file_inode(file);
613 unsigned long npages = dir_blocks(inode); 612 unsigned long npages = dir_blocks(inode);
614 unsigned char *types = NULL;
615 unsigned int bit_pos = 0, start_bit_pos = 0; 613 unsigned int bit_pos = 0, start_bit_pos = 0;
616 int over = 0;
617 struct f2fs_dentry_block *dentry_blk = NULL; 614 struct f2fs_dentry_block *dentry_blk = NULL;
618 struct f2fs_dir_entry *de = NULL; 615 struct f2fs_dir_entry *de = NULL;
619 struct page *dentry_page = NULL; 616 struct page *dentry_page = NULL;
620 unsigned int n = 0; 617 unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK);
621 unsigned char d_type = DT_UNKNOWN; 618 unsigned char d_type = DT_UNKNOWN;
622 int slots; 619 int slots;
623 620
624 types = f2fs_filetype_table; 621 bit_pos = ((unsigned long)ctx->pos % NR_DENTRY_IN_BLOCK);
625 bit_pos = (pos % NR_DENTRY_IN_BLOCK);
626 n = (pos / NR_DENTRY_IN_BLOCK);
627 622
628 for ( ; n < npages; n++) { 623 for ( ; n < npages; n++) {
629 dentry_page = get_lock_data_page(inode, n); 624 dentry_page = get_lock_data_page(inode, n);
@@ -633,31 +628,28 @@ static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir)
633 start_bit_pos = bit_pos; 628 start_bit_pos = bit_pos;
634 dentry_blk = kmap(dentry_page); 629 dentry_blk = kmap(dentry_page);
635 while (bit_pos < NR_DENTRY_IN_BLOCK) { 630 while (bit_pos < NR_DENTRY_IN_BLOCK) {
636 d_type = DT_UNKNOWN;
637 bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 631 bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
638 NR_DENTRY_IN_BLOCK, 632 NR_DENTRY_IN_BLOCK,
639 bit_pos); 633 bit_pos);
640 if (bit_pos >= NR_DENTRY_IN_BLOCK) 634 if (bit_pos >= NR_DENTRY_IN_BLOCK)
641 break; 635 break;
642 636
637 ctx->pos += bit_pos - start_bit_pos;
643 de = &dentry_blk->dentry[bit_pos]; 638 de = &dentry_blk->dentry[bit_pos];
644 if (types && de->file_type < F2FS_FT_MAX) 639 if (de->file_type < F2FS_FT_MAX)
645 d_type = types[de->file_type]; 640 d_type = f2fs_filetype_table[de->file_type];
646 641 else
647 over = filldir(dirent, 642 d_type = DT_UNKNOWN;
648 dentry_blk->filename[bit_pos], 643 if (!dir_emit(ctx,
649 le16_to_cpu(de->name_len), 644 dentry_blk->filename[bit_pos],
650 (n * NR_DENTRY_IN_BLOCK) + bit_pos, 645 le16_to_cpu(de->name_len),
651 le32_to_cpu(de->ino), d_type); 646 le32_to_cpu(de->ino), d_type))
652 if (over) {
653 file->f_pos += bit_pos - start_bit_pos;
654 goto success; 647 goto success;
655 }
656 slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 648 slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
657 bit_pos += slots; 649 bit_pos += slots;
658 } 650 }
659 bit_pos = 0; 651 bit_pos = 0;
660 file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK; 652 ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK;
661 kunmap(dentry_page); 653 kunmap(dentry_page);
662 f2fs_put_page(dentry_page, 1); 654 f2fs_put_page(dentry_page, 1);
663 dentry_page = NULL; 655 dentry_page = NULL;
@@ -674,7 +666,7 @@ success:
674const struct file_operations f2fs_dir_operations = { 666const struct file_operations f2fs_dir_operations = {
675 .llseek = generic_file_llseek, 667 .llseek = generic_file_llseek,
676 .read = generic_read_dir, 668 .read = generic_read_dir,
677 .readdir = f2fs_readdir, 669 .iterate = f2fs_readdir,
678 .fsync = f2fs_sync_file, 670 .fsync = f2fs_sync_file,
679 .unlocked_ioctl = f2fs_ioctl, 671 .unlocked_ioctl = f2fs_ioctl,
680}; 672};