Commit d5ffdf8b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-for-linus-4.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs

Pull more xfs updates from Dave Chinner:
 "This is the second update for XFS that I mentioned in the original
  pull request last week.

  It contains a revert for a suspend regression in 4.4 and a fix for a
  long standing log recovery issue that has been further exposed by all
  the log recovery changes made in the original 4.5 merge.

  There is one more thing in this pull request - one that I forgot to
  merge into the origin.  That is, pulling the XFS_IOC_FS[GS]ETXATTR
  ioctl up to the VFS level so that other filesystems can also use it
  for modifying project quota IDs

  Summary:

   - promotion of XFS_IOC_FS[GS]ETXATTR ioctl to the vfs level so that
     it can be shared with other filesystems.  The ext4 project quota
     functionality is the first target for this.  The commits in this
     series have not been updated with review or final SOB tags because
     the branch they were originally published in was needed by ext4.
     Those tags are:
Reviewed-by: default avatarTheodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarDave Chinner <david@fromrobit.com>

   - Revert a change that is causing suspend failures.

   - Fix a use-after-free that can occur on log mount failures.  Been
     around forever, but now exposed by other changes to log recovery
     made in the first 4.5 merge"

* tag 'xfs-for-linus-4.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs:
  xfs: log mount failures don't wait for buffers to be released
  Revert "xfs: clear PF_NOFREEZE for xfsaild kthread"
  xfs: introduce per-inode DAX enablement
  xfs: use FS_XFLAG definitions directly
  fs: XFS_IOC_FS[SG]SETXATTR to FS_IOC_FS[SG]ETXATTR promotion
parents eadee0ce ee3804d9
...@@ -984,8 +984,6 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) ...@@ -984,8 +984,6 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
/* /*
* Values for di_flags * 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_REALTIME_BIT 0 /* file's blocks come from rt area */
#define XFS_DIFLAG_PREALLOC_BIT 1 /* file space has been preallocated */ #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) ...@@ -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_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) 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: * Inode number format:
* low inopblog bits - offset in block * low inopblog bits - offset in block
......
...@@ -35,40 +35,6 @@ struct dioattr { ...@@ -35,40 +35,6 @@ struct dioattr {
}; };
#endif #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. * Structure for XFS_IOC_GETBMAP.
* On input, fill in bmv_offset and bmv_length of the first structure * On input, fill in bmv_offset and bmv_length of the first structure
...@@ -514,8 +480,8 @@ typedef struct xfs_swapext ...@@ -514,8 +480,8 @@ typedef struct xfs_swapext
#define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64) #define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
#define XFS_IOC_FREESP _IOW ('X', 11, 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_DIOINFO _IOR ('X', 30, struct dioattr)
#define XFS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr) #define XFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
#define XFS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr) #define XFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
#define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64) #define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
#define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64) #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
#define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap) #define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)
......
...@@ -1527,6 +1527,16 @@ xfs_wait_buftarg( ...@@ -1527,6 +1527,16 @@ xfs_wait_buftarg(
LIST_HEAD(dispose); LIST_HEAD(dispose);
int loop = 0; int loop = 0;
/*
* We need to flush the buffer workqueue to ensure that all IO
* completion processing is 100% done. Just waiting on buffer locks is
* not sufficient for async IO as the reference count held over IO is
* not released until after the buffer lock is dropped. Hence we need to
* ensure here that all reference counts have been dropped before we
* start walking the LRU list.
*/
drain_workqueue(btp->bt_mount->m_buf_workqueue);
/* loop until there is nothing left on the lru list. */ /* loop until there is nothing left on the lru list. */
while (list_lru_count(&btp->bt_lru)) { while (list_lru_count(&btp->bt_lru)) {
list_lru_walk(&btp->bt_lru, xfs_buftarg_wait_rele, list_lru_walk(&btp->bt_lru, xfs_buftarg_wait_rele,
......
...@@ -610,60 +610,69 @@ __xfs_iflock( ...@@ -610,60 +610,69 @@ __xfs_iflock(
STATIC uint STATIC uint
_xfs_dic2xflags( _xfs_dic2xflags(
__uint16_t di_flags) __uint16_t di_flags,
uint64_t di_flags2,
bool has_attr)
{ {
uint flags = 0; uint flags = 0;
if (di_flags & XFS_DIFLAG_ANY) { if (di_flags & XFS_DIFLAG_ANY) {
if (di_flags & XFS_DIFLAG_REALTIME) if (di_flags & XFS_DIFLAG_REALTIME)
flags |= XFS_XFLAG_REALTIME; flags |= FS_XFLAG_REALTIME;
if (di_flags & XFS_DIFLAG_PREALLOC) if (di_flags & XFS_DIFLAG_PREALLOC)
flags |= XFS_XFLAG_PREALLOC; flags |= FS_XFLAG_PREALLOC;
if (di_flags & XFS_DIFLAG_IMMUTABLE) if (di_flags & XFS_DIFLAG_IMMUTABLE)
flags |= XFS_XFLAG_IMMUTABLE; flags |= FS_XFLAG_IMMUTABLE;
if (di_flags & XFS_DIFLAG_APPEND) if (di_flags & XFS_DIFLAG_APPEND)
flags |= XFS_XFLAG_APPEND; flags |= FS_XFLAG_APPEND;
if (di_flags & XFS_DIFLAG_SYNC) if (di_flags & XFS_DIFLAG_SYNC)
flags |= XFS_XFLAG_SYNC; flags |= FS_XFLAG_SYNC;
if (di_flags & XFS_DIFLAG_NOATIME) if (di_flags & XFS_DIFLAG_NOATIME)
flags |= XFS_XFLAG_NOATIME; flags |= FS_XFLAG_NOATIME;
if (di_flags & XFS_DIFLAG_NODUMP) if (di_flags & XFS_DIFLAG_NODUMP)
flags |= XFS_XFLAG_NODUMP; flags |= FS_XFLAG_NODUMP;
if (di_flags & XFS_DIFLAG_RTINHERIT) if (di_flags & XFS_DIFLAG_RTINHERIT)
flags |= XFS_XFLAG_RTINHERIT; flags |= FS_XFLAG_RTINHERIT;
if (di_flags & XFS_DIFLAG_PROJINHERIT) if (di_flags & XFS_DIFLAG_PROJINHERIT)
flags |= XFS_XFLAG_PROJINHERIT; flags |= FS_XFLAG_PROJINHERIT;
if (di_flags & XFS_DIFLAG_NOSYMLINKS) if (di_flags & XFS_DIFLAG_NOSYMLINKS)
flags |= XFS_XFLAG_NOSYMLINKS; flags |= FS_XFLAG_NOSYMLINKS;
if (di_flags & XFS_DIFLAG_EXTSIZE) if (di_flags & XFS_DIFLAG_EXTSIZE)
flags |= XFS_XFLAG_EXTSIZE; flags |= FS_XFLAG_EXTSIZE;
if (di_flags & XFS_DIFLAG_EXTSZINHERIT) if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
flags |= XFS_XFLAG_EXTSZINHERIT; flags |= FS_XFLAG_EXTSZINHERIT;
if (di_flags & XFS_DIFLAG_NODEFRAG) if (di_flags & XFS_DIFLAG_NODEFRAG)
flags |= XFS_XFLAG_NODEFRAG; flags |= FS_XFLAG_NODEFRAG;
if (di_flags & XFS_DIFLAG_FILESTREAM) 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; return flags;
} }
uint uint
xfs_ip2xflags( 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) | return _xfs_dic2xflags(dic->di_flags, dic->di_flags2, XFS_IFORK_Q(ip));
(XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
} }
uint uint
xfs_dic2xflags( xfs_dic2xflags(
xfs_dinode_t *dip) struct xfs_dinode *dip)
{ {
return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) | return _xfs_dic2xflags(be16_to_cpu(dip->di_flags),
(XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); be64_to_cpu(dip->di_flags2), XFS_DFORK_Q(dip));
} }
/* /*
...@@ -862,6 +871,7 @@ xfs_ialloc( ...@@ -862,6 +871,7 @@ xfs_ialloc(
case S_IFREG: case S_IFREG:
case S_IFDIR: case S_IFDIR:
if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
uint64_t di_flags2 = 0;
uint di_flags = 0; uint di_flags = 0;
if (S_ISDIR(mode)) { if (S_ISDIR(mode)) {
...@@ -898,7 +908,11 @@ xfs_ialloc( ...@@ -898,7 +908,11 @@ xfs_ialloc(
di_flags |= XFS_DIFLAG_NODEFRAG; di_flags |= XFS_DIFLAG_NODEFRAG;
if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM) if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
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_flags |= di_flags;
ip->i_d.di_flags2 |= di_flags2;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case S_IFLNK: case S_IFLNK:
......
...@@ -859,25 +859,25 @@ xfs_merge_ioc_xflags( ...@@ -859,25 +859,25 @@ xfs_merge_ioc_xflags(
unsigned int xflags = start; unsigned int xflags = start;
if (flags & FS_IMMUTABLE_FL) if (flags & FS_IMMUTABLE_FL)
xflags |= XFS_XFLAG_IMMUTABLE; xflags |= FS_XFLAG_IMMUTABLE;
else else
xflags &= ~XFS_XFLAG_IMMUTABLE; xflags &= ~FS_XFLAG_IMMUTABLE;
if (flags & FS_APPEND_FL) if (flags & FS_APPEND_FL)
xflags |= XFS_XFLAG_APPEND; xflags |= FS_XFLAG_APPEND;
else else
xflags &= ~XFS_XFLAG_APPEND; xflags &= ~FS_XFLAG_APPEND;
if (flags & FS_SYNC_FL) if (flags & FS_SYNC_FL)
xflags |= XFS_XFLAG_SYNC; xflags |= FS_XFLAG_SYNC;
else else
xflags &= ~XFS_XFLAG_SYNC; xflags &= ~FS_XFLAG_SYNC;
if (flags & FS_NOATIME_FL) if (flags & FS_NOATIME_FL)
xflags |= XFS_XFLAG_NOATIME; xflags |= FS_XFLAG_NOATIME;
else else
xflags &= ~XFS_XFLAG_NOATIME; xflags &= ~FS_XFLAG_NOATIME;
if (flags & FS_NODUMP_FL) if (flags & FS_NODUMP_FL)
xflags |= XFS_XFLAG_NODUMP; xflags |= FS_XFLAG_NODUMP;
else else
xflags &= ~XFS_XFLAG_NODUMP; xflags &= ~FS_XFLAG_NODUMP;
return xflags; return xflags;
} }
...@@ -945,40 +945,51 @@ xfs_set_diflags( ...@@ -945,40 +945,51 @@ xfs_set_diflags(
unsigned int xflags) unsigned int xflags)
{ {
unsigned int di_flags; unsigned int di_flags;
uint64_t di_flags2;
/* can't set PREALLOC this way, just preserve it */ /* can't set PREALLOC this way, just preserve it */
di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); 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; di_flags |= XFS_DIFLAG_IMMUTABLE;
if (xflags & XFS_XFLAG_APPEND) if (xflags & FS_XFLAG_APPEND)
di_flags |= XFS_DIFLAG_APPEND; di_flags |= XFS_DIFLAG_APPEND;
if (xflags & XFS_XFLAG_SYNC) if (xflags & FS_XFLAG_SYNC)
di_flags |= XFS_DIFLAG_SYNC; di_flags |= XFS_DIFLAG_SYNC;
if (xflags & XFS_XFLAG_NOATIME) if (xflags & FS_XFLAG_NOATIME)
di_flags |= XFS_DIFLAG_NOATIME; di_flags |= XFS_DIFLAG_NOATIME;
if (xflags & XFS_XFLAG_NODUMP) if (xflags & FS_XFLAG_NODUMP)
di_flags |= XFS_DIFLAG_NODUMP; di_flags |= XFS_DIFLAG_NODUMP;
if (xflags & XFS_XFLAG_NODEFRAG) if (xflags & FS_XFLAG_NODEFRAG)
di_flags |= XFS_DIFLAG_NODEFRAG; di_flags |= XFS_DIFLAG_NODEFRAG;
if (xflags & XFS_XFLAG_FILESTREAM) if (xflags & FS_XFLAG_FILESTREAM)
di_flags |= XFS_DIFLAG_FILESTREAM; di_flags |= XFS_DIFLAG_FILESTREAM;
if (S_ISDIR(ip->i_d.di_mode)) { if (S_ISDIR(ip->i_d.di_mode)) {
if (xflags & XFS_XFLAG_RTINHERIT) if (xflags & FS_XFLAG_RTINHERIT)
di_flags |= XFS_DIFLAG_RTINHERIT; di_flags |= XFS_DIFLAG_RTINHERIT;
if (xflags & XFS_XFLAG_NOSYMLINKS) if (xflags & FS_XFLAG_NOSYMLINKS)
di_flags |= XFS_DIFLAG_NOSYMLINKS; di_flags |= XFS_DIFLAG_NOSYMLINKS;
if (xflags & XFS_XFLAG_EXTSZINHERIT) if (xflags & FS_XFLAG_EXTSZINHERIT)
di_flags |= XFS_DIFLAG_EXTSZINHERIT; di_flags |= XFS_DIFLAG_EXTSZINHERIT;
if (xflags & XFS_XFLAG_PROJINHERIT) if (xflags & FS_XFLAG_PROJINHERIT)
di_flags |= XFS_DIFLAG_PROJINHERIT; di_flags |= XFS_DIFLAG_PROJINHERIT;
} else if (S_ISREG(ip->i_d.di_mode)) { } else if (S_ISREG(ip->i_d.di_mode)) {
if (xflags & XFS_XFLAG_REALTIME) if (xflags & FS_XFLAG_REALTIME)
di_flags |= XFS_DIFLAG_REALTIME; di_flags |= XFS_DIFLAG_REALTIME;
if (xflags & XFS_XFLAG_EXTSIZE) if (xflags & FS_XFLAG_EXTSIZE)
di_flags |= XFS_DIFLAG_EXTSIZE; di_flags |= XFS_DIFLAG_EXTSIZE;
} }
ip->i_d.di_flags = di_flags; 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 STATIC void
...@@ -988,22 +999,27 @@ xfs_diflags_to_linux( ...@@ -988,22 +999,27 @@ xfs_diflags_to_linux(
struct inode *inode = VFS_I(ip); struct inode *inode = VFS_I(ip);
unsigned int xflags = xfs_ip2xflags(ip); unsigned int xflags = xfs_ip2xflags(ip);
if (xflags & XFS_XFLAG_IMMUTABLE) if (xflags & FS_XFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE; inode->i_flags |= S_IMMUTABLE;
else else
inode->i_flags &= ~S_IMMUTABLE; inode->i_flags &= ~S_IMMUTABLE;
if (xflags & XFS_XFLAG_APPEND) if (xflags & FS_XFLAG_APPEND)
inode->i_flags |= S_APPEND; inode->i_flags |= S_APPEND;
else else
inode->i_flags &= ~S_APPEND; inode->i_flags &= ~S_APPEND;
if (xflags & XFS_XFLAG_SYNC) if (xflags & FS_XFLAG_SYNC)
inode->i_flags |= S_SYNC; inode->i_flags |= S_SYNC;
else else
inode->i_flags &= ~S_SYNC; inode->i_flags &= ~S_SYNC;
if (xflags & XFS_XFLAG_NOATIME) if (xflags & FS_XFLAG_NOATIME)
inode->i_flags |= S_NOATIME; inode->i_flags |= S_NOATIME;
else else
inode->i_flags &= ~S_NOATIME; inode->i_flags &= ~S_NOATIME;
if (xflags & FS_XFLAG_DAX)
inode->i_flags |= S_DAX;
else
inode->i_flags &= ~S_DAX;
} }
static int static int
...@@ -1016,11 +1032,11 @@ xfs_ioctl_setattr_xflags( ...@@ -1016,11 +1032,11 @@ xfs_ioctl_setattr_xflags(
/* Can't change realtime flag if any extents are allocated. */ /* Can't change realtime flag if any extents are allocated. */
if ((ip->i_d.di_nextents || ip->i_delayed_blks) && 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; return -EINVAL;
/* If realtime flag is set then must have realtime device */ /* 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 || if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
(ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
return -EINVAL; return -EINVAL;
...@@ -1031,7 +1047,7 @@ xfs_ioctl_setattr_xflags( ...@@ -1031,7 +1047,7 @@ xfs_ioctl_setattr_xflags(
* we have appropriate permission. * we have appropriate permission.
*/ */
if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) || 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)) !capable(CAP_LINUX_IMMUTABLE))
return -EPERM; return -EPERM;
...@@ -1095,8 +1111,8 @@ xfs_ioctl_setattr_get_trans( ...@@ -1095,8 +1111,8 @@ xfs_ioctl_setattr_get_trans(
* extent size hint validation is somewhat cumbersome. Rules are: * extent size hint validation is somewhat cumbersome. Rules are:
* *
* 1. extent size hint is only valid for directories and regular files * 1. extent size hint is only valid for directories and regular files
* 2. XFS_XFLAG_EXTSIZE is only valid for regular files * 2. FS_XFLAG_EXTSIZE is only valid for regular files
* 3. XFS_XFLAG_EXTSZINHERIT is only valid for directories. * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
* 4. can only be changed on regular files if no extents are allocated * 4. can only be changed on regular files if no extents are allocated
* 5. can be changed on directories at any time * 5. can be changed on directories at any time
* 6. extsize hint of 0 turns off hints, clears inode flags. * 6. extsize hint of 0 turns off hints, clears inode flags.
...@@ -1112,10 +1128,10 @@ xfs_ioctl_setattr_check_extsize( ...@@ -1112,10 +1128,10 @@ xfs_ioctl_setattr_check_extsize(
{ {
struct xfs_mount *mp = ip->i_mount; 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; return -EINVAL;
if ((fa->fsx_xflags & XFS_XFLAG_EXTSZINHERIT) && if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
!S_ISDIR(ip->i_d.di_mode)) !S_ISDIR(ip->i_d.di_mode))
return -EINVAL; return -EINVAL;
...@@ -1132,7 +1148,7 @@ xfs_ioctl_setattr_check_extsize( ...@@ -1132,7 +1148,7 @@ xfs_ioctl_setattr_check_extsize(
return -EINVAL; return -EINVAL;
if (XFS_IS_REALTIME_INODE(ip) || 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; size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
} else { } else {
size = mp->m_sb.sb_blocksize; size = mp->m_sb.sb_blocksize;
...@@ -1143,7 +1159,7 @@ xfs_ioctl_setattr_check_extsize( ...@@ -1143,7 +1159,7 @@ xfs_ioctl_setattr_check_extsize(
if (fa->fsx_extsize % size) if (fa->fsx_extsize % size)
return -EINVAL; return -EINVAL;
} else } else
fa->fsx_xflags &= ~(XFS_XFLAG_EXTSIZE | XFS_XFLAG_EXTSZINHERIT); fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
return 0; return 0;
} }
...@@ -1168,7 +1184,7 @@ xfs_ioctl_setattr_check_projid( ...@@ -1168,7 +1184,7 @@ xfs_ioctl_setattr_check_projid(
if (xfs_get_projid(ip) != fa->fsx_projid) if (xfs_get_projid(ip) != fa->fsx_projid)
return -EINVAL; return -EINVAL;
if ((fa->fsx_xflags & XFS_XFLAG_PROJINHERIT) != if ((fa->fsx_xflags & FS_XFLAG_PROJINHERIT) !=
(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)) (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
return -EINVAL; return -EINVAL;
......
...@@ -1205,8 +1205,8 @@ xfs_diflags_to_iflags( ...@@ -1205,8 +1205,8 @@ xfs_diflags_to_iflags(
inode->i_flags |= S_SYNC; inode->i_flags |= S_SYNC;
if (flags & XFS_DIFLAG_NOATIME) if (flags & XFS_DIFLAG_NOATIME)
inode->i_flags |= S_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; inode->i_flags |= S_DAX;
} }
......
...@@ -497,7 +497,6 @@ xfsaild( ...@@ -497,7 +497,6 @@ xfsaild(
long tout = 0; /* milliseconds */ long tout = 0; /* milliseconds */
current->flags |= PF_MEMALLOC; current->flags |= PF_MEMALLOC;
set_freezable();
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
if (tout && tout <= 20) if (tout && tout <= 20)
......
...@@ -146,6 +146,37 @@ struct inodes_stat_t { ...@@ -146,6 +146,37 @@ struct inodes_stat_t {
#define MS_MGC_VAL 0xC0ED0000 #define MS_MGC_VAL 0xC0ED0000
#define MS_MGC_MSK 0xffff0000 #define MS_MGC_MSK 0xffff0000
/*
* Structure for FS_IOC_FSGETXATTR[A] and FS_IOC_FSSETXATTR.
*/
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];
};
/*
* Flags for the fsx_xflags field
*/
#define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
#define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
#define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
#define FS_XFLAG_APPEND 0x00000010 /* all writes append */
#define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
#define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */
#define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
#define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
#define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
#define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
#define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
#define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */
#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
/* the read-only stuff doesn't really belong here, but any other place is /* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */ probably as bad and I don't want to create yet another include file. */
...@@ -210,6 +241,8 @@ struct inodes_stat_t { ...@@ -210,6 +241,8 @@ struct inodes_stat_t {
#define FS_IOC32_SETFLAGS _IOW('f', 2, int) #define FS_IOC32_SETFLAGS _IOW('f', 2, int)
#define FS_IOC32_GETVERSION _IOR('v', 1, int) #define FS_IOC32_GETVERSION _IOR('v', 1, int)
#define FS_IOC32_SETVERSION _IOW('v', 2, int) #define FS_IOC32_SETVERSION _IOW('v', 2, int)
#define FS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr)
#define FS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr)
/* /*
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment