]> 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, 20 Dec 2013 15:07:19 +0000 (07:07 -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)

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>
(cherry picked from commit 192536d62b085bb14f54ffc958e6303810cca624)

Change-Id: I01b319c43ee74d220cccc6c0defbe1a8cd38b9c4
Reviewed-on: http://gerrit.openafs.org/10605
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
Tested-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 01498fa8b2daeb4483c53b7d86ab105b4dc51c8c..fc8e41b9129680ded92ff33c63554b0f6a072849 100644 (file)
@@ -1368,7 +1368,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 78b98ba5e0289f5aad44a793a4555f3550692f92..3a2a67f6b486a6015f9bcd04bdf1be4603a25297 100644 (file)
@@ -1574,7 +1574,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 6c0589b76c82fd305dc92316b6032fddf92dbdb5..c9af3bbb7a36292616c8fe78a7c7f5a789673e80 100644 (file)
@@ -1447,7 +1447,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 8b0be90fb418c93944fe2413a923d00ed8b87220..746b4660eb0c13b26fb200904875c4917b6ab85f 100644 (file)
@@ -1295,7 +1295,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);