From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kalpak Shah Subject: Re: [PATCH 4/4] ext4: implement ext4_fiemap Date: Thu, 03 Jul 2008 22:31:53 +0530 Message-ID: <1215104513.4272.23.camel@localhost> References: <20080625221915.GU28100@wotan.suse.de> Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7BIT Cc: linux-fsdevel@vger.kernel.org, Eric Sandeen To: Mark Fasheh Return-path: Received: from sineb-mail-1.sun.com ([192.18.19.6]:33842 "EHLO sineb-mail-1.sun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752068AbYGCRUC (ORCPT ); Thu, 3 Jul 2008 13:20:02 -0400 Received: from fe-apac-05.sun.com (fe-apac-05.sun.com [192.18.19.176] (may be forged)) by sineb-mail-1.sun.com (8.13.6+Sun/8.12.9) with ESMTP id m63H206S000017 for ; Thu, 3 Jul 2008 17:02:01 GMT Received: from conversion-daemon.mail-apac.sun.com by mail-apac.sun.com (Sun Java System Messaging Server 6.2-6.01 (built Apr 3 2006)) id <0K3F00701WDSUL00@mail-apac.sun.com> (original mail from Kalpak.Shah@Sun.COM) for linux-fsdevel@vger.kernel.org; Fri, 04 Jul 2008 01:01:06 +0800 (SGT) In-reply-to: <20080625221915.GU28100@wotan.suse.de> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Wed, 2008-06-25 at 15:19 -0700, Mark Fasheh wrote: > From: Eric Sandeen > +/* 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 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