summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgt29601 <none@none>2008-04-10 10:53:21 -0700
committergt29601 <none@none>2008-04-10 10:53:21 -0700
commitfd7da6184b3d96d5ce022d41d140bf547f0344cf (patch)
treeba1b29d2930e31bde40795b291609961fe0fec7a
parent7730e2acd408d8c08610e39353747d95fe743bce (diff)
downloadillumos-joyent-fd7da6184b3d96d5ce022d41d140bf547f0344cf.tar.gz
6614416 panic in spec_fsync() when creating a device file via NFS
-rw-r--r--usr/src/uts/common/fs/nfs/nfs3_srv.c8
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_srv.c11
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_srv.c10
3 files changed, 25 insertions, 4 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs3_srv.c b/usr/src/uts/common/fs/nfs/nfs3_srv.c
index 21c9679e73..e0669e8a67 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_srv.c
@@ -2166,6 +2166,7 @@ rfs3_mknod(MKNOD3args *args, MKNOD3res *resp, struct exportinfo *exi,
{
int error;
vnode_t *vp;
+ vnode_t *realvp;
vnode_t *dvp;
struct vattr *vap;
struct vattr va;
@@ -2335,8 +2336,13 @@ rfs3_mknod(MKNOD3args *args, MKNOD3res *resp, struct exportinfo *exi,
/*
* Force modified metadata out to stable storage.
+ *
+ * if a underlying vp exists, pass it to VOP_FSYNC
*/
- (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
+ if (VOP_REALVP(vp, &realvp, NULL) == 0)
+ (void) VOP_FSYNC(realvp, FNODSYNC, cr, NULL);
+ else
+ (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
VN_RELE(vp);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv.c b/usr/src/uts/common/fs/nfs/nfs4_srv.c
index 2591611b62..b61669122b 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c
@@ -1505,6 +1505,7 @@ rfs4_op_create(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
cred_t *cr = cs->cr;
vnode_t *dvp = cs->vp;
vnode_t *vp = NULL;
+ vnode_t *realvp;
char *nm, *lnm;
uint_t len, llen;
int syncval = 0;
@@ -1804,7 +1805,15 @@ rfs4_op_create(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
else
resp->cinfo.atomic = FALSE;
- (void) VOP_FSYNC(vp, syncval, cr, NULL);
+ /*
+ * Force modified metadata out to stable storage.
+ *
+ * if a underlying vp exists, pass it to VOP_FSYNC
+ */
+ if (VOP_REALVP(vp, &realvp, NULL) == 0)
+ (void) VOP_FSYNC(realvp, syncval, cr, NULL);
+ else
+ (void) VOP_FSYNC(vp, syncval, cr, NULL);
if (resp->status != NFS4_OK) {
VN_RELE(vp);
diff --git a/usr/src/uts/common/fs/nfs/nfs_srv.c b/usr/src/uts/common/fs/nfs/nfs_srv.c
index 45f57c2255..e2a97f813d 100644
--- a/usr/src/uts/common/fs/nfs/nfs_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs_srv.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1731,6 +1731,7 @@ rfs_create(struct nfscreatargs *args, struct nfsdiropres *dr,
int in_crit = 0;
struct vattr va;
vnode_t *vp;
+ vnode_t *realvp;
vnode_t *dvp;
char *name = args->ca_da.da_name;
vnode_t *tvp = NULL;
@@ -1958,8 +1959,13 @@ rfs_create(struct nfscreatargs *args, struct nfsdiropres *dr,
}
/*
* Force modified metadata out to stable storage.
+ *
+ * if a underlying vp exists, pass it to VOP_FSYNC
*/
- (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
+ if (VOP_REALVP(vp, &realvp, NULL) == 0)
+ (void) VOP_FSYNC(realvp, FNODSYNC, cr, NULL);
+ else
+ (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
VN_RELE(vp);
}