diff options
| author | shepler <none@none> | 2005-07-11 17:12:14 -0700 |
|---|---|---|
| committer | shepler <none@none> | 2005-07-11 17:12:14 -0700 |
| commit | 418d27f31a05724c1efac6769b51b1a2505536f1 (patch) | |
| tree | f48c66e20618f9078f30bdbebc41ce2420ac72ce | |
| parent | 3d1c78fb548b54befec40c16e54a4cd1e41b20bd (diff) | |
| download | illumos-joyent-418d27f31a05724c1efac6769b51b1a2505536f1.tar.gz | |
6262563 NFSv4 server panic in fop_getattr due to bad call by rfs4_op_remove
6263280 ::svc_pool does not work
6265027 rpc destroys a CV with waiters
| -rw-r--r-- | usr/src/uts/common/fs/nfs/nfs4_srv.c | 60 | ||||
| -rw-r--r-- | usr/src/uts/common/rpc/clnt_cots.c | 2 |
2 files changed, 42 insertions, 20 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv.c b/usr/src/uts/common/fs/nfs/nfs4_srv.c index f4df9039da..f941e5340e 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_srv.c +++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c @@ -3709,20 +3709,30 @@ rfs4_op_remove(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req, if ((error = VOP_REMOVE(dvp, nm, cs->cr)) == 0 && fp != NULL) { struct vattr va; + vnode_t *tvp; - /* - * This is va_seq safe because we are not - * manipulating dvp. - */ - va.va_mask = AT_NLINK; - if (!VOP_GETATTR(fp->vp, &va, 0, cs->cr) && - va.va_nlink == 0) { - /* The file is gone and so should the state */ - if (in_crit) { - nbl_end_crit(vp); - in_crit = 0; + rfs4_dbe_lock(fp->dbe); + tvp = fp->vp; + if (tvp) + VN_HOLD(tvp); + rfs4_dbe_unlock(fp->dbe); + + if (tvp) { + /* + * This is va_seq safe because we are not + * manipulating dvp. + */ + va.va_mask = AT_NLINK; + if (!VOP_GETATTR(tvp, &va, 0, cs->cr) && + va.va_nlink == 0) { + /* Remove state on file remove */ + if (in_crit) { + nbl_end_crit(vp); + in_crit = 0; + } + rfs4_close_all_state(fp); } - rfs4_close_all_state(fp); + VN_RELE(tvp); } } } @@ -3968,16 +3978,26 @@ rfs4_op_rename(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req, if ((error = VOP_RENAME(odvp, onm, ndvp, nnm, cs->cr)) == 0 && fp != NULL) { struct vattr va; + vnode_t *tvp; - va.va_mask = AT_NLINK; - if (!VOP_GETATTR(fp->vp, &va, 0, cs->cr) && - va.va_nlink == 0) { - /* The file is gone and so should the state */ - if (in_crit_targ) { - nbl_end_crit(targvp); - in_crit_targ = 0; + rfs4_dbe_lock(fp->dbe); + tvp = fp->vp; + if (tvp) + VN_HOLD(tvp); + rfs4_dbe_unlock(fp->dbe); + + if (tvp) { + va.va_mask = AT_NLINK; + if (!VOP_GETATTR(tvp, &va, 0, cs->cr) && + va.va_nlink == 0) { + /* The file is gone and so should the state */ + if (in_crit_targ) { + nbl_end_crit(targvp); + in_crit_targ = 0; + } + rfs4_close_all_state(fp); } - rfs4_close_all_state(fp); + VN_RELE(tvp); } } diff --git a/usr/src/uts/common/rpc/clnt_cots.c b/usr/src/uts/common/rpc/clnt_cots.c index ad5cd82ac4..8537fa9cf5 100644 --- a/usr/src/uts/common/rpc/clnt_cots.c +++ b/usr/src/uts/common/rpc/clnt_cots.c @@ -1716,7 +1716,9 @@ use_new_conn: * for needs disconnect. */ if (cm_entry->x_needdis) { + CONN_HOLD(cm_entry); connmgr_dis_and_wait(cm_entry); + connmgr_release(cm_entry); /* * connmgr_lock could have been * dropped for the disconnect |
