Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c931f77 authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-setxattr-promotion' into for-next

parents dde7f55b 58f88ca2
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -984,8 +984,6 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)

/*
 * Values for di_flags
 * There should be a one-to-one correspondence between these flags and the
 * XFS_XFLAG_s.
 */
#define XFS_DIFLAG_REALTIME_BIT  0	/* file's blocks come from rt area */
#define XFS_DIFLAG_PREALLOC_BIT  1	/* file space has been preallocated */
@@ -1025,6 +1023,15 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
	 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM)

/*
 * Values for di_flags2 These start by being exposed to userspace in the upper
 * 16 bits of the XFS_XFLAG_s range.
 */
#define XFS_DIFLAG2_DAX_BIT	0	/* use DAX for this inode */
#define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)

#define XFS_DIFLAG2_ANY		(XFS_DIFLAG2_DAX)

/*
 * Inode number format:
 * low inopblog bits - offset in block
+2 −36
Original line number Diff line number Diff line
@@ -35,40 +35,6 @@ struct dioattr {
};
#endif

/*
 * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
 */
#ifndef HAVE_FSXATTR
struct fsxattr {
	__u32		fsx_xflags;	/* xflags field value (get/set) */
	__u32		fsx_extsize;	/* extsize field value (get/set)*/
	__u32		fsx_nextents;	/* nextents field value (get)	*/
	__u32		fsx_projid;	/* project identifier (get/set) */
	unsigned char	fsx_pad[12];
};
#endif

/*
 * Flags for the bs_xflags/fsx_xflags field
 * There should be a one-to-one correspondence between these flags and the
 * XFS_DIFLAG_s.
 */
#define XFS_XFLAG_REALTIME	0x00000001	/* data in realtime volume */
#define XFS_XFLAG_PREALLOC	0x00000002	/* preallocated file extents */
#define XFS_XFLAG_IMMUTABLE	0x00000008	/* file cannot be modified */
#define XFS_XFLAG_APPEND	0x00000010	/* all writes append */
#define XFS_XFLAG_SYNC		0x00000020	/* all writes synchronous */
#define XFS_XFLAG_NOATIME	0x00000040	/* do not update access time */
#define XFS_XFLAG_NODUMP	0x00000080	/* do not include in backups */
#define XFS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
#define XFS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
#define XFS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
#define XFS_XFLAG_EXTSIZE	0x00000800	/* extent size allocator hint */
#define XFS_XFLAG_EXTSZINHERIT	0x00001000	/* inherit inode extent size */
#define XFS_XFLAG_NODEFRAG	0x00002000  	/* do not defragment */
#define XFS_XFLAG_FILESTREAM	0x00004000	/* use filestream allocator */
#define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/

/*
 * Structure for XFS_IOC_GETBMAP.
 * On input, fill in bmv_offset and bmv_length of the first structure
@@ -514,8 +480,8 @@ typedef struct xfs_swapext
#define XFS_IOC_ALLOCSP		_IOW ('X', 10, struct xfs_flock64)
#define XFS_IOC_FREESP		_IOW ('X', 11, struct xfs_flock64)
#define XFS_IOC_DIOINFO		_IOR ('X', 30, struct dioattr)
#define XFS_IOC_FSGETXATTR	_IOR ('X', 31, struct fsxattr)
#define XFS_IOC_FSSETXATTR	_IOW ('X', 32, struct fsxattr)
#define XFS_IOC_FSGETXATTR	FS_IOC_FSGETXATTR
#define XFS_IOC_FSSETXATTR	FS_IOC_FSSETXATTR
#define XFS_IOC_ALLOCSP64	_IOW ('X', 36, struct xfs_flock64)
#define XFS_IOC_FREESP64	_IOW ('X', 37, struct xfs_flock64)
#define XFS_IOC_GETBMAP		_IOWR('X', 38, struct getbmap)
+37 −23
Original line number Diff line number Diff line
@@ -610,60 +610,69 @@ __xfs_iflock(

STATIC uint
_xfs_dic2xflags(
	__uint16_t		di_flags)
	__uint16_t		di_flags,
	uint64_t		di_flags2,
	bool			has_attr)
{
	uint			flags = 0;

	if (di_flags & XFS_DIFLAG_ANY) {
		if (di_flags & XFS_DIFLAG_REALTIME)
			flags |= XFS_XFLAG_REALTIME;
			flags |= FS_XFLAG_REALTIME;
		if (di_flags & XFS_DIFLAG_PREALLOC)
			flags |= XFS_XFLAG_PREALLOC;
			flags |= FS_XFLAG_PREALLOC;
		if (di_flags & XFS_DIFLAG_IMMUTABLE)
			flags |= XFS_XFLAG_IMMUTABLE;
			flags |= FS_XFLAG_IMMUTABLE;
		if (di_flags & XFS_DIFLAG_APPEND)
			flags |= XFS_XFLAG_APPEND;
			flags |= FS_XFLAG_APPEND;
		if (di_flags & XFS_DIFLAG_SYNC)
			flags |= XFS_XFLAG_SYNC;
			flags |= FS_XFLAG_SYNC;
		if (di_flags & XFS_DIFLAG_NOATIME)
			flags |= XFS_XFLAG_NOATIME;
			flags |= FS_XFLAG_NOATIME;
		if (di_flags & XFS_DIFLAG_NODUMP)
			flags |= XFS_XFLAG_NODUMP;
			flags |= FS_XFLAG_NODUMP;
		if (di_flags & XFS_DIFLAG_RTINHERIT)
			flags |= XFS_XFLAG_RTINHERIT;
			flags |= FS_XFLAG_RTINHERIT;
		if (di_flags & XFS_DIFLAG_PROJINHERIT)
			flags |= XFS_XFLAG_PROJINHERIT;
			flags |= FS_XFLAG_PROJINHERIT;
		if (di_flags & XFS_DIFLAG_NOSYMLINKS)
			flags |= XFS_XFLAG_NOSYMLINKS;
			flags |= FS_XFLAG_NOSYMLINKS;
		if (di_flags & XFS_DIFLAG_EXTSIZE)
			flags |= XFS_XFLAG_EXTSIZE;
			flags |= FS_XFLAG_EXTSIZE;
		if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
			flags |= XFS_XFLAG_EXTSZINHERIT;
			flags |= FS_XFLAG_EXTSZINHERIT;
		if (di_flags & XFS_DIFLAG_NODEFRAG)
			flags |= XFS_XFLAG_NODEFRAG;
			flags |= FS_XFLAG_NODEFRAG;
		if (di_flags & XFS_DIFLAG_FILESTREAM)
			flags |= XFS_XFLAG_FILESTREAM;
			flags |= FS_XFLAG_FILESTREAM;
	}

	if (di_flags2 & XFS_DIFLAG2_ANY) {
		if (di_flags2 & XFS_DIFLAG2_DAX)
			flags |= FS_XFLAG_DAX;
	}

	if (has_attr)
		flags |= FS_XFLAG_HASATTR;

	return flags;
}

uint
xfs_ip2xflags(
	xfs_inode_t		*ip)
	struct xfs_inode	*ip)
{
	xfs_icdinode_t		*dic = &ip->i_d;
	struct xfs_icdinode	*dic = &ip->i_d;

	return _xfs_dic2xflags(dic->di_flags) |
				(XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
	return _xfs_dic2xflags(dic->di_flags, dic->di_flags2, XFS_IFORK_Q(ip));
}

uint
xfs_dic2xflags(
	xfs_dinode_t		*dip)
	struct xfs_dinode	*dip)
{
	return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
				(XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
	return _xfs_dic2xflags(be16_to_cpu(dip->di_flags),
				be64_to_cpu(dip->di_flags2), XFS_DFORK_Q(dip));
}

/*
@@ -862,6 +871,7 @@ xfs_ialloc(
	case S_IFREG:
	case S_IFDIR:
		if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
			uint64_t	di_flags2 = 0;
			uint		di_flags = 0;

			if (S_ISDIR(mode)) {
@@ -898,7 +908,11 @@ xfs_ialloc(
				di_flags |= XFS_DIFLAG_NODEFRAG;
			if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
				di_flags |= XFS_DIFLAG_FILESTREAM;
			if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
				di_flags2 |= XFS_DIFLAG2_DAX;

			ip->i_d.di_flags |= di_flags;
			ip->i_d.di_flags2 |= di_flags2;
		}
		/* FALLTHROUGH */
	case S_IFLNK:
+54 −38
Original line number Diff line number Diff line
@@ -859,25 +859,25 @@ xfs_merge_ioc_xflags(
	unsigned int	xflags = start;

	if (flags & FS_IMMUTABLE_FL)
		xflags |= XFS_XFLAG_IMMUTABLE;
		xflags |= FS_XFLAG_IMMUTABLE;
	else
		xflags &= ~XFS_XFLAG_IMMUTABLE;
		xflags &= ~FS_XFLAG_IMMUTABLE;
	if (flags & FS_APPEND_FL)
		xflags |= XFS_XFLAG_APPEND;
		xflags |= FS_XFLAG_APPEND;
	else
		xflags &= ~XFS_XFLAG_APPEND;
		xflags &= ~FS_XFLAG_APPEND;
	if (flags & FS_SYNC_FL)
		xflags |= XFS_XFLAG_SYNC;
		xflags |= FS_XFLAG_SYNC;
	else
		xflags &= ~XFS_XFLAG_SYNC;
		xflags &= ~FS_XFLAG_SYNC;
	if (flags & FS_NOATIME_FL)
		xflags |= XFS_XFLAG_NOATIME;
		xflags |= FS_XFLAG_NOATIME;
	else
		xflags &= ~XFS_XFLAG_NOATIME;
		xflags &= ~FS_XFLAG_NOATIME;
	if (flags & FS_NODUMP_FL)
		xflags |= XFS_XFLAG_NODUMP;
		xflags |= FS_XFLAG_NODUMP;
	else
		xflags &= ~XFS_XFLAG_NODUMP;
		xflags &= ~FS_XFLAG_NODUMP;

	return xflags;
}
@@ -945,40 +945,51 @@ xfs_set_diflags(
	unsigned int		xflags)
{
	unsigned int		di_flags;
	uint64_t		di_flags2;

	/* can't set PREALLOC this way, just preserve it */
	di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
	if (xflags & XFS_XFLAG_IMMUTABLE)
	if (xflags & FS_XFLAG_IMMUTABLE)
		di_flags |= XFS_DIFLAG_IMMUTABLE;
	if (xflags & XFS_XFLAG_APPEND)
	if (xflags & FS_XFLAG_APPEND)
		di_flags |= XFS_DIFLAG_APPEND;
	if (xflags & XFS_XFLAG_SYNC)
	if (xflags & FS_XFLAG_SYNC)
		di_flags |= XFS_DIFLAG_SYNC;
	if (xflags & XFS_XFLAG_NOATIME)
	if (xflags & FS_XFLAG_NOATIME)
		di_flags |= XFS_DIFLAG_NOATIME;
	if (xflags & XFS_XFLAG_NODUMP)
	if (xflags & FS_XFLAG_NODUMP)
		di_flags |= XFS_DIFLAG_NODUMP;
	if (xflags & XFS_XFLAG_NODEFRAG)
	if (xflags & FS_XFLAG_NODEFRAG)
		di_flags |= XFS_DIFLAG_NODEFRAG;
	if (xflags & XFS_XFLAG_FILESTREAM)
	if (xflags & FS_XFLAG_FILESTREAM)
		di_flags |= XFS_DIFLAG_FILESTREAM;
	if (S_ISDIR(ip->i_d.di_mode)) {
		if (xflags & XFS_XFLAG_RTINHERIT)
		if (xflags & FS_XFLAG_RTINHERIT)
			di_flags |= XFS_DIFLAG_RTINHERIT;
		if (xflags & XFS_XFLAG_NOSYMLINKS)
		if (xflags & FS_XFLAG_NOSYMLINKS)
			di_flags |= XFS_DIFLAG_NOSYMLINKS;
		if (xflags & XFS_XFLAG_EXTSZINHERIT)
		if (xflags & FS_XFLAG_EXTSZINHERIT)
			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
		if (xflags & XFS_XFLAG_PROJINHERIT)
		if (xflags & FS_XFLAG_PROJINHERIT)
			di_flags |= XFS_DIFLAG_PROJINHERIT;
	} else if (S_ISREG(ip->i_d.di_mode)) {
		if (xflags & XFS_XFLAG_REALTIME)
		if (xflags & FS_XFLAG_REALTIME)
			di_flags |= XFS_DIFLAG_REALTIME;
		if (xflags & XFS_XFLAG_EXTSIZE)
		if (xflags & FS_XFLAG_EXTSIZE)
			di_flags |= XFS_DIFLAG_EXTSIZE;
	}

	ip->i_d.di_flags = di_flags;

	/* diflags2 only valid for v3 inodes. */
	if (ip->i_d.di_version < 3)
		return;

	di_flags2 = 0;
	if (xflags & FS_XFLAG_DAX)
		di_flags2 |= XFS_DIFLAG2_DAX;

	ip->i_d.di_flags2 = di_flags2;

}

STATIC void
@@ -988,22 +999,27 @@ xfs_diflags_to_linux(
	struct inode		*inode = VFS_I(ip);
	unsigned int		xflags = xfs_ip2xflags(ip);

	if (xflags & XFS_XFLAG_IMMUTABLE)
	if (xflags & FS_XFLAG_IMMUTABLE)
		inode->i_flags |= S_IMMUTABLE;
	else
		inode->i_flags &= ~S_IMMUTABLE;
	if (xflags & XFS_XFLAG_APPEND)
	if (xflags & FS_XFLAG_APPEND)
		inode->i_flags |= S_APPEND;
	else
		inode->i_flags &= ~S_APPEND;
	if (xflags & XFS_XFLAG_SYNC)
	if (xflags & FS_XFLAG_SYNC)
		inode->i_flags |= S_SYNC;
	else
		inode->i_flags &= ~S_SYNC;
	if (xflags & XFS_XFLAG_NOATIME)
	if (xflags & FS_XFLAG_NOATIME)
		inode->i_flags |= S_NOATIME;
	else
		inode->i_flags &= ~S_NOATIME;
	if (xflags & FS_XFLAG_DAX)
		inode->i_flags |= S_DAX;
	else
		inode->i_flags &= ~S_DAX;

}

static int
@@ -1016,11 +1032,11 @@ xfs_ioctl_setattr_xflags(

	/* Can't change realtime flag if any extents are allocated. */
	if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
	    XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & XFS_XFLAG_REALTIME))
	    XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
		return -EINVAL;

	/* If realtime flag is set then must have realtime device */
	if (fa->fsx_xflags & XFS_XFLAG_REALTIME) {
	if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
		if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
		    (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
			return -EINVAL;
@@ -1031,7 +1047,7 @@ xfs_ioctl_setattr_xflags(
	 * we have appropriate permission.
	 */
	if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
	     (fa->fsx_xflags & (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
	     (fa->fsx_xflags & (FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND))) &&
	    !capable(CAP_LINUX_IMMUTABLE))
		return -EPERM;

@@ -1095,8 +1111,8 @@ xfs_ioctl_setattr_get_trans(
 * extent size hint validation is somewhat cumbersome. Rules are:
 *
 * 1. extent size hint is only valid for directories and regular files
 * 2. XFS_XFLAG_EXTSIZE is only valid for regular files
 * 3. XFS_XFLAG_EXTSZINHERIT is only valid for directories.
 * 2. FS_XFLAG_EXTSIZE is only valid for regular files
 * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
 * 4. can only be changed on regular files if no extents are allocated
 * 5. can be changed on directories at any time
 * 6. extsize hint of 0 turns off hints, clears inode flags.
@@ -1112,10 +1128,10 @@ xfs_ioctl_setattr_check_extsize(
{
	struct xfs_mount	*mp = ip->i_mount;

	if ((fa->fsx_xflags & XFS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
	if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
		return -EINVAL;

	if ((fa->fsx_xflags & XFS_XFLAG_EXTSZINHERIT) &&
	if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
	    !S_ISDIR(ip->i_d.di_mode))
		return -EINVAL;

@@ -1132,7 +1148,7 @@ xfs_ioctl_setattr_check_extsize(
			return -EINVAL;

		if (XFS_IS_REALTIME_INODE(ip) ||
		    (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
		    (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
			size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
		} else {
			size = mp->m_sb.sb_blocksize;
@@ -1143,7 +1159,7 @@ xfs_ioctl_setattr_check_extsize(
		if (fa->fsx_extsize % size)
			return -EINVAL;
	} else
		fa->fsx_xflags &= ~(XFS_XFLAG_EXTSIZE | XFS_XFLAG_EXTSZINHERIT);
		fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);

	return 0;
}
@@ -1168,7 +1184,7 @@ xfs_ioctl_setattr_check_projid(

	if (xfs_get_projid(ip) != fa->fsx_projid)
		return -EINVAL;
	if ((fa->fsx_xflags & XFS_XFLAG_PROJINHERIT) !=
	if ((fa->fsx_xflags & FS_XFLAG_PROJINHERIT) !=
	    (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
		return -EINVAL;

+2 −2
Original line number Diff line number Diff line
@@ -1201,8 +1201,8 @@ xfs_diflags_to_iflags(
		inode->i_flags |= S_SYNC;
	if (flags & XFS_DIFLAG_NOATIME)
		inode->i_flags |= S_NOATIME;
	/* XXX: Also needs an on-disk per inode flag! */
	if (ip->i_mount->m_flags & XFS_MOUNT_DAX)
	if (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
	    ip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
		inode->i_flags |= S_DAX;
}

Loading