diff options
author | Brian Behlendorf <[email protected]> | 2016-12-19 13:01:10 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2016-12-19 13:01:10 -0800 |
commit | a3823f428deb8f15dd383dc6210b2e16926f4217 (patch) | |
tree | 23587a8fb08289ce0f871af9265652664719c509 /module/zfs | |
parent | 58bf046ab304482775355b21eacd9f9ccbf62c12 (diff) | |
parent | b4d8e2be036891dcf2fdb510571bdeb9f2c64faa (diff) |
Fix file attributes
This branch contains the following fixes/improvements.
* Fix setting i_flags
* Fix wrong operator in xvattr.h
* Fix fchange macro in zpl_ioctl_setflags()
* Added configure check to use inode_set_flags()
* Added a test case for chattr for better test coverage
Reviewed-by: Tim Chase <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes #5486
Closes #5470
Closes #5469
Diffstat (limited to 'module/zfs')
-rw-r--r-- | module/zfs/zfs_znode.c | 47 | ||||
-rw-r--r-- | module/zfs/zpl_file.c | 3 |
2 files changed, 37 insertions, 13 deletions
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 624e92696..92241d6a5 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -479,6 +479,34 @@ zfs_inode_set_ops(zfs_sb_t *zsb, struct inode *ip) } } +void +zfs_set_inode_flags(znode_t *zp, struct inode *ip) +{ + /* + * Linux and Solaris have different sets of file attributes, so we + * restrict this conversion to the intersection of the two. + */ +#ifdef HAVE_INODE_SET_FLAGS + unsigned int flags = 0; + if (zp->z_pflags & ZFS_IMMUTABLE) + flags |= S_IMMUTABLE; + if (zp->z_pflags & ZFS_APPENDONLY) + flags |= S_APPEND; + + inode_set_flags(ip, flags, S_IMMUTABLE|S_APPEND); +#else + if (zp->z_pflags & ZFS_IMMUTABLE) + ip->i_flags |= S_IMMUTABLE; + else + ip->i_flags &= ~S_IMMUTABLE; + + if (zp->z_pflags & ZFS_APPENDONLY) + ip->i_flags |= S_APPEND; + else + ip->i_flags &= ~S_APPEND; +#endif +} + /* * Update the embedded inode given the znode. We should work toward * eliminating this function as soon as possible by removing values @@ -588,6 +616,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz, set_nlink(ip, (uint32_t)links); zfs_uid_write(ip, z_uid); zfs_gid_write(ip, z_gid); + zfs_set_inode_flags(zp, ip); /* Cache the xattr parent id */ if (zp->z_pflags & ZFS_XATTR) @@ -918,6 +947,7 @@ void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) { xoptattr_t *xoap; + boolean_t update_inode = B_FALSE; xoap = xva_getxoptattr(xvap); ASSERT(xoap); @@ -929,7 +959,6 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) ×, sizeof (times), tx); XVA_SET_RTN(xvap, XAT_CREATETIME); } - if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { ZFS_ATTR_SET(zp, ZFS_READONLY, xoap->xoa_readonly, zp->z_pflags, tx); @@ -955,11 +984,8 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zp->z_pflags, tx); XVA_SET_RTN(xvap, XAT_IMMUTABLE); - ZTOI(zp)->i_flags |= S_IMMUTABLE; - } else { - ZTOI(zp)->i_flags &= ~S_IMMUTABLE; + update_inode = B_TRUE; } - if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { ZFS_ATTR_SET(zp, ZFS_NOUNLINK, xoap->xoa_nounlink, zp->z_pflags, tx); @@ -970,12 +996,8 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zp->z_pflags, tx); XVA_SET_RTN(xvap, XAT_APPENDONLY); - ZTOI(zp)->i_flags |= S_APPEND; - } else { - - ZTOI(zp)->i_flags &= ~S_APPEND; + update_inode = B_TRUE; } - if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { ZFS_ATTR_SET(zp, ZFS_NODUMP, xoap->xoa_nodump, zp->z_pflags, tx); @@ -1015,6 +1037,9 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zp->z_pflags, tx); XVA_SET_RTN(xvap, XAT_SPARSE); } + + if (update_inode) + zfs_set_inode_flags(zp, ZTOI(zp)); } int @@ -1220,12 +1245,12 @@ zfs_rezget(znode_t *zp) zp->z_unlinked = (ZTOI(zp)->i_nlink == 0); set_nlink(ZTOI(zp), (uint32_t)links); + zfs_set_inode_flags(zp, ZTOI(zp)); zp->z_blksz = doi.doi_data_block_size; zp->z_atime_dirty = 0; zfs_inode_update(zp); - zfs_znode_hold_exit(zsb, zh); return (0); diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index a22522028..332fb992e 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -737,8 +737,7 @@ zpl_ioctl_getflags(struct file *filp, void __user *arg) * is outside of our jurisdiction. */ -#define fchange(f0, f1, b0, b1) ((((f0) & (b0)) == (b0)) != \ - (((b1) & (f1)) == (f1))) +#define fchange(f0, f1, b0, b1) (!((f0) & (b0)) != !((f1) & (b1))) static int zpl_ioctl_setflags(struct file *filp, void __user *arg) |