diff options
| -rw-r--r-- | fs/ocfs2/dir.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index e15351338417..7453b70c1a19 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -588,7 +588,7 @@ bail: | |||
| 588 | static int ocfs2_dir_foreach_blk_id(struct inode *inode, | 588 | static int ocfs2_dir_foreach_blk_id(struct inode *inode, |
| 589 | unsigned long *f_version, | 589 | unsigned long *f_version, |
| 590 | loff_t *f_pos, void *priv, | 590 | loff_t *f_pos, void *priv, |
| 591 | filldir_t filldir) | 591 | filldir_t filldir, int *filldir_err) |
| 592 | { | 592 | { |
| 593 | int ret, i, filldir_ret; | 593 | int ret, i, filldir_ret; |
| 594 | unsigned long offset = *f_pos; | 594 | unsigned long offset = *f_pos; |
| @@ -659,8 +659,11 @@ revalidate: | |||
| 659 | *f_pos, | 659 | *f_pos, |
| 660 | le64_to_cpu(de->inode), | 660 | le64_to_cpu(de->inode), |
| 661 | d_type); | 661 | d_type); |
| 662 | if (filldir_ret) | 662 | if (filldir_ret) { |
| 663 | if (filldir_err) | ||
| 664 | *filldir_err = filldir_ret; | ||
| 663 | break; | 665 | break; |
| 666 | } | ||
| 664 | if (version != *f_version) | 667 | if (version != *f_version) |
| 665 | goto revalidate; | 668 | goto revalidate; |
| 666 | } | 669 | } |
| @@ -676,7 +679,7 @@ out: | |||
| 676 | static int ocfs2_dir_foreach_blk_el(struct inode *inode, | 679 | static int ocfs2_dir_foreach_blk_el(struct inode *inode, |
| 677 | unsigned long *f_version, | 680 | unsigned long *f_version, |
| 678 | loff_t *f_pos, void *priv, | 681 | loff_t *f_pos, void *priv, |
| 679 | filldir_t filldir) | 682 | filldir_t filldir, int *filldir_err) |
| 680 | { | 683 | { |
| 681 | int error = 0; | 684 | int error = 0; |
| 682 | unsigned long offset, blk, last_ra_blk = 0; | 685 | unsigned long offset, blk, last_ra_blk = 0; |
| @@ -775,8 +778,11 @@ revalidate: | |||
| 775 | *f_pos, | 778 | *f_pos, |
| 776 | le64_to_cpu(de->inode), | 779 | le64_to_cpu(de->inode), |
| 777 | d_type); | 780 | d_type); |
| 778 | if (error) | 781 | if (error) { |
| 782 | if (filldir_err) | ||
| 783 | *filldir_err = error; | ||
| 779 | break; | 784 | break; |
| 785 | } | ||
| 780 | if (version != *f_version) | 786 | if (version != *f_version) |
| 781 | goto revalidate; | 787 | goto revalidate; |
| 782 | stored ++; | 788 | stored ++; |
| @@ -793,13 +799,15 @@ out: | |||
| 793 | } | 799 | } |
| 794 | 800 | ||
| 795 | static int ocfs2_dir_foreach_blk(struct inode *inode, unsigned long *f_version, | 801 | static int ocfs2_dir_foreach_blk(struct inode *inode, unsigned long *f_version, |
| 796 | loff_t *f_pos, void *priv, filldir_t filldir) | 802 | loff_t *f_pos, void *priv, filldir_t filldir, |
| 803 | int *filldir_err) | ||
| 797 | { | 804 | { |
| 798 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) | 805 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) |
| 799 | return ocfs2_dir_foreach_blk_id(inode, f_version, f_pos, priv, | 806 | return ocfs2_dir_foreach_blk_id(inode, f_version, f_pos, priv, |
| 800 | filldir); | 807 | filldir, filldir_err); |
| 801 | 808 | ||
| 802 | return ocfs2_dir_foreach_blk_el(inode, f_version, f_pos, priv, filldir); | 809 | return ocfs2_dir_foreach_blk_el(inode, f_version, f_pos, priv, filldir, |
| 810 | filldir_err); | ||
| 803 | } | 811 | } |
| 804 | 812 | ||
| 805 | /* | 813 | /* |
| @@ -809,16 +817,19 @@ static int ocfs2_dir_foreach_blk(struct inode *inode, unsigned long *f_version, | |||
| 809 | int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv, | 817 | int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv, |
| 810 | filldir_t filldir) | 818 | filldir_t filldir) |
| 811 | { | 819 | { |
| 812 | int ret = 0; | 820 | int ret = 0, filldir_err = 0; |
| 813 | unsigned long version = inode->i_version; | 821 | unsigned long version = inode->i_version; |
| 814 | 822 | ||
| 815 | while (*f_pos < i_size_read(inode)) { | 823 | while (*f_pos < i_size_read(inode)) { |
| 816 | ret = ocfs2_dir_foreach_blk(inode, &version, f_pos, priv, | 824 | ret = ocfs2_dir_foreach_blk(inode, &version, f_pos, priv, |
| 817 | filldir); | 825 | filldir, &filldir_err); |
| 818 | if (ret) | 826 | if (ret || filldir_err) |
| 819 | break; | 827 | break; |
| 820 | } | 828 | } |
| 821 | 829 | ||
| 830 | if (ret > 0) | ||
| 831 | ret = -EIO; | ||
| 832 | |||
| 822 | return 0; | 833 | return 0; |
| 823 | } | 834 | } |
| 824 | 835 | ||
| @@ -852,7 +863,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
| 852 | } | 863 | } |
| 853 | 864 | ||
| 854 | error = ocfs2_dir_foreach_blk(inode, &filp->f_version, &filp->f_pos, | 865 | error = ocfs2_dir_foreach_blk(inode, &filp->f_version, &filp->f_pos, |
| 855 | dirent, filldir); | 866 | dirent, filldir, NULL); |
| 856 | 867 | ||
| 857 | ocfs2_meta_unlock(inode, lock_level); | 868 | ocfs2_meta_unlock(inode, lock_level); |
| 858 | 869 | ||
