Page MenuHomeFreeBSD

D27875.id81446.diff
No OneTemporary

D27875.id81446.diff

diff --git a/sys/fs/nfs/nfs_var.h.sav b/sys/fs/nfs/nfs_var.h
--- a/sys/fs/nfs/nfs_var.h.sav
+++ b/sys/fs/nfs/nfs_var.h
@@ -753,6 +753,8 @@
struct ucred *, struct thread *);
int nfsvno_listxattr(struct vnode *, uint64_t, struct ucred *, struct thread *,
u_char **, uint32_t *, bool *);
+void nfsm_trimtrailing(struct nfsrv_descript *, struct mbuf *, char *, int,
+ int);
/* nfs_commonkrpc.c */
int newnfs_nmcancelreqs(struct nfsmount *);
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c.sav b/sys/fs/nfsserver/nfs_nfsdport.c
--- a/sys/fs/nfsserver/nfs_nfsdport.c.sav
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -146,8 +146,6 @@
static int nfsrv_dssetacl(struct vnode *, struct acl *, struct ucred *,
NFSPROC_T *);
static int nfsrv_pnfsstatfs(struct statfs *, struct mount *);
-static void nfsm_trimtrailing(struct nfsrv_descript *, struct mbuf *,
- char *, int, int);
int nfs_pnfsio(task_fn_t *, void *);
@@ -6564,7 +6562,7 @@
/*
* Trim trailing data off the mbuf list being built.
*/
-static void
+void
nfsm_trimtrailing(struct nfsrv_descript *nd, struct mbuf *mb, char *bpos,
int bextpg, int bextpgsiz)
{
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c.sav b/sys/fs/nfsserver/nfs_nfsdsocket.c
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c.sav
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -534,11 +534,23 @@
{
int error = 0, lktype;
vnode_t vp;
- mount_t mp = NULL;
+ mount_t mp;
struct nfsrvfh fh;
struct nfsexstuff nes;
+ struct mbuf *md;
+ char *dpos;
/*
+ * Save the current position in the request mbuf list so
+ * that a rollback to this location can be done upon an
+ * ERELOOKUP error return from an RPC function.
+ */
+ md = nd->nd_md;
+ dpos = nd->nd_dpos;
+tryagain:
+ mp = NULL;
+
+ /*
* Get a locked vnode for the first file handle
*/
if (!(nd->nd_flag & ND_NFSV4)) {
@@ -634,6 +646,21 @@
if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0)
vn_finished_write(mp);
+ if (error == 0 && nd->nd_repstat == ERELOOKUP) {
+ /*
+ * Roll back to the beginning of the RPC request
+ * arguments.
+ */
+ nd->nd_md = md;
+ nd->nd_dpos = dpos;
+
+ /* Free the junk RPC reply and redo the RPC. */
+ m_freem(nd->nd_mreq);
+ nd->nd_mreq = nd->nd_mb = NULL;
+ nd->nd_repstat = 0;
+ goto tryagain;
+ }
+
nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
/*now*/ NULL, /*then*/ &start_time);
}
@@ -691,6 +718,9 @@
static u_int64_t compref = 0;
struct bintime start_time;
struct thread *p;
+ struct mbuf *mb, *md;
+ char *bpos, *dpos;
+ int bextpg, bextpgsiz;
p = curthread;
@@ -1045,6 +1075,20 @@
break;
}
}
+
+ /*
+ * Save the current positions in the mbuf lists so
+ * that a rollback to this location can be done upon a
+ * redo due to a ERELOOKUP return for a operation.
+ */
+ mb = nd->nd_mb;
+ bpos = nd->nd_bpos;
+ bextpg = nd->nd_bextpg;
+ bextpgsiz = nd->nd_bextpgsiz;
+ md = nd->nd_md;
+ dpos = nd->nd_dpos;
+tryagain:
+
if (nfsv4_opflag[op].retfh == 1) {
if (!vp) {
nd->nd_repstat = NFSERR_NOFILEHANDLE;
@@ -1152,6 +1196,23 @@
printf("nfsv4 comperr0=%d\n", error);
}
error = 0;
+ }
+
+ if (nd->nd_repstat == ERELOOKUP) {
+ /*
+ * Roll back to the beginning of the operation
+ * arguments.
+ */
+ nd->nd_md = md;
+ nd->nd_dpos = dpos;
+
+ /*
+ * Trim off the bogus reply for this operation
+ * and redo the operation.
+ */
+ nfsm_trimtrailing(nd, mb, bpos, bextpg, bextpgsiz);
+ nd->nd_repstat = 0;
+ goto tryagain;
}
if (statsinprog != 0) {

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 20, 4:16 AM (1 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29997750
Default Alt Text
D27875.id81446.diff (3 KB)

Event Timeline