Skip to content

Commit 1d4795e

Browse files
Christoph Hellwigdchinner
authored andcommitted
xfs: (re-)implement FIEMAP_FLAG_XATTR
Use a special read-only iomap_ops implementation to support fiemap on the attr fork. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
1 parent b95a212 commit 1d4795e

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

fs/xfs/xfs_iomap.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,3 +1106,48 @@ struct iomap_ops xfs_iomap_ops = {
11061106
.iomap_begin = xfs_file_iomap_begin,
11071107
.iomap_end = xfs_file_iomap_end,
11081108
};
1109+
1110+
static int
1111+
xfs_xattr_iomap_begin(
1112+
struct inode *inode,
1113+
loff_t offset,
1114+
loff_t length,
1115+
unsigned flags,
1116+
struct iomap *iomap)
1117+
{
1118+
struct xfs_inode *ip = XFS_I(inode);
1119+
struct xfs_mount *mp = ip->i_mount;
1120+
xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
1121+
xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length);
1122+
struct xfs_bmbt_irec imap;
1123+
int nimaps = 1, error = 0;
1124+
unsigned lockmode;
1125+
1126+
if (XFS_FORCED_SHUTDOWN(mp))
1127+
return -EIO;
1128+
1129+
lockmode = xfs_ilock_data_map_shared(ip);
1130+
1131+
/* if there are no attribute fork or extents, return ENOENT */
1132+
if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) {
1133+
error = -ENOENT;
1134+
goto out_unlock;
1135+
}
1136+
1137+
ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL);
1138+
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
1139+
&nimaps, XFS_BMAPI_ENTIRE | XFS_BMAPI_ATTRFORK);
1140+
out_unlock:
1141+
xfs_iunlock(ip, lockmode);
1142+
1143+
if (!error) {
1144+
ASSERT(nimaps);
1145+
xfs_bmbt_to_iomap(ip, iomap, &imap);
1146+
}
1147+
1148+
return error;
1149+
}
1150+
1151+
struct iomap_ops xfs_xattr_iomap_ops = {
1152+
.iomap_begin = xfs_xattr_iomap_begin,
1153+
};

fs/xfs/xfs_iomap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
3535
struct xfs_bmbt_irec *);
3636

3737
extern struct iomap_ops xfs_iomap_ops;
38+
extern struct iomap_ops xfs_xattr_iomap_ops;
3839

3940
#endif /* __XFS_IOMAP_H__*/

fs/xfs/xfs_iops.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,14 @@ xfs_vn_fiemap(
10091009
int error;
10101010

10111011
xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED);
1012-
error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops);
1012+
if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
1013+
fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR;
1014+
error = iomap_fiemap(inode, fieinfo, start, length,
1015+
&xfs_xattr_iomap_ops);
1016+
} else {
1017+
error = iomap_fiemap(inode, fieinfo, start, length,
1018+
&xfs_iomap_ops);
1019+
}
10131020
xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED);
10141021

10151022
return error;

0 commit comments

Comments
 (0)