Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/ufs Eliminate the old ufs_rename. The only reason th...



details:   https://anonhg.NetBSD.org/src/rev/5161c1306808
branches:  trunk
changeset: 767424:5161c1306808
user:      dholland <dholland%NetBSD.org@localhost>
date:      Mon Jul 18 06:45:47 2011 +0000

description:
Eliminate the old ufs_rename. The only reason the WAPBL one was
different is that in order to avoid issues with the WAPBL journal lock
the wrong locking had to be changed to different wrong locking. This
is now moot.

I have not hand-validated that the current two copies of rename are
equivalent, or that the locking fixes merged with the old rename
produce code that is textually identical (modulo WAPBL calls that do
nothing when WAPBL is turned off) to the WAPBL rename... but I did
this check when preparing my previous round of rename patches last
year and all updates since have been applied to both.

diffstat:

 sys/ufs/ufs/ufs_vnops.c |  412 +-----------------------------------------------
 1 files changed, 3 insertions(+), 409 deletions(-)

diffs (truncated from 442 to 300 lines):

diff -r f76129e85d56 -r 5161c1306808 sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c   Mon Jul 18 06:45:27 2011 +0000
+++ b/sys/ufs/ufs/ufs_vnops.c   Mon Jul 18 06:45:47 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_vnops.c,v 1.199 2011/07/18 06:45:27 dholland Exp $ */
+/*     $NetBSD: ufs_vnops.c,v 1.200 2011/07/18 06:45:47 dholland Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.199 2011/07/18 06:45:27 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.200 2011/07/18 06:45:47 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -1300,15 +1300,9 @@
  *    directory was moved and the parent of the destination
  *    is different from the source, patch the ".." entry in the
  *    directory.
- *
- * WAPBL NOTE: wapbl_ufs_rename derived from ufs_rename in ufs_vnops.c
- * ufs_vnops.c netbsd cvs revision 1.108
- * which has the berkeley copyright above
- * changes introduced to ufs_rename since netbsd cvs revision 1.164
- * will need to be ported into wapbl_ufs_rename
  */
 int
-wapbl_ufs_rename(void *v)
+ufs_rename(void *v)
 {
        struct vop_rename_args  /* {
                struct vnode            *a_fdvp;
@@ -1970,406 +1964,6 @@
 }
 
 int
-ufs_rename(void *v)
-{
-       struct vop_rename_args  /* {
-               struct vnode            *a_fdvp;
-               struct vnode            *a_fvp;
-               struct componentname    *a_fcnp;
-               struct vnode            *a_tdvp;
-               struct vnode            *a_tvp;
-               struct componentname    *a_tcnp;
-       } */ *ap = v;
-       struct vnode            *tvp, *tdvp, *fvp, *fdvp;
-       struct componentname    *tcnp, *fcnp;
-       struct inode            *ip, *xp, *dp;
-       struct mount            *mp;
-       struct direct           *newdir;
-       int                     doingdirectory, oldparent, newparent, error;
-       struct ufs_lookup_results from_ulr, to_ulr;
-
-#ifdef WAPBL
-       if (ap->a_tdvp->v_mount->mnt_wapbl)
-               return wapbl_ufs_rename(v);
-#endif
-
-       tvp = ap->a_tvp;
-       tdvp = ap->a_tdvp;
-       fvp = ap->a_fvp;
-       fdvp = ap->a_fdvp;
-       tcnp = ap->a_tcnp;
-       fcnp = ap->a_fcnp;
-       doingdirectory = oldparent = newparent = error = 0;
-
-       /* save the supplemental lookup results as they currently exist */
-       from_ulr = VTOI(fdvp)->i_crap;
-       to_ulr = VTOI(tdvp)->i_crap;
-       UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
-       UFS_CHECK_CRAPCOUNTER(VTOI(tdvp));
-
-       /*
-        * Check for cross-device rename.
-        */
-       if ((fvp->v_mount != tdvp->v_mount) ||
-           (tvp && (fvp->v_mount != tvp->v_mount))) {
-               error = EXDEV;
- abortit:
-               VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
-               if (tdvp == tvp)
-                       vrele(tdvp);
-               else
-                       vput(tdvp);
-               if (tvp)
-                       vput(tvp);
-               VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
-               vrele(fdvp);
-               vrele(fvp);
-               return (error);
-       }
-
-       /*
-        * Check if just deleting a link name.
-        */
-       if (tvp && ((VTOI(tvp)->i_flags & (IMMUTABLE | APPEND)) ||
-           (VTOI(tdvp)->i_flags & APPEND))) {
-               error = EPERM;
-               goto abortit;
-       }
-       if (fvp == tvp) {
-               if (fvp->v_type == VDIR) {
-                       error = EINVAL;
-                       goto abortit;
-               }
-
-               /* Release destination completely. */
-               VOP_ABORTOP(tdvp, tcnp);
-               vput(tdvp);
-               vput(tvp);
-
-               /* Delete source. */
-               vrele(fvp);
-               fcnp->cn_flags &= ~(MODMASK);
-               fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
-               fcnp->cn_nameiop = DELETE;
-               vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
-               if ((error = relookup(fdvp, &fvp, fcnp, 0))) {
-                       vput(fdvp);
-                       return (error);
-               }
-               return (VOP_REMOVE(fdvp, fvp, fcnp));
-       }
-       if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
-               goto abortit;
-       dp = VTOI(fdvp);
-       ip = VTOI(fvp);
-       if ((nlink_t) ip->i_nlink >= LINK_MAX) {
-               VOP_UNLOCK(fvp);
-               error = EMLINK;
-               goto abortit;
-       }
-       if ((ip->i_flags & (IMMUTABLE | APPEND)) ||
-               (dp->i_flags & APPEND)) {
-               VOP_UNLOCK(fvp);
-               error = EPERM;
-               goto abortit;
-       }
-       if ((ip->i_mode & IFMT) == IFDIR) {
-               /*
-                * Avoid ".", "..", and aliases of "." for obvious reasons.
-                */
-               if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
-                   dp == ip ||
-                   (fcnp->cn_flags & ISDOTDOT) ||
-                   (tcnp->cn_flags & ISDOTDOT) ||
-                   (ip->i_flag & IN_RENAME)) {
-                       VOP_UNLOCK(fvp);
-                       error = EINVAL;
-                       goto abortit;
-               }
-               ip->i_flag |= IN_RENAME;
-               oldparent = dp->i_number;
-               doingdirectory = 1;
-       }
-       VN_KNOTE(fdvp, NOTE_WRITE);             /* XXXLUKEM/XXX: right place? */
-
-       /*
-        * When the target exists, both the directory
-        * and target vnodes are returned locked.
-        */
-       dp = VTOI(tdvp);
-       xp = NULL;
-       if (tvp)
-               xp = VTOI(tvp);
-
-       mp = fdvp->v_mount;
-       fstrans_start(mp, FSTRANS_SHARED);
-
-       /*
-        * 1) Bump link count while we're moving stuff
-        *    around.  If we crash somewhere before
-        *    completing our work, the link count
-        *    may be wrong, but correctable.
-        */
-       ip->i_nlink++;
-       DIP_ASSIGN(ip, nlink, ip->i_nlink);
-       ip->i_flag |= IN_CHANGE;
-       if ((error = UFS_UPDATE(fvp, NULL, NULL, UPDATE_DIROP)) != 0) {
-               VOP_UNLOCK(fvp);
-               goto bad;
-       }
-
-       /*
-        * If ".." must be changed (ie the directory gets a new
-        * parent) then the source directory must not be in the
-        * directory hierarchy above the target, as this would
-        * orphan everything below the source directory. Also
-        * the user must have write permission in the source so
-        * as to be able to change "..". We must repeat the call
-        * to namei, as the parent directory is unlocked by the
-        * call to checkpath().
-        */
-       error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
-       VOP_UNLOCK(fvp);
-       if (oldparent != dp->i_number)
-               newparent = dp->i_number;
-       if (doingdirectory && newparent) {
-               if (error)      /* write access check above */
-                       goto bad;
-               if (xp != NULL)
-                       vput(tvp);
-               vref(tdvp);     /* compensate for the ref checkpath loses */
-               if ((error = ufs_checkpath(ip, dp, tcnp->cn_cred)) != 0) {
-                       vrele(tdvp);
-                       goto out;
-               }
-               vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
-               error = relookup(tdvp, &tvp, tcnp, 0);
-               if (error != 0) {
-                       vput(tdvp);
-                       goto out;
-               }
-               dp = VTOI(tdvp);
-
-               /* update the supplemental reasults */
-               to_ulr = dp->i_crap;
-               UFS_CHECK_CRAPCOUNTER(dp);
-
-               xp = NULL;
-               if (tvp)
-                       xp = VTOI(tvp);
-       }
-       /*
-        * 2) If target doesn't exist, link the target
-        *    to the source and unlink the source.
-        *    Otherwise, rewrite the target directory
-        *    entry to reference the source inode and
-        *    expunge the original entry's existence.
-        */
-       if (xp == NULL) {
-               if (dp->i_dev != ip->i_dev)
-                       panic("rename: EXDEV");
-               /*
-                * Account for ".." in new directory.
-                * When source and destination have the same
-                * parent we don't fool with the link count.
-                */
-               if (doingdirectory && newparent) {
-                       if ((nlink_t)dp->i_nlink >= LINK_MAX) {
-                               error = EMLINK;
-                               goto bad;
-                       }
-                       dp->i_nlink++;
-                       DIP_ASSIGN(dp, nlink, dp->i_nlink);
-                       dp->i_flag |= IN_CHANGE;
-                       if ((error = UFS_UPDATE(tdvp, NULL, NULL,
-                           UPDATE_DIROP)) != 0) {
-                               dp->i_nlink--;
-                               DIP_ASSIGN(dp, nlink, dp->i_nlink);
-                               dp->i_flag |= IN_CHANGE;
-                               goto bad;
-                       }
-               }
-               newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK);
-               ufs_makedirentry(ip, tcnp, newdir);
-               error = ufs_direnter(tdvp, &to_ulr,
-                                    NULL, newdir, tcnp, NULL);
-               pool_cache_put(ufs_direct_cache, newdir);
-               if (error != 0) {
-                       if (doingdirectory && newparent) {
-                               dp->i_nlink--;
-                               DIP_ASSIGN(dp, nlink, dp->i_nlink);
-                               dp->i_flag |= IN_CHANGE;
-                               (void)UFS_UPDATE(tdvp, NULL, NULL,
-                                                UPDATE_WAIT|UPDATE_DIROP);
-                       }
-                       goto bad;
-               }
-               VN_KNOTE(tdvp, NOTE_WRITE);
-               vput(tdvp);
-       } else {
-               if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
-                       panic("rename: EXDEV");
-               /*
-                * Short circuit rename(foo, foo).
-                */
-               if (xp->i_number == ip->i_number)
-                       panic("rename: same file");
-               /*
-                * If the parent directory is "sticky", then the user must
-                * own the parent directory, or the destination of the rename,
-                * otherwise the destination may not be changed (except by
-                * root). This implements append-only directories.
-                */
-               if ((dp->i_mode & S_ISTXT) &&
-                   kauth_authorize_generic(tcnp->cn_cred,
-                    KAUTH_GENERIC_ISSUSER, NULL) != 0 &&
-                   kauth_cred_geteuid(tcnp->cn_cred) != dp->i_uid &&
-                   xp->i_uid != kauth_cred_geteuid(tcnp->cn_cred)) {
-                       error = EPERM;
-                       goto bad;
-               }
-               /*
-                * Target must be empty if a directory and have no links
-                * to it. Also, ensure source and target are compatible



Home | Main Index | Thread Index | Old Index