Re: [PATCH 4/4] ext4: implement ext4_fiemap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2008-06-25 at 15:19 -0700, Mark Fasheh wrote:
> From: Eric Sandeen <sandeen@xxxxxxxxxx>
> +/* fiemap flags we can handle specified here */
> +#define EXT4_FIEMAP_FLAGS	(FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
> +
> +int ext4_xattr_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo)
> +{
> +	__u64 physical = 0;
> +	__u64 length;
> +	__u32 flags = FIEMAP_EXTENT_LAST;
> +	int blockbits = inode->i_sb->s_blocksize_bits;
> +	int error = 0;
> +
> +	/* in-inode? */
> +	if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) {
> +		struct ext4_iloc iloc;
> +		int offset;	/* offset of xattr in inode */
> +
> +		error = ext4_get_inode_loc(inode, &iloc);
> +		if (error)
> +			return error;
> +		physical = iloc.bh->b_blocknr << blockbits;
> +		offset = EXT4_GOOD_OLD_INODE_SIZE +
> +				EXT4_I(inode)->i_extra_isize;
> +		physical += offset;
> +		length = EXT4_SB(inode->i_sb)->s_inode_size - offset;
> +		flags |= FIEMAP_EXTENT_DATA_INLINE;
> +	} else { /* external block */
> +		physical = EXT4_I(inode)->i_file_acl << blockbits;
> +		length = inode->i_sb->s_blocksize;
> +	}
> +
> +	if (physical)
> +		error = fiemap_fill_next_extent(fieinfo, 0, physical,
> +					length, flags, inode->i_sb->s_dev);
> +	return (error < 0 ? error : 0);
> +}
> +

Extended attributes can be present in the inode as well as the external block at the same time and we should be returning extents for both them in that case. Below patch fixes this problem:

Signed-off-by: Kalpak Shah <kalpak.shah@xxxxxxx> 

Index: linux-2.6/fs/ext4/extents.c
===================================================================
--- linux-2.6.orig/fs/ext4/extents.c
+++ linux-2.6/fs/ext4/extents.c
@@ -3130,7 +3130,7 @@ int ext4_xattr_fiemap(struct inode *inod
 {
 	__u64 physical = 0;
 	__u64 length;
-	__u32 flags = FIEMAP_EXTENT_LAST;
+	__u32 flags = 0;
 	int blockbits = inode->i_sb->s_blocksize_bits;
 	int error = 0;
 
@@ -3148,14 +3148,24 @@ int ext4_xattr_fiemap(struct inode *inod
 		physical += offset;
 		length = EXT4_SB(inode->i_sb)->s_inode_size - offset;
 		flags |= FIEMAP_EXTENT_DATA_INLINE;
-	} else { /* external block */
-		physical = EXT4_I(inode)->i_file_acl << blockbits;
-		length = inode->i_sb->s_blocksize;
+		if (EXT4_I(inode)->i_file_acl == 0)
+			flags |= FIEMAP_EXTENT_LAST;
+
+		error = fiemap_fill_next_extent(fieinfo, 0, physical, length,
+						flags, inode->i_sb->s_dev);
+		if (error)
+			goto out;
 	}
 
+	/* external block */
+	flags = FIEMAP_EXTENT_LAST;
+	physical = EXT4_I(inode)->i_file_acl << blockbits;
+	length = inode->i_sb->s_blocksize;
 	if (physical)
-		error = fiemap_fill_next_extent(fieinfo, 0, physical,
-					length, flags, inode->i_sb->s_dev);
+		error = fiemap_fill_next_extent(fieinfo, 0, physical, length,
+						flags, inode->i_sb->s_dev);
+
+out:
 	return (error < 0 ? error : 0);
 }
 

Thanks,
Kalpak


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux