diff options
Diffstat (limited to 'fs/ocfs2/extent_map.c')
-rw-r--r-- | fs/ocfs2/extent_map.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index cdce5f8c1cfa..d35a27f4523e 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "extent_map.h" | 37 | #include "extent_map.h" |
38 | #include "inode.h" | 38 | #include "inode.h" |
39 | #include "super.h" | 39 | #include "super.h" |
40 | #include "symlink.h" | ||
40 | 41 | ||
41 | #include "buffer_head_io.h" | 42 | #include "buffer_head_io.h" |
42 | 43 | ||
@@ -703,6 +704,12 @@ out: | |||
703 | return ret; | 704 | return ret; |
704 | } | 705 | } |
705 | 706 | ||
707 | /* | ||
708 | * The ocfs2_fiemap_inline() may be a little bit misleading, since | ||
709 | * it not only handles the fiemap for inlined files, but also deals | ||
710 | * with the fast symlink, cause they have no difference for extent | ||
711 | * mapping per se. | ||
712 | */ | ||
706 | static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, | 713 | static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, |
707 | struct fiemap_extent_info *fieinfo, | 714 | struct fiemap_extent_info *fieinfo, |
708 | u64 map_start) | 715 | u64 map_start) |
@@ -715,11 +722,18 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, | |||
715 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 722 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
716 | 723 | ||
717 | di = (struct ocfs2_dinode *)di_bh->b_data; | 724 | di = (struct ocfs2_dinode *)di_bh->b_data; |
718 | id_count = le16_to_cpu(di->id2.i_data.id_count); | 725 | if (ocfs2_inode_is_fast_symlink(inode)) |
726 | id_count = ocfs2_fast_symlink_chars(inode->i_sb); | ||
727 | else | ||
728 | id_count = le16_to_cpu(di->id2.i_data.id_count); | ||
719 | 729 | ||
720 | if (map_start < id_count) { | 730 | if (map_start < id_count) { |
721 | phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits; | 731 | phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits; |
722 | phys += offsetof(struct ocfs2_dinode, id2.i_data.id_data); | 732 | if (ocfs2_inode_is_fast_symlink(inode)) |
733 | phys += offsetof(struct ocfs2_dinode, id2.i_symlink); | ||
734 | else | ||
735 | phys += offsetof(struct ocfs2_dinode, | ||
736 | id2.i_data.id_data); | ||
723 | 737 | ||
724 | ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, | 738 | ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, |
725 | flags); | 739 | flags); |
@@ -756,9 +770,10 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
756 | down_read(&OCFS2_I(inode)->ip_alloc_sem); | 770 | down_read(&OCFS2_I(inode)->ip_alloc_sem); |
757 | 771 | ||
758 | /* | 772 | /* |
759 | * Handle inline-data separately. | 773 | * Handle inline-data and fast symlink separately. |
760 | */ | 774 | */ |
761 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | 775 | if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || |
776 | ocfs2_inode_is_fast_symlink(inode)) { | ||
762 | ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start); | 777 | ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start); |
763 | goto out_unlock; | 778 | goto out_unlock; |
764 | } | 779 | } |