]> 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)
committerDerrick Brashear <shadow@your-file-system.com>
Thu, 21 Nov 2013 22:15:27 +0000 (14:15 -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

Change-Id: I33b2f51cd10f76689eb9868eb05800ab493087c4
Reviewed-on: http://gerrit.openafs.org/10474
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
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 421215a295877666f0d2adf51ab25819c2e55908..d49c96db02b33fcb9efc59c922a7175846830200 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 9797249f05546627797d9197af5218cca8e70fc4..024e2d15be9ae2871dbdee2882115f51427e1877 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 f113596f5b81199fe2addc1f8775d6cc5f8fb9e5..dd644fe84d82f57a08ac9c3c163bd43b51060698 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 2a29625057e168051b9ded2df865789423442453..28841c8d2adbd28ec1a261b14b7d6c27f296e21e 100644 (file)
@@ -1596,7 +1596,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 4e0055946062c041ec9d6ec22f3d45850008123b..cfbcca392ca0a49d8ca692952a6a0db8ff6c8433 100644 (file)
@@ -1431,7 +1431,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 4c172aa87ba0a12db2c3adf7406150caaa3e9bb1..b4899dcb8682236ea3d1c9c448c047fcfa0c5648 100644 (file)
@@ -1076,7 +1076,7 @@ afs_nbsd_symlink(void *v)
     name = cnstrdup(cnp);
     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);
     if (code == 0) {
        code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
index d3b85fd9bd588d3689b5f6b506aa4066b049b9aa..022504e675da55d638ebdeb6216340229a2bc00d 100644 (file)
@@ -845,7 +845,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 9f9915775b0901722e11351844063fc172590b2f..55415fff48def636a283aa197671b360f50577a9 100644 (file)
@@ -1622,7 +1622,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 f6195b9ebd0b3ab40ed492a7888685835c548435..e0ad0bb512b0b0c947d064fed9cd6f1c16fe4b4e 100644 (file)
@@ -3059,7 +3059,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 e4019561f4607f42170c10ee66eeddaa59ce5dfa..38904cc677264a751acc544980c31e80799ff9ea 100644 (file)
@@ -1252,7 +1252,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 13591ce901fbc2e87abd9a16de2ef66ce8365151..dfb9e4c2cf0d20391db7c7076108c51f07bb5775 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 f98aef2ae1cae03ea79f878e53c10951d093c5f8..ae8a3b1227faa81afc844b52ac22053dd2051031 100644 (file)
@@ -1327,7 +1327,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);