vap->va_mode = ip->i_d.di_mode;
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_tag = ip->i_d.di_tag;
vap->va_projid = ip->i_d.di_projid;
/*
uint commit_flags=0;
uid_t uid=0, iuid=0;
gid_t gid=0, igid=0;
- xid_t xid=0, ixid=0;
+ tag_t tag=0, itag=0;
int timeflags = 0;
bhv_vnode_t *vp;
xfs_prid_t projid=0, iprojid=0;
(mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
uint qflags = 0;
- /* FIXME: handle xid? */
+ /* TODO: handle tagging? */
if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
uid = vap->va_uid;
qflags |= XFS_QMOPT_UQUOTA;
if (mask &
(XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
XFS_AT_GID|XFS_AT_PROJID)) {
- /* FIXME: handle xid? */
+ /* TODO: handle tagging? */
/*
* 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_XID|XFS_AT_PROJID)) {
+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
/*
* These IDs could have changed since we last looked at them.
* But, we're assured that if the ownership did change
*/
iuid = ip->i_d.di_uid;
igid = ip->i_d.di_gid;
- ixid = ip->i_d.di_xid;
+ itag = ip->i_d.di_tag;
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;
+ tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
iprojid;
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
(XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
- /* FIXME: handle xid? */
+ /* TODO: handle tagging? */
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_XID|XFS_AT_PROJID)) {
+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|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 (itag != tag) {
+ ip->i_d.di_tag = tag;
}
if (iuid != uid) {
if (XFS_IS_UQUOTA_ON(mp)) {
pathlen = (int)ip->i_d.di_size;
if (ip->i_df.if_flags & XFS_IFINLINE) {
- error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
+ error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
}
else {
/*
byte_cnt = pathlen;
pathlen -= byte_cnt;
- error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
+ error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
xfs_buf_relse (bp);
}
namelen = VNAMELEN(dentry);
+ if (!xfs_get_dir_entry(dentry, &ip)) {
+ dm_di_mode = ip->i_d.di_mode;
+ IRELE(ip);
+ }
+
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
+ name, NULL, dm_di_mode, 0, 0);
if (error)
return error;
}
int cancel_flags;
int committed;
bhv_vnode_t *dir_vp;
- int dm_di_mode = 0;
+ int dm_di_mode = S_IFDIR;
int last_cdp_link;
int namelen;
uint resblks;
return XFS_ERROR(EIO);
namelen = VNAMELEN(dentry);
+ if (!xfs_get_dir_entry(dentry, &cdp)) {
+ dm_di_mode = cdp->i_d.di_mode;
+ IRELE(cdp);
+ }
+
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
dir_vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
- name, NULL, 0, 0, 0);
+ name, NULL, dm_di_mode, 0, 0);
if (error)
return XFS_ERROR(error);
}
*/
xfs_synchronize_atime(ip);
- /* If we have nothing to flush with this inode then complete the
- * teardown now, otherwise break the link between the xfs inode
- * and the linux inode and clean up the xfs inode later. This
- * avoids flushing the inode to disk during the delete operation
- * itself.
+ /*
+ * If we have nothing to flush with this inode then complete the
+ * teardown now, otherwise break the link between the xfs inode and the
+ * linux inode and clean up the xfs inode later. This avoids flushing
+ * the inode to disk during the delete operation itself.
+ *
+ * When breaking the link, we need to set the XFS_IRECLAIMABLE flag
+ * first to ensure that xfs_iunpin() will never see an xfs inode
+ * that has a linux inode being reclaimed. Synchronisation is provided
+ * by the i_flags_lock.
*/
if (!ip->i_update_core && (ip->i_itemp == NULL)) {
xfs_ilock(ip, XFS_ILOCK_EXCL);
} else {
xfs_mount_t *mp = ip->i_mount;
- /* Protect sync from us */
+ /* Protect sync and unpin from us */
XFS_MOUNT_ILOCK(mp);
+ spin_lock(&ip->i_flags_lock);
+ __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
+ spin_unlock(&ip->i_flags_lock);
list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
- ip->i_flags |= XFS_IRECLAIMABLE;
XFS_MOUNT_IUNLOCK(mp);
}
return 0;
* us.
*/
write_lock(&ih->ih_lock);
- if ((ip->i_flags & XFS_IRECLAIM) ||
- (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
+ spin_lock(&ip->i_flags_lock);
+ if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
+ (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
+ spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);
if (locked) {
xfs_ifunlock(ip);
}
return 1;
}
- ip->i_flags |= XFS_IRECLAIM;
+ __xfs_iflags_set(ip, XFS_IRECLAIM);
+ spin_unlock(&ip->i_flags_lock);
write_unlock(&ih->ih_lock);
/*
xfs_mount_t *mp;
int nimap;
uint resblks;
- int rounding;
+ uint rounding;
int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
vn_iowait(vp); /* wait for the completion of any pending DIOs */
}
- rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
- (__uint8_t)NBPP);
+ rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
ilen = len + (offset & (rounding - 1));
ioffset = offset & ~(rounding - 1);
if (ilen & (rounding - 1))