/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
vap->va_mode = ip->i_d.di_mode & MODEMASK;
vap->va_uid = ip->i_d.di_uid;
vap->va_gid = ip->i_d.di_gid;
+ vap->va_xid = ip->i_d.di_xid;
vap->va_projid = ip->i_d.di_projid;
/*
/*
* Convert di_flags to xflags.
*/
- vap->va_xflags = xfs_dic2xflags(&ip->i_d, ARCH_NOCONVERT);
+ vap->va_xflags = xfs_ip2xflags(ip);
/*
* Exit for inode revalidate. See if any of the rest of
uint commit_flags=0;
uid_t uid=0, iuid=0;
gid_t gid=0, igid=0;
+ xid_t xid=0, ixid=0;
int timeflags = 0;
vnode_t *vp;
xfs_prid_t projid=0, iprojid=0;
int mandlock_before, mandlock_after;
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
int file_owner;
- int need_iolock = (flags & ATTR_DMI) == 0;
+ int need_iolock = 1;
vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) {
uint qflags = 0;
+ /* FIXME: handle xid? */
if (mask & XFS_AT_UID) {
uid = vap->va_uid;
qflags |= XFS_QMOPT_UQUOTA;
*/
tp = NULL;
lock_flags = XFS_ILOCK_EXCL;
+ ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
+ if (flags & ATTR_NOLOCK)
+ need_iolock = 0;
if (!(mask & XFS_AT_SIZE)) {
if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
(mp->m_flags & XFS_MOUNT_WSYNC)) {
if (mask &
(XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
XFS_AT_GID|XFS_AT_PROJID)) {
+ /* FIXME: handle xid? */
+
/*
* CAP_FOWNER overrides the following restrictions:
*
* and can change the group id only to a group of which he
* or she is a member.
*/
- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) {
/*
* These IDs could have changed since we last looked at them.
* But, we're assured that if the ownership did change
* would have changed also.
*/
iuid = ip->i_d.di_uid;
- iprojid = ip->i_d.di_projid;
igid = ip->i_d.di_gid;
- gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
+ ixid = ip->i_d.di_xid;
+ iprojid = ip->i_d.di_projid;
uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
+ gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
+ xid = (mask & XFS_AT_XID) ? vap->va_xid : ixid;
projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
iprojid;
*/
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
+ /* FIXME: handle xid? */
ASSERT(tp);
code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ?
* and can change the group id only to a group of which he
* or she is a member.
*/
- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) {
/*
* CAP_FSETID overrides the following restrictions:
*
* Change the ownerships and register quota modifications
* in the transaction.
*/
+ if (ixid != xid) {
+ if (XFS_IS_GQUOTA_ON(mp)) {
+ /* FIXME: handle xid quota? */
+ }
+ ip->i_d.di_xid = xid;
+ }
if (iuid != uid) {
if (XFS_IS_UQUOTA_ON(mp)) {
ASSERT(mask & XFS_AT_UID);
* create transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
* remove transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
* link transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
* mkdir transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
* rmdir transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
* symlink transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
xfs_trans_set_sync(tp);
}
int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
- int need_iolock = (attr_flags & ATTR_DMI) == 0;
+ int need_iolock = 1;
vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
mp = ip->i_mount;
return(error);
}
+ ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
+ if (attr_flags & ATTR_NOLOCK)
+ need_iolock = 0;
if (need_iolock)
xfs_ilock(ip, XFS_IOLOCK_EXCL);
+
rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
(__uint8_t)NBPP);
ilen = len + (offset & (rounding - 1));