fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / xfs / xfs_vnodeops.c
index 7151482..2344664 100644 (file)
@@ -160,7 +160,7 @@ xfs_getattr(
        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;
 
        /*
@@ -261,7 +261,7 @@ xfs_setattr(
        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;
@@ -318,7 +318,7 @@ xfs_setattr(
            (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;
@@ -398,7 +398,7 @@ xfs_setattr(
        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:
@@ -448,7 +448,7 @@ xfs_setattr(
         * 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
@@ -457,11 +457,11 @@ xfs_setattr(
                 */
                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;
 
@@ -489,7 +489,7 @@ xfs_setattr(
                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) ?
@@ -715,7 +715,7 @@ xfs_setattr(
         * 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:
                 *
@@ -731,11 +731,8 @@ xfs_setattr(
                 * 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)) {
@@ -1031,7 +1028,7 @@ xfs_readlink(
        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 {
                /*
@@ -1062,7 +1059,7 @@ xfs_readlink(
                                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);
                }
 
@@ -2384,10 +2381,15 @@ xfs_remove(
 
        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;
        }
@@ -3013,7 +3015,7 @@ xfs_rmdir(
        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;
@@ -3028,11 +3030,16 @@ xfs_rmdir(
                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);
        }
@@ -3835,11 +3842,16 @@ xfs_reclaim(
         */
        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);
@@ -3848,11 +3860,13 @@ xfs_reclaim(
        } 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;
@@ -3877,8 +3891,10 @@ xfs_finish_reclaim(
         * 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);
@@ -3886,7 +3902,8 @@ xfs_finish_reclaim(
                }
                return 1;
        }
-       ip->i_flags |= XFS_IRECLAIM;
+       __xfs_iflags_set(ip, XFS_IRECLAIM);
+       spin_unlock(&ip->i_flags_lock);
        write_unlock(&ih->ih_lock);
 
        /*
@@ -4290,7 +4307,7 @@ xfs_free_file_space(
        xfs_mount_t             *mp;
        int                     nimap;
        uint                    resblks;
-       int                     rounding;
+       uint                    rounding;
        int                     rt;
        xfs_fileoff_t           startoffset_fsb;
        xfs_trans_t             *tp;
@@ -4331,8 +4348,7 @@ xfs_free_file_space(
                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))