@@ -1063,12 +1063,15 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
#define XFS_DIFLAG2_DAX_BIT 0 /* use DAX for this inode */
#define XFS_DIFLAG2_REFLINK_BIT 1 /* file's blocks may be shared */
#define XFS_DIFLAG2_COWEXTSIZE_BIT 2 /* copy on write extent size hint */
+#define XFS_DIFLAG2_IOMAP_IMMUTABLE_BIT 3 /* set S_IOMAP_IMMUTABLE for this inode */
#define XFS_DIFLAG2_DAX (1 << XFS_DIFLAG2_DAX_BIT)
#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT)
#define XFS_DIFLAG2_COWEXTSIZE (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
+#define XFS_DIFLAG2_IOMAP_IMMUTABLE (1 << XFS_DIFLAG2_IOMAP_IMMUTABLE_BIT)
#define XFS_DIFLAG2_ANY \
- (XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE)
+ (XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
+ XFS_DIFLAG2_IOMAP_IMMUTABLE)
/*
* Inode number format:
@@ -674,6 +674,8 @@ _xfs_dic2xflags(
flags |= FS_XFLAG_DAX;
if (di_flags2 & XFS_DIFLAG2_COWEXTSIZE)
flags |= FS_XFLAG_COWEXTSIZE;
+ if (di_flags2 & XFS_DIFLAG2_IOMAP_IMMUTABLE)
+ flags |= FS_XFLAG_IOMAP_IMMUTABLE;
}
if (has_attr)
@@ -978,6 +978,7 @@ xfs_set_diflags(
return;
di_flags2 = (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK);
+ di_flags2 |= (ip->i_d.di_flags2 & XFS_DIFLAG2_IOMAP_IMMUTABLE);
if (xflags & FS_XFLAG_DAX)
di_flags2 |= XFS_DIFLAG2_DAX;
if (xflags & FS_XFLAG_COWEXTSIZE)
@@ -1186,9 +1186,10 @@ xfs_diflags_to_iflags(
struct xfs_inode *ip)
{
uint16_t flags = ip->i_d.di_flags;
+ uint64_t flags2 = ip->i_d.di_flags2;
inode->i_flags &= ~(S_IMMUTABLE | S_APPEND | S_SYNC |
- S_NOATIME | S_DAX);
+ S_NOATIME | S_DAX | S_IOMAP_IMMUTABLE);
if (flags & XFS_DIFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
@@ -1201,9 +1202,10 @@ xfs_diflags_to_iflags(
if (S_ISREG(inode->i_mode) &&
ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
!xfs_is_reflink_inode(ip) &&
- (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
- ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+ (ip->i_mount->m_flags & XFS_MOUNT_DAX || flags2 & XFS_DIFLAG2_DAX))
inode->i_flags |= S_DAX;
+ if (flags2 & XFS_DIFLAG2_IOMAP_IMMUTABLE)
+ inode->i_flags |= S_IOMAP_IMMUTABLE;
}
/*
@@ -182,6 +182,7 @@ struct fsxattr {
#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
#define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */
#define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */
+#define FS_XFLAG_IOMAP_IMMUTABLE 0x00020000 /* block map immutable */
#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
/* the read-only stuff doesn't really belong here, but any other place is
Add an on-disk inode flag to record the state of the S_IOMAP_IMMUTABLE in-memory vfs inode flags. This allows the protections against reflink and hole punch to be automatically restored on a sub-sequent boot when the in-memory inode is established. The FS_XFLAG_IOMAP_IMMUTABLE is introduced to allow xfs_io to read the state of the flag, but toggling the flag requires going through fallocate(FALLOC_FL_[UN]SEAL_BLOCK_MAP). Support for toggling this on-disk state is saved for a later patch. Cc: Jan Kara <jack@suse.cz> Cc: Jeff Moyer <jmoyer@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Suggested-by: Dave Chinner <david@fromorbit.com> Suggested-by: "Darrick J. Wong" <darrick.wong@oracle.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- fs/xfs/libxfs/xfs_format.h | 5 ++++- fs/xfs/xfs_inode.c | 2 ++ fs/xfs/xfs_ioctl.c | 1 + fs/xfs/xfs_iops.c | 8 +++++--- include/uapi/linux/fs.h | 1 + 5 files changed, 13 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html