diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/ocfs2/extent_map.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/ocfs2/extent_map.c')
-rw-r--r-- | fs/ocfs2/extent_map.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 843db64e9d4a..09e3fdfa6d33 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | 28 | #include <linux/types.h> |
28 | #include <linux/fiemap.h> | 29 | #include <linux/fiemap.h> |
29 | 30 | ||
@@ -37,6 +38,7 @@ | |||
37 | #include "extent_map.h" | 38 | #include "extent_map.h" |
38 | #include "inode.h" | 39 | #include "inode.h" |
39 | #include "super.h" | 40 | #include "super.h" |
41 | #include "symlink.h" | ||
40 | 42 | ||
41 | #include "buffer_head_io.h" | 43 | #include "buffer_head_io.h" |
42 | 44 | ||
@@ -191,7 +193,7 @@ static int ocfs2_try_to_merge_extent_map(struct ocfs2_extent_map_item *emi, | |||
191 | emi->ei_clusters += ins->ei_clusters; | 193 | emi->ei_clusters += ins->ei_clusters; |
192 | return 1; | 194 | return 1; |
193 | } else if ((ins->ei_phys + ins->ei_clusters) == emi->ei_phys && | 195 | } else if ((ins->ei_phys + ins->ei_clusters) == emi->ei_phys && |
194 | (ins->ei_cpos + ins->ei_clusters) == emi->ei_phys && | 196 | (ins->ei_cpos + ins->ei_clusters) == emi->ei_cpos && |
195 | ins->ei_flags == emi->ei_flags) { | 197 | ins->ei_flags == emi->ei_flags) { |
196 | emi->ei_phys = ins->ei_phys; | 198 | emi->ei_phys = ins->ei_phys; |
197 | emi->ei_cpos = ins->ei_cpos; | 199 | emi->ei_cpos = ins->ei_cpos; |
@@ -452,7 +454,7 @@ static int ocfs2_get_clusters_nocache(struct inode *inode, | |||
452 | if (i == -1) { | 454 | if (i == -1) { |
453 | /* | 455 | /* |
454 | * Holes can be larger than the maximum size of an | 456 | * Holes can be larger than the maximum size of an |
455 | * extent, so we return their lengths in a seperate | 457 | * extent, so we return their lengths in a separate |
456 | * field. | 458 | * field. |
457 | */ | 459 | */ |
458 | if (hole_len) { | 460 | if (hole_len) { |
@@ -703,6 +705,12 @@ out: | |||
703 | return ret; | 705 | return ret; |
704 | } | 706 | } |
705 | 707 | ||
708 | /* | ||
709 | * The ocfs2_fiemap_inline() may be a little bit misleading, since | ||
710 | * it not only handles the fiemap for inlined files, but also deals | ||
711 | * with the fast symlink, cause they have no difference for extent | ||
712 | * mapping per se. | ||
713 | */ | ||
706 | static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, | 714 | static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, |
707 | struct fiemap_extent_info *fieinfo, | 715 | struct fiemap_extent_info *fieinfo, |
708 | u64 map_start) | 716 | u64 map_start) |
@@ -715,11 +723,18 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, | |||
715 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 723 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
716 | 724 | ||
717 | di = (struct ocfs2_dinode *)di_bh->b_data; | 725 | di = (struct ocfs2_dinode *)di_bh->b_data; |
718 | id_count = le16_to_cpu(di->id2.i_data.id_count); | 726 | if (ocfs2_inode_is_fast_symlink(inode)) |
727 | id_count = ocfs2_fast_symlink_chars(inode->i_sb); | ||
728 | else | ||
729 | id_count = le16_to_cpu(di->id2.i_data.id_count); | ||
719 | 730 | ||
720 | if (map_start < id_count) { | 731 | if (map_start < id_count) { |
721 | phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits; | 732 | phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits; |
722 | phys += offsetof(struct ocfs2_dinode, id2.i_data.id_data); | 733 | if (ocfs2_inode_is_fast_symlink(inode)) |
734 | phys += offsetof(struct ocfs2_dinode, id2.i_symlink); | ||
735 | else | ||
736 | phys += offsetof(struct ocfs2_dinode, | ||
737 | id2.i_data.id_data); | ||
723 | 738 | ||
724 | ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, | 739 | ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, |
725 | flags); | 740 | flags); |
@@ -756,9 +771,10 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
756 | down_read(&OCFS2_I(inode)->ip_alloc_sem); | 771 | down_read(&OCFS2_I(inode)->ip_alloc_sem); |
757 | 772 | ||
758 | /* | 773 | /* |
759 | * Handle inline-data separately. | 774 | * Handle inline-data and fast symlink separately. |
760 | */ | 775 | */ |
761 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | 776 | if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || |
777 | ocfs2_inode_is_fast_symlink(inode)) { | ||
762 | ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start); | 778 | ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start); |
763 | goto out_unlock; | 779 | goto out_unlock; |
764 | } | 780 | } |
@@ -786,6 +802,8 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
786 | fe_flags = 0; | 802 | fe_flags = 0; |
787 | if (rec.e_flags & OCFS2_EXT_UNWRITTEN) | 803 | if (rec.e_flags & OCFS2_EXT_UNWRITTEN) |
788 | fe_flags |= FIEMAP_EXTENT_UNWRITTEN; | 804 | fe_flags |= FIEMAP_EXTENT_UNWRITTEN; |
805 | if (rec.e_flags & OCFS2_EXT_REFCOUNTED) | ||
806 | fe_flags |= FIEMAP_EXTENT_SHARED; | ||
789 | if (is_last) | 807 | if (is_last) |
790 | fe_flags |= FIEMAP_EXTENT_LAST; | 808 | fe_flags |= FIEMAP_EXTENT_LAST; |
791 | len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits; | 809 | len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits; |