aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/extent_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/extent_map.c')
-rw-r--r--fs/ocfs2/extent_map.c30
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 */
706static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, 714static 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;