]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Support for changes to OS X Mavericks VNOP_SYMLINK() function.
authorKen Hornstein <kenh@cmf.nrl.navy.mil>
Wed, 20 Nov 2013 18:37:52 +0000 (13:37 -0500)
committerStephan Wiesand <stephan.wiesand@desy.de>
Fri, 6 Dec 2013 14:48:25 +0000 (06:48 -0800)
Add support for an extra argument to afs_symlink() to return the
newly-created symlink vnode if requested (this is needed on OS X
Mavericks).  On OS X Mavericks return the newly-created symlink vnode in
the symlink vnops functions, on all other platforms ignore it.

It turns out that technically OS X has required the symlink to be
created for a while, but code inside of symlink() would call namei() on
the symlink name if the returned vnode point was NULL.  The difference
is that on Mavericks the Manditory Access Control Framework has been
enabled, and that turns on some extra code which unconditionally calls
vnode_mount() on the returned vnode pointer, which ends up causing a
panic

Reviewed-on: http://gerrit.openafs.org/10474
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit 3f4c1099b7b2d1467b1f5b701ea2f953fec20dc0)

Change-Id: Ib8bac6fd4ed8fe5c2e9567431f7d03fdab50cd50
Reviewed-on: http://gerrit.openafs.org/10519
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
13 files changed:
src/afs/AIX/osi_vnodeops.c
src/afs/DARWIN/osi_vnodeops.c
src/afs/FBSD/osi_vnodeops.c
src/afs/HPUX/osi_vnodeops.c
src/afs/LINUX/osi_vnodeops.c
src/afs/LINUX24/osi_vnodeops.c
src/afs/NBSD/osi_vnodeops.c
src/afs/OBSD/osi_vnodeops.c
src/afs/SOLARIS/osi_vnodeops.c
src/afs/UKERNEL/afs_usrops.c
src/afs/UKERNEL/sysincludes.h
src/afs/VNOPS/afs_vnop_symlink.c
src/afs/afs_prototypes.h

index 0e4000159eac17c7420574497ba2d4759d56c1ec..b86347e163a11410386a160fd8be1f6fd4952efb 100644 (file)
@@ -1420,7 +1420,7 @@ afs_gn_symlink(struct vnode *vp,
     AFS_STATCNT(afs_gn_symlink);
     VATTR_NULL(&va);
     va.va_mode = 0777;
-    error = afs_symlink(vp, link, &va, target, cred);
+    error = afs_symlink(vp, link, &va, target, NULL, cred);
     afs_Trace4(afs_iclSetp, CM_TRACE_GSYMLINK, ICL_TYPE_POINTER, vp,
               ICL_TYPE_STRING, link, ICL_TYPE_STRING, target, ICL_TYPE_LONG,
               error);
index 1b2156ffe6c02f12348af0ac753669f1369846f2..54c07ad6c6e4d291849fa05ef45795c43b6d738d 100644 (file)
@@ -1655,19 +1655,25 @@ afs_vop_symlink(ap)
                                 * } */ *ap;
 {
     struct vnode *dvp = ap->a_dvp;
+    struct vcache *vpp = NULL;
     int error = 0;
-    /* NFS ignores a_vpp; so do we. */
 
     GETNAME();
     AFS_GLOCK();
-    error =
-       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, vop_cn_cred);
+    error = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, &vpp,
+                       vop_cn_cred);
     AFS_GUNLOCK();
-    DROPNAME();
 #ifndef AFS_DARWIN80_ENV
     FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
     vput(dvp);
 #endif
+    *ap->a_vpp = NULL;
+    if (!error) {
+       error = afs_darwin_finalizevnode(vpp, dvp, ap->a_cnp, 0, 0);
+       if (! error)
+           *ap->a_vpp = AFSTOV(vpp);
+    }
+    DROPNAME();
     return error;
 }
 
index ac16df034b4080bf898ac91e5d46854d68351450..7a521524e573a961743c06d4eda3ecc3e89e5361 100644 (file)
@@ -1365,7 +1365,8 @@ afs_vop_symlink(struct vop_symlink_args *ap)
     newvp = NULL;
 
     error =
-       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
+       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, NULL,
+                   cnp->cn_cred);
     if (error == 0) {
        error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
        if (error == 0) {
index a9114ef980a1f751e9cd3844e8b378113b221fd2..dab15dbfecc2dd950608f3dff3df8b429e270ca6 100644 (file)
@@ -502,7 +502,7 @@ mp_afs_symlink(struct vnode *adp, char *aname, struct vattr *attrs,
     int code;
 
     AFS_GLOCK();
-    code = afs_symlink(adp, aname, attrs, atargetName, acred);
+    code = afs_symlink(adp, aname, attrs, atargetName, NULL, acred);
     AFS_GUNLOCK();
     return (code);
 }
index ada29624ae7e2bfa1ea77cf336e0d4f02ca20d92..b3190baf05383923b2ac4f67c0321214ad436fe8 100644 (file)
@@ -1568,7 +1568,8 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
 
     VATTR_NULL(&vattr);
     AFS_GLOCK();
-    code = afs_symlink(VTOAFS(dip), (char *)name, &vattr, (char *)target, credp);
+    code = afs_symlink(VTOAFS(dip), (char *)name, &vattr, (char *)target, NULL,
+                      credp);
     AFS_GUNLOCK();
     crfree(credp);
     return afs_convert_code(code);
index 5351a7e09debcaa002c669616e967fea4dc373f6..9ac0b1ca362aae896e0cb9083937e43c3c4a7158 100644 (file)
@@ -1429,7 +1429,8 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
 
     VATTR_NULL(&vattr);
     AFS_GLOCK();
-    code = afs_symlink(VTOAFS(dip), (char *)name, &vattr, (char *)target, credp);
+    code = afs_symlink(VTOAFS(dip), (char *)name, &vattr, (char *)target, NULL,
+                      credp);
     AFS_GUNLOCK();
     crfree(credp);
     return afs_convert_code(code);
index 56c42a3272b7c85c3293aec6097098edeed9a309..48e29f09fb2eb9176846cc064c9597f14ed4b7a0 100644 (file)
@@ -852,7 +852,7 @@ afs_nbsd_symlink(void *v)
     GETNAME();
     AFS_GLOCK();
     code =
-       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
+       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, NULL,
                    cnp->cn_cred);
     AFS_GUNLOCK();
     DROPCNP(cnp);
index 9bf045d4a61d7e39b5367148e00e28e1f81e50fa..141c88172cdabf11bd665e155140ca2d3985cd5f 100644 (file)
@@ -847,7 +847,8 @@ afs_obsd_symlink(void *v)
     GETNAME();
     AFS_GLOCK();
     code =
-       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
+       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, NULL,
+                   cnp->cn_cred);
     AFS_GUNLOCK();
     DROPCNP(cnp);
     DROPNAME();
index f810c6db9358f5d73f319e681557d364121342da..ff1e124bc6433f824350886d9a3ca0c828575df4 100644 (file)
@@ -1771,7 +1771,7 @@ gafs_symlink(struct vcache *adp, char *aname, struct vattr *attrs,
     int code;
 
     AFS_GLOCK();
-    code = afs_symlink(adp, aname, attrs, atargetName, acred);
+    code = afs_symlink(adp, aname, attrs, atargetName, NULL, acred);
     AFS_GUNLOCK();
     return (code);
 }
index a4a0fdbaec991e8204adcae5f8d3e4717ed5f7fc..a9825e8ea4d299e1b6c1f9d0fc94615f908a6e20 100644 (file)
@@ -3043,7 +3043,8 @@ uafs_symlink_r(char *target, char *source)
     attrs.va_mode = 0777;
     attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
     attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
-    code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, get_user_struct()->u_cred);
+    code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, NULL,
+                      get_user_struct()->u_cred);
     VN_RELE(dirP);
     if (code != 0) {
        errno = code;
index f5b2d9621a59e68bf6a527794e555c9fd4a96be3..1b5b7f7f5be5533c5700dc67f94837c901a2e734 100644 (file)
@@ -1246,7 +1246,7 @@ struct usr_vnodeops {
     int (*vn_rmdir) (struct vcache *adp, char *, afs_ucred_t *);
     int (*vn_readdir) (struct vcache *avc, struct uio *, afs_ucred_t *);
     int (*vn_symlink) (struct vcache *adp, char *, struct vattr *, char *,
-                      afs_ucred_t *);
+                      struct vcache **vpp, afs_ucred_t *);
     int (*vn_readlink) (struct vcache *avc, struct uio *, afs_ucred_t *);
     int (*vn_fsync) (struct vcache *avc, afs_ucred_t *);
     int (*vn_inactive) (struct vcache *avc, afs_ucred_t *acred);
index faf103e13f477def29a0d795544f566a4090d69f..95f69736dfd5cfcee2f72ceaca0a8c11559e3c56 100644 (file)
@@ -66,7 +66,7 @@ afs_DisconCreateSymlink(struct vcache *avc, char *aname,
 /* don't set CDirty in here because RPC is called synchronously */
 int 
 afs_symlink(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, 
-           char *atargetName, afs_ucred_t *acred)
+           char *atargetName, struct vcache **tvcp, afs_ucred_t *acred)
 {
     afs_uint32 now = 0;
     struct vrequest treq;
@@ -284,7 +284,10 @@ afs_symlink(OSI_VC_DECL(adp), char *aname, struct vattr *attrs,
     }
     ReleaseWriteLock(&tvc->lock);
     ReleaseWriteLock(&afs_xvcache);
-    afs_PutVCache(tvc);
+    if (tvcp)
+       *tvcp = tvc;
+    else
+       afs_PutVCache(tvc);
     code = 0;
   done:
     afs_PutFakeStat(&fakestate);
index 1d6d72f36377062bbcc2103bc8645c0fae782d91..d8c4b89045532649f7776cd3d1e2ce026bc894b8 100644 (file)
@@ -1291,7 +1291,7 @@ extern int afs_UFSHandleLink(struct vcache *avc,
                             struct vrequest *areq);
 extern int afs_symlink(OSI_VC_DECL(adp), char *aname,
                       struct vattr *attrs, char *atargetName,
-                      afs_ucred_t *acred);
+                      struct vcache **tvcp, afs_ucred_t *acred);
 extern int afs_readlink(OSI_VC_DECL(avc), struct uio *auio,
                        afs_ucred_t *acred);