提交 0f285c8a 编写于 作者: C Christoph Hellwig 提交者: Niv Sardi

[XFS] Now that xfs_setattr is only used for attributes set from ->setattr

it can be switched to take struct iattr directly and thus simplify the
implementation greatly. Also rename the ATTR_ flags to XFS_ATTR_ to not
conflict with the ATTR_ flags used by the VFS.

SGI-PV: 984565

SGI-Modid: xfs-linux-melb:xfs-kern:31678a
Signed-off-by: NChristoph Hellwig <hch@infradead.org>
Signed-off-by: NTim Shimmin <tes@sgi.com>
Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
上级 25fe55e8
...@@ -688,9 +688,9 @@ xfs_ioc_space( ...@@ -688,9 +688,9 @@ xfs_ioc_space(
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= ATTR_NONBLOCK; attr_flags |= XFS_ATTR_NONBLOCK;
if (ioflags & IO_INVIS) if (ioflags & IO_INVIS)
attr_flags |= ATTR_DMI; attr_flags |= XFS_ATTR_DMI;
error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos, error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos,
NULL, attr_flags); NULL, attr_flags);
......
...@@ -648,54 +648,20 @@ xfs_vn_getattr( ...@@ -648,54 +648,20 @@ xfs_vn_getattr(
STATIC int STATIC int
xfs_vn_setattr( xfs_vn_setattr(
struct dentry *dentry, struct dentry *dentry,
struct iattr *attr) struct iattr *iattr)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
unsigned int ia_valid = attr->ia_valid;
bhv_vattr_t vattr = { 0 };
int flags = 0;
int error; int error;
if (ia_valid & ATTR_UID) { if (iattr->ia_valid & ATTR_ATIME)
vattr.va_mask |= XFS_AT_UID; inode->i_atime = iattr->ia_atime;
vattr.va_uid = attr->ia_uid;
} if (iattr->ia_valid & ATTR_MODE) {
if (ia_valid & ATTR_GID) {
vattr.va_mask |= XFS_AT_GID;
vattr.va_gid = attr->ia_gid;
}
if (ia_valid & ATTR_SIZE) {
vattr.va_mask |= XFS_AT_SIZE;
vattr.va_size = attr->ia_size;
}
if (ia_valid & ATTR_ATIME) {
vattr.va_mask |= XFS_AT_ATIME;
vattr.va_atime = attr->ia_atime;
inode->i_atime = attr->ia_atime;
}
if (ia_valid & ATTR_MTIME) {
vattr.va_mask |= XFS_AT_MTIME;
vattr.va_mtime = attr->ia_mtime;
}
if (ia_valid & ATTR_CTIME) {
vattr.va_mask |= XFS_AT_CTIME;
vattr.va_ctime = attr->ia_ctime;
}
if (ia_valid & ATTR_MODE) {
vattr.va_mask |= XFS_AT_MODE;
vattr.va_mode = attr->ia_mode;
if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
inode->i_mode &= ~S_ISGID; inode->i_mode &= ~S_ISGID;
} }
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) error = xfs_setattr(XFS_I(inode), iattr, 0, NULL);
flags |= ATTR_UTIME;
#ifdef ATTR_NO_BLOCK
if ((ia_valid & ATTR_NO_BLOCK))
flags |= ATTR_NONBLOCK;
#endif
error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL);
if (likely(!error)) if (likely(!error))
vn_revalidate(vn_from_inode(inode)); vn_revalidate(vn_from_inode(inode));
return -error; return -error;
...@@ -739,18 +705,18 @@ xfs_vn_fallocate( ...@@ -739,18 +705,18 @@ xfs_vn_fallocate(
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,
0, NULL, ATTR_NOLOCK); 0, NULL, XFS_ATTR_NOLOCK);
if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && if (!error && !(mode & FALLOC_FL_KEEP_SIZE) &&
offset + len > i_size_read(inode)) offset + len > i_size_read(inode))
new_size = offset + len; new_size = offset + len;
/* Change file size if needed */ /* Change file size if needed */
if (new_size) { if (new_size) {
bhv_vattr_t va; struct iattr iattr;
va.va_mask = XFS_AT_SIZE; iattr.ia_valid = ATTR_SIZE;
va.va_size = new_size; iattr.ia_size = new_size;
error = xfs_setattr(ip, &va, ATTR_NOLOCK, NULL); error = xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK, NULL);
} }
xfs_iunlock(ip, XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL);
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#define __XFS_VNODE_H__ #define __XFS_VNODE_H__
struct file; struct file;
struct bhv_vattr;
struct xfs_iomap; struct xfs_iomap;
struct attrlist_cursor_kern; struct attrlist_cursor_kern;
...@@ -66,69 +65,6 @@ static inline struct inode *vn_to_inode(bhv_vnode_t *vnode) ...@@ -66,69 +65,6 @@ static inline struct inode *vn_to_inode(bhv_vnode_t *vnode)
Prevent VM access to the pages until Prevent VM access to the pages until
the operation completes. */ the operation completes. */
/*
* Vnode attributes. va_mask indicates those attributes the caller
* wants to set or extract.
*/
typedef struct bhv_vattr {
int va_mask; /* bit-mask of attributes present */
mode_t va_mode; /* file access mode and type */
xfs_nlink_t va_nlink; /* number of references to file */
uid_t va_uid; /* owner user id */
gid_t va_gid; /* owner group id */
xfs_ino_t va_nodeid; /* file id */
xfs_off_t va_size; /* file size in bytes */
u_long va_blocksize; /* blocksize preferred for i/o */
struct timespec va_atime; /* time of last access */
struct timespec va_mtime; /* time of last modification */
struct timespec va_ctime; /* time file changed */
u_int va_gen; /* generation number of file */
xfs_dev_t va_rdev; /* device the special file represents */
__int64_t va_nblocks; /* number of blocks allocated */
u_long va_xflags; /* random extended file flags */
u_long va_extsize; /* file extent size */
u_long va_nextents; /* number of extents in file */
u_long va_anextents; /* number of attr extents in file */
prid_t va_projid; /* project id */
} bhv_vattr_t;
/*
* setattr or getattr attributes
*/
#define XFS_AT_TYPE 0x00000001
#define XFS_AT_MODE 0x00000002
#define XFS_AT_UID 0x00000004
#define XFS_AT_GID 0x00000008
#define XFS_AT_FSID 0x00000010
#define XFS_AT_NODEID 0x00000020
#define XFS_AT_NLINK 0x00000040
#define XFS_AT_SIZE 0x00000080
#define XFS_AT_ATIME 0x00000100
#define XFS_AT_MTIME 0x00000200
#define XFS_AT_CTIME 0x00000400
#define XFS_AT_RDEV 0x00000800
#define XFS_AT_BLKSIZE 0x00001000
#define XFS_AT_NBLOCKS 0x00002000
#define XFS_AT_VCODE 0x00004000
#define XFS_AT_MAC 0x00008000
#define XFS_AT_UPDATIME 0x00010000
#define XFS_AT_UPDMTIME 0x00020000
#define XFS_AT_UPDCTIME 0x00040000
#define XFS_AT_ACL 0x00080000
#define XFS_AT_CAP 0x00100000
#define XFS_AT_INF 0x00200000
#define XFS_AT_NEXTENTS 0x01000000
#define XFS_AT_ANEXTENTS 0x02000000
#define XFS_AT_SIZE_NOPERM 0x08000000
#define XFS_AT_GENCOUNT 0x10000000
#define XFS_AT_TIMES (XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME)
#define XFS_AT_UPDTIMES (XFS_AT_UPDATIME|XFS_AT_UPDMTIME|XFS_AT_UPDCTIME)
#define XFS_AT_NOSET (XFS_AT_NLINK|XFS_AT_RDEV|XFS_AT_FSID|XFS_AT_NODEID|\
XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\
XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT)
extern void vn_init(void); extern void vn_init(void);
extern int vn_revalidate(bhv_vnode_t *); extern int vn_revalidate(bhv_vnode_t *);
...@@ -204,15 +140,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) ...@@ -204,15 +140,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
PAGECACHE_TAG_DIRTY) PAGECACHE_TAG_DIRTY)
/*
* Flags to vop_setattr/getattr.
*/
#define ATTR_UTIME 0x01 /* non-default utime(2) request */
#define ATTR_DMI 0x08 /* invocation from a DMI function */
#define ATTR_LAZY 0x80 /* set/get attributes lazily */
#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
/* /*
* Tracking vnode activity. * Tracking vnode activity.
......
...@@ -719,7 +719,7 @@ xfs_acl_setmode( ...@@ -719,7 +719,7 @@ xfs_acl_setmode(
xfs_acl_t *acl, xfs_acl_t *acl,
int *basicperms) int *basicperms)
{ {
bhv_vattr_t va; struct iattr iattr;
xfs_acl_entry_t *ap; xfs_acl_entry_t *ap;
xfs_acl_entry_t *gap = NULL; xfs_acl_entry_t *gap = NULL;
int i, nomask = 1; int i, nomask = 1;
...@@ -733,25 +733,25 @@ xfs_acl_setmode( ...@@ -733,25 +733,25 @@ xfs_acl_setmode(
* Copy the u::, g::, o::, and m:: bits from the ACL into the * Copy the u::, g::, o::, and m:: bits from the ACL into the
* mode. The m:: bits take precedence over the g:: bits. * mode. The m:: bits take precedence over the g:: bits.
*/ */
va.va_mask = XFS_AT_MODE; iattr.ia_valid = ATTR_MODE;
va.va_mode = xfs_vtoi(vp)->i_d.di_mode; iattr.ia_mode = xfs_vtoi(vp)->i_d.di_mode;
va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); iattr.ia_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO);
ap = acl->acl_entry; ap = acl->acl_entry;
for (i = 0; i < acl->acl_cnt; ++i) { for (i = 0; i < acl->acl_cnt; ++i) {
switch (ap->ae_tag) { switch (ap->ae_tag) {
case ACL_USER_OBJ: case ACL_USER_OBJ:
va.va_mode |= ap->ae_perm << 6; iattr.ia_mode |= ap->ae_perm << 6;
break; break;
case ACL_GROUP_OBJ: case ACL_GROUP_OBJ:
gap = ap; gap = ap;
break; break;
case ACL_MASK: /* more than just standard modes */ case ACL_MASK: /* more than just standard modes */
nomask = 0; nomask = 0;
va.va_mode |= ap->ae_perm << 3; iattr.ia_mode |= ap->ae_perm << 3;
*basicperms = 0; *basicperms = 0;
break; break;
case ACL_OTHER: case ACL_OTHER:
va.va_mode |= ap->ae_perm; iattr.ia_mode |= ap->ae_perm;
break; break;
default: /* more than just standard modes */ default: /* more than just standard modes */
*basicperms = 0; *basicperms = 0;
...@@ -762,9 +762,9 @@ xfs_acl_setmode( ...@@ -762,9 +762,9 @@ xfs_acl_setmode(
/* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */ /* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */
if (gap && nomask) if (gap && nomask)
va.va_mode |= gap->ae_perm << 3; iattr.ia_mode |= gap->ae_perm << 3;
return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred); return xfs_setattr(xfs_vtoi(vp), &iattr, 0, sys_cred);
} }
/* /*
......
...@@ -166,6 +166,6 @@ typedef enum { ...@@ -166,6 +166,6 @@ typedef enum {
#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \ #define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
DM_FLAGS_NDELAY : 0) DM_FLAGS_NDELAY : 0)
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) #define AT_DELAY_FLAG(f) ((f & XFS_ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
#endif /* __XFS_DMAPI_H__ */ #endif /* __XFS_DMAPI_H__ */
...@@ -75,19 +75,16 @@ xfs_open( ...@@ -75,19 +75,16 @@ xfs_open(
return 0; return 0;
} }
/*
* xfs_setattr
*/
int int
xfs_setattr( xfs_setattr(
xfs_inode_t *ip, struct xfs_inode *ip,
bhv_vattr_t *vap, struct iattr *iattr,
int flags, int flags,
cred_t *credp) cred_t *credp)
{ {
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
int mask = iattr->ia_valid;
xfs_trans_t *tp; xfs_trans_t *tp;
int mask;
int code; int code;
uint lock_flags; uint lock_flags;
uint commit_flags=0; uint commit_flags=0;
...@@ -103,30 +100,9 @@ xfs_setattr( ...@@ -103,30 +100,9 @@ xfs_setattr(
if (mp->m_flags & XFS_MOUNT_RDONLY) if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS); return XFS_ERROR(EROFS);
/*
* Cannot set certain attributes.
*/
mask = vap->va_mask;
if (mask & XFS_AT_NOSET) {
return XFS_ERROR(EINVAL);
}
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
/*
* Timestamps do not need to be logged and hence do not
* need to be done within a transaction.
*/
if (mask & XFS_AT_UPDTIMES) {
ASSERT((mask & ~XFS_AT_UPDTIMES) == 0);
timeflags = ((mask & XFS_AT_UPDATIME) ? XFS_ICHGTIME_ACC : 0) |
((mask & XFS_AT_UPDCTIME) ? XFS_ICHGTIME_CHG : 0) |
((mask & XFS_AT_UPDMTIME) ? XFS_ICHGTIME_MOD : 0);
xfs_ichgtime(ip, timeflags);
return 0;
}
olddquot1 = olddquot2 = NULL; olddquot1 = olddquot2 = NULL;
udqp = gdqp = NULL; udqp = gdqp = NULL;
...@@ -138,17 +114,17 @@ xfs_setattr( ...@@ -138,17 +114,17 @@ xfs_setattr(
* If the IDs do change before we take the ilock, we're covered * If the IDs do change before we take the ilock, we're covered
* because the i_*dquot fields will get updated anyway. * because the i_*dquot fields will get updated anyway.
*/ */
if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) {
uint qflags = 0; uint qflags = 0;
if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) { if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) {
uid = vap->va_uid; uid = iattr->ia_uid;
qflags |= XFS_QMOPT_UQUOTA; qflags |= XFS_QMOPT_UQUOTA;
} else { } else {
uid = ip->i_d.di_uid; uid = ip->i_d.di_uid;
} }
if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) { if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) {
gid = vap->va_gid; gid = iattr->ia_gid;
qflags |= XFS_QMOPT_GQUOTA; qflags |= XFS_QMOPT_GQUOTA;
} else { } else {
gid = ip->i_d.di_gid; gid = ip->i_d.di_gid;
...@@ -173,10 +149,10 @@ xfs_setattr( ...@@ -173,10 +149,10 @@ xfs_setattr(
*/ */
tp = NULL; tp = NULL;
lock_flags = XFS_ILOCK_EXCL; lock_flags = XFS_ILOCK_EXCL;
if (flags & ATTR_NOLOCK) if (flags & XFS_ATTR_NOLOCK)
need_iolock = 0; need_iolock = 0;
if (!(mask & XFS_AT_SIZE)) { if (!(mask & ATTR_SIZE)) {
if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || if ((mask != (ATTR_CTIME|ATTR_ATIME|ATTR_MTIME)) ||
(mp->m_flags & XFS_MOUNT_WSYNC)) { (mp->m_flags & XFS_MOUNT_WSYNC)) {
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
commit_flags = 0; commit_flags = 0;
...@@ -189,10 +165,10 @@ xfs_setattr( ...@@ -189,10 +165,10 @@ xfs_setattr(
} }
} else { } else {
if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
!(flags & ATTR_DMI)) { !(flags & XFS_ATTR_DMI)) {
int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, ip, code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, ip,
vap->va_size, 0, dmflags, NULL); iattr->ia_size, 0, dmflags, NULL);
if (code) { if (code) {
lock_flags = 0; lock_flags = 0;
goto error_return; goto error_return;
...@@ -212,7 +188,7 @@ xfs_setattr( ...@@ -212,7 +188,7 @@ xfs_setattr(
* Only the owner or users with CAP_FOWNER * Only the owner or users with CAP_FOWNER
* capability may do these things. * capability may do these things.
*/ */
if (mask & (XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID)) { if (mask & (ATTR_MODE|ATTR_UID|ATTR_GID)) {
/* /*
* CAP_FOWNER overrides the following restrictions: * CAP_FOWNER overrides the following restrictions:
* *
...@@ -236,21 +212,21 @@ xfs_setattr( ...@@ -236,21 +212,21 @@ xfs_setattr(
* IDs of the calling process shall match the group owner of * IDs of the calling process shall match the group owner of
* the file when setting the set-group-ID bit on that file * the file when setting the set-group-ID bit on that file
*/ */
if (mask & XFS_AT_MODE) { if (mask & ATTR_MODE) {
mode_t m = 0; mode_t m = 0;
if ((vap->va_mode & S_ISUID) && !file_owner) if ((iattr->ia_mode & S_ISUID) && !file_owner)
m |= S_ISUID; m |= S_ISUID;
if ((vap->va_mode & S_ISGID) && if ((iattr->ia_mode & S_ISGID) &&
!in_group_p((gid_t)ip->i_d.di_gid)) !in_group_p((gid_t)ip->i_d.di_gid))
m |= S_ISGID; m |= S_ISGID;
#if 0 #if 0
/* Linux allows this, Irix doesn't. */ /* Linux allows this, Irix doesn't. */
if ((vap->va_mode & S_ISVTX) && !S_ISDIR(ip->i_d.di_mode)) if ((iattr->ia_mode & S_ISVTX) && !S_ISDIR(ip->i_d.di_mode))
m |= S_ISVTX; m |= S_ISVTX;
#endif #endif
if (m && !capable(CAP_FSETID)) if (m && !capable(CAP_FSETID))
vap->va_mode &= ~m; iattr->ia_mode &= ~m;
} }
} }
...@@ -261,7 +237,7 @@ xfs_setattr( ...@@ -261,7 +237,7 @@ xfs_setattr(
* and can change the group id only to a group of which he * and can change the group id only to a group of which he
* or she is a member. * or she is a member.
*/ */
if (mask & (XFS_AT_UID|XFS_AT_GID)) { if (mask & (ATTR_UID|ATTR_GID)) {
/* /*
* These IDs could have changed since we last looked at them. * These IDs could have changed since we last looked at them.
* But, we're assured that if the ownership did change * But, we're assured that if the ownership did change
...@@ -270,8 +246,8 @@ xfs_setattr( ...@@ -270,8 +246,8 @@ xfs_setattr(
*/ */
iuid = ip->i_d.di_uid; iuid = ip->i_d.di_uid;
igid = ip->i_d.di_gid; igid = ip->i_d.di_gid;
gid = (mask & XFS_AT_GID) ? vap->va_gid : igid; gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid; uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
/* /*
* CAP_CHOWN overrides the following restrictions: * CAP_CHOWN overrides the following restrictions:
...@@ -308,13 +284,13 @@ xfs_setattr( ...@@ -308,13 +284,13 @@ xfs_setattr(
/* /*
* Truncate file. Must have write permission and not be a directory. * Truncate file. Must have write permission and not be a directory.
*/ */
if (mask & XFS_AT_SIZE) { if (mask & ATTR_SIZE) {
/* Short circuit the truncate case for zero length files */ /* Short circuit the truncate case for zero length files */
if ((vap->va_size == 0) && if (iattr->ia_size == 0 &&
(ip->i_size == 0) && (ip->i_d.di_nextents == 0)) { ip->i_size == 0 && ip->i_d.di_nextents == 0) {
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
lock_flags &= ~XFS_ILOCK_EXCL; lock_flags &= ~XFS_ILOCK_EXCL;
if (mask & XFS_AT_CTIME) if (mask & ATTR_CTIME)
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
code = 0; code = 0;
goto error_return; goto error_return;
...@@ -337,9 +313,9 @@ xfs_setattr( ...@@ -337,9 +313,9 @@ xfs_setattr(
/* /*
* Change file access or modified times. * Change file access or modified times.
*/ */
if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) { if (mask & (ATTR_ATIME|ATTR_MTIME)) {
if (!file_owner) { if (!file_owner) {
if ((flags & ATTR_UTIME) && if ((mask & (ATTR_MTIME_SET|ATTR_ATIME_SET)) &&
!capable(CAP_FOWNER)) { !capable(CAP_FOWNER)) {
code = XFS_ERROR(EPERM); code = XFS_ERROR(EPERM);
goto error_return; goto error_return;
...@@ -349,23 +325,22 @@ xfs_setattr( ...@@ -349,23 +325,22 @@ xfs_setattr(
/* /*
* Now we can make the changes. Before we join the inode * Now we can make the changes. Before we join the inode
* to the transaction, if XFS_AT_SIZE is set then take care of * to the transaction, if ATTR_SIZE is set then take care of
* the part of the truncation that must be done without the * the part of the truncation that must be done without the
* inode lock. This needs to be done before joining the inode * inode lock. This needs to be done before joining the inode
* to the transaction, because the inode cannot be unlocked * to the transaction, because the inode cannot be unlocked
* once it is a part of the transaction. * once it is a part of the transaction.
*/ */
if (mask & XFS_AT_SIZE) { if (mask & ATTR_SIZE) {
code = 0; code = 0;
if ((vap->va_size > ip->i_size) && if (iattr->ia_size > ip->i_size) {
(flags & ATTR_NOSIZETOK) == 0) {
/* /*
* Do the first part of growing a file: zero any data * Do the first part of growing a file: zero any data
* in the last block that is beyond the old EOF. We * in the last block that is beyond the old EOF. We
* need to do this before the inode is joined to the * need to do this before the inode is joined to the
* transaction to modify the i_size. * transaction to modify the i_size.
*/ */
code = xfs_zero_eof(ip, vap->va_size, ip->i_size); code = xfs_zero_eof(ip, iattr->ia_size, ip->i_size);
} }
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
...@@ -382,10 +357,10 @@ xfs_setattr( ...@@ -382,10 +357,10 @@ xfs_setattr(
* not within the range we care about here. * not within the range we care about here.
*/ */
if (!code && if (!code &&
(ip->i_size != ip->i_d.di_size) && ip->i_size != ip->i_d.di_size &&
(vap->va_size > ip->i_d.di_size)) { iattr->ia_size > ip->i_d.di_size) {
code = xfs_flush_pages(ip, code = xfs_flush_pages(ip,
ip->i_d.di_size, vap->va_size, ip->i_d.di_size, iattr->ia_size,
XFS_B_ASYNC, FI_NONE); XFS_B_ASYNC, FI_NONE);
} }
...@@ -393,7 +368,7 @@ xfs_setattr( ...@@ -393,7 +368,7 @@ xfs_setattr(
vn_iowait(ip); vn_iowait(ip);
if (!code) if (!code)
code = xfs_itruncate_data(ip, vap->va_size); code = xfs_itruncate_data(ip, iattr->ia_size);
if (code) { if (code) {
ASSERT(tp == NULL); ASSERT(tp == NULL);
lock_flags &= ~XFS_ILOCK_EXCL; lock_flags &= ~XFS_ILOCK_EXCL;
...@@ -422,31 +397,30 @@ xfs_setattr( ...@@ -422,31 +397,30 @@ xfs_setattr(
/* /*
* Truncate file. Must have write permission and not be a directory. * Truncate file. Must have write permission and not be a directory.
*/ */
if (mask & XFS_AT_SIZE) { if (mask & ATTR_SIZE) {
/* /*
* Only change the c/mtime if we are changing the size * Only change the c/mtime if we are changing the size
* or we are explicitly asked to change it. This handles * or we are explicitly asked to change it. This handles
* the semantic difference between truncate() and ftruncate() * the semantic difference between truncate() and ftruncate()
* as implemented in the VFS. * as implemented in the VFS.
*/ */
if (vap->va_size != ip->i_size || (mask & XFS_AT_CTIME)) if (iattr->ia_size != ip->i_size || (mask & ATTR_CTIME))
timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
if (vap->va_size > ip->i_size) { if (iattr->ia_size > ip->i_size) {
ip->i_d.di_size = vap->va_size; ip->i_d.di_size = iattr->ia_size;
ip->i_size = vap->va_size; ip->i_size = iattr->ia_size;
if (!(flags & ATTR_DMI)) if (!(flags & XFS_ATTR_DMI))
xfs_ichgtime(ip, XFS_ICHGTIME_CHG); xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
} else if ((vap->va_size <= ip->i_size) || } else if (iattr->ia_size <= ip->i_size ||
((vap->va_size == 0) && ip->i_d.di_nextents)) { (iattr->ia_size == 0 && ip->i_d.di_nextents)) {
/* /*
* signal a sync transaction unless * signal a sync transaction unless
* we're truncating an already unlinked * we're truncating an already unlinked
* file on a wsync filesystem * file on a wsync filesystem
*/ */
code = xfs_itruncate_finish(&tp, ip, code = xfs_itruncate_finish(&tp, ip, iattr->ia_size,
(xfs_fsize_t)vap->va_size,
XFS_DATA_FORK, XFS_DATA_FORK,
((ip->i_d.di_nlink != 0 || ((ip->i_d.di_nlink != 0 ||
!(mp->m_flags & XFS_MOUNT_WSYNC)) !(mp->m_flags & XFS_MOUNT_WSYNC))
...@@ -468,9 +442,9 @@ xfs_setattr( ...@@ -468,9 +442,9 @@ xfs_setattr(
/* /*
* Change file access modes. * Change file access modes.
*/ */
if (mask & XFS_AT_MODE) { if (mask & ATTR_MODE) {
ip->i_d.di_mode &= S_IFMT; ip->i_d.di_mode &= S_IFMT;
ip->i_d.di_mode |= vap->va_mode & ~S_IFMT; ip->i_d.di_mode |= iattr->ia_mode & ~S_IFMT;
xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
timeflags |= XFS_ICHGTIME_CHG; timeflags |= XFS_ICHGTIME_CHG;
...@@ -483,7 +457,7 @@ xfs_setattr( ...@@ -483,7 +457,7 @@ xfs_setattr(
* and can change the group id only to a group of which he * and can change the group id only to a group of which he
* or she is a member. * or she is a member.
*/ */
if (mask & (XFS_AT_UID|XFS_AT_GID)) { if (mask & (ATTR_UID|ATTR_GID)) {
/* /*
* CAP_FSETID overrides the following restrictions: * CAP_FSETID overrides the following restrictions:
* *
...@@ -501,7 +475,7 @@ xfs_setattr( ...@@ -501,7 +475,7 @@ xfs_setattr(
*/ */
if (iuid != uid) { if (iuid != uid) {
if (XFS_IS_UQUOTA_ON(mp)) { if (XFS_IS_UQUOTA_ON(mp)) {
ASSERT(mask & XFS_AT_UID); ASSERT(mask & ATTR_UID);
ASSERT(udqp); ASSERT(udqp);
olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
&ip->i_udquot, udqp); &ip->i_udquot, udqp);
...@@ -511,7 +485,7 @@ xfs_setattr( ...@@ -511,7 +485,7 @@ xfs_setattr(
if (igid != gid) { if (igid != gid) {
if (XFS_IS_GQUOTA_ON(mp)) { if (XFS_IS_GQUOTA_ON(mp)) {
ASSERT(!XFS_IS_PQUOTA_ON(mp)); ASSERT(!XFS_IS_PQUOTA_ON(mp));
ASSERT(mask & XFS_AT_GID); ASSERT(mask & ATTR_GID);
ASSERT(gdqp); ASSERT(gdqp);
olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
&ip->i_gdquot, gdqp); &ip->i_gdquot, gdqp);
...@@ -527,31 +501,31 @@ xfs_setattr( ...@@ -527,31 +501,31 @@ xfs_setattr(
/* /*
* Change file access or modified times. * Change file access or modified times.
*/ */
if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) { if (mask & (ATTR_ATIME|ATTR_MTIME)) {
if (mask & XFS_AT_ATIME) { if (mask & ATTR_ATIME) {
ip->i_d.di_atime.t_sec = vap->va_atime.tv_sec; ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
ip->i_d.di_atime.t_nsec = vap->va_atime.tv_nsec; ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
ip->i_update_core = 1; ip->i_update_core = 1;
timeflags &= ~XFS_ICHGTIME_ACC; timeflags &= ~XFS_ICHGTIME_ACC;
} }
if (mask & XFS_AT_MTIME) { if (mask & ATTR_MTIME) {
ip->i_d.di_mtime.t_sec = vap->va_mtime.tv_sec; ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
ip->i_d.di_mtime.t_nsec = vap->va_mtime.tv_nsec; ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
timeflags &= ~XFS_ICHGTIME_MOD; timeflags &= ~XFS_ICHGTIME_MOD;
timeflags |= XFS_ICHGTIME_CHG; timeflags |= XFS_ICHGTIME_CHG;
} }
if (tp && (flags & ATTR_UTIME)) if (tp && (mask & (ATTR_MTIME_SET|ATTR_ATIME_SET)))
xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
} }
/* /*
* Change file inode change time only if XFS_AT_CTIME set * Change file inode change time only if ATTR_CTIME set
* AND we have been called by a DMI function. * AND we have been called by a DMI function.
*/ */
if ( (flags & ATTR_DMI) && (mask & XFS_AT_CTIME) ) { if ((flags & XFS_ATTR_DMI) && (mask & ATTR_CTIME)) {
ip->i_d.di_ctime.t_sec = vap->va_ctime.tv_sec; ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
ip->i_d.di_ctime.t_nsec = vap->va_ctime.tv_nsec; ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
ip->i_update_core = 1; ip->i_update_core = 1;
timeflags &= ~XFS_ICHGTIME_CHG; timeflags &= ~XFS_ICHGTIME_CHG;
} }
...@@ -560,7 +534,7 @@ xfs_setattr( ...@@ -560,7 +534,7 @@ xfs_setattr(
* Send out timestamp changes that need to be set to the * Send out timestamp changes that need to be set to the
* current time. Not done when called by a DMI function. * current time. Not done when called by a DMI function.
*/ */
if (timeflags && !(flags & ATTR_DMI)) if (timeflags && !(flags & XFS_ATTR_DMI))
xfs_ichgtime(ip, timeflags); xfs_ichgtime(ip, timeflags);
XFS_STATS_INC(xs_ig_attrchg); XFS_STATS_INC(xs_ig_attrchg);
...@@ -598,7 +572,7 @@ xfs_setattr( ...@@ -598,7 +572,7 @@ xfs_setattr(
} }
if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
!(flags & ATTR_DMI)) { !(flags & XFS_ATTR_DMI)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL, (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL, NULL, NULL, NULL, DM_RIGHT_NULL, NULL, NULL,
0, 0, AT_DELAY_FLAG(flags)); 0, 0, AT_DELAY_FLAG(flags));
...@@ -3113,7 +3087,7 @@ xfs_alloc_file_space( ...@@ -3113,7 +3087,7 @@ xfs_alloc_file_space(
/* Generate a DMAPI event if needed. */ /* Generate a DMAPI event if needed. */
if (alloc_type != 0 && offset < ip->i_size && if (alloc_type != 0 && offset < ip->i_size &&
(attr_flags&ATTR_DMI) == 0 && (attr_flags & XFS_ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
xfs_off_t end_dmi_offset; xfs_off_t end_dmi_offset;
...@@ -3227,7 +3201,7 @@ xfs_alloc_file_space( ...@@ -3227,7 +3201,7 @@ xfs_alloc_file_space(
allocatesize_fsb -= allocated_fsb; allocatesize_fsb -= allocated_fsb;
} }
dmapi_enospc_check: dmapi_enospc_check:
if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 && if (error == ENOSPC && (attr_flags & XFS_ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) { DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
ip, DM_RIGHT_NULL, ip, DM_RIGHT_NULL,
...@@ -3374,7 +3348,7 @@ xfs_free_file_space( ...@@ -3374,7 +3348,7 @@ xfs_free_file_space(
end_dmi_offset = offset + len; end_dmi_offset = offset + len;
endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 && if (offset < ip->i_size && (attr_flags & XFS_ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
if (end_dmi_offset > ip->i_size) if (end_dmi_offset > ip->i_size)
end_dmi_offset = ip->i_size; end_dmi_offset = ip->i_size;
...@@ -3385,7 +3359,7 @@ xfs_free_file_space( ...@@ -3385,7 +3359,7 @@ xfs_free_file_space(
return error; return error;
} }
if (attr_flags & ATTR_NOLOCK) if (attr_flags & XFS_ATTR_NOLOCK)
need_iolock = 0; need_iolock = 0;
if (need_iolock) { if (need_iolock) {
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
...@@ -3562,7 +3536,7 @@ xfs_change_file_space( ...@@ -3562,7 +3536,7 @@ xfs_change_file_space(
xfs_off_t startoffset; xfs_off_t startoffset;
xfs_off_t llen; xfs_off_t llen;
xfs_trans_t *tp; xfs_trans_t *tp;
bhv_vattr_t va; struct iattr iattr;
xfs_itrace_entry(ip); xfs_itrace_entry(ip);
...@@ -3636,10 +3610,10 @@ xfs_change_file_space( ...@@ -3636,10 +3610,10 @@ xfs_change_file_space(
break; break;
} }
va.va_mask = XFS_AT_SIZE; iattr.ia_valid = ATTR_SIZE;
va.va_size = startoffset; iattr.ia_size = startoffset;
error = xfs_setattr(ip, &va, attr_flags, credp); error = xfs_setattr(ip, &iattr, attr_flags, credp);
if (error) if (error)
return error; return error;
...@@ -3669,7 +3643,7 @@ xfs_change_file_space( ...@@ -3669,7 +3643,7 @@ xfs_change_file_space(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip); xfs_trans_ihold(tp, ip);
if ((attr_flags & ATTR_DMI) == 0) { if ((attr_flags & XFS_ATTR_DMI) == 0) {
ip->i_d.di_mode &= ~S_ISUID; ip->i_d.di_mode &= ~S_ISUID;
/* /*
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
#define _XFS_VNODEOPS_H 1 #define _XFS_VNODEOPS_H 1
struct attrlist_cursor_kern; struct attrlist_cursor_kern;
struct bhv_vattr;
struct cred; struct cred;
struct file; struct file;
struct iattr;
struct inode; struct inode;
struct iovec; struct iovec;
struct kiocb; struct kiocb;
...@@ -15,8 +15,12 @@ struct xfs_iomap; ...@@ -15,8 +15,12 @@ struct xfs_iomap;
int xfs_open(struct xfs_inode *ip); int xfs_open(struct xfs_inode *ip);
int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags,
struct cred *credp); struct cred *credp);
#define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */
#define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */
#define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */
int xfs_readlink(struct xfs_inode *ip, char *link); int xfs_readlink(struct xfs_inode *ip, char *link);
int xfs_fsync(struct xfs_inode *ip); int xfs_fsync(struct xfs_inode *ip);
int xfs_release(struct xfs_inode *ip); int xfs_release(struct xfs_inode *ip);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册