summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nuttx/fs/nfs/nfs.h148
-rw-r--r--nuttx/fs/nfs/nfs_mount.h2
-rw-r--r--nuttx/fs/nfs/nfs_node.h1
-rw-r--r--nuttx/fs/nfs/nfs_socket.c57
-rw-r--r--nuttx/fs/nfs/nfs_socket.h8
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c623
-rw-r--r--nuttx/fs/nfs/rpc.h3
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c386
8 files changed, 710 insertions, 518 deletions
diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h
index 88276123c3..d9e61e57c0 100644
--- a/nuttx/fs/nfs/nfs.h
+++ b/nuttx/fs/nfs/nfs.h
@@ -73,9 +73,9 @@
/* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
* broken NFS/ethernet drivers that won't work with anything bigger (Linux..)
*/
-
-#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
-#define NFS_READDIRBLKSIZ 512 /* Size of read dir blocks. XXX */
+
+#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
+#define NFS_READDIRBLKSIZ 512 /* Size of read dir blocks. XXX */
/* Oddballs */
@@ -102,17 +102,17 @@
* buffer cache code to say "Invalidate the block after it is written back".
*/
-#define B_INVAFTERWRITE B_INVAL
+#define B_INVAFTERWRITE B_INVAL
/* Flags for nfssvc() system call. */
-#define NFSSVC_BIOD 0x002
-#define NFSSVC_NFSD 0x004
-#define NFSSVC_ADDSOCK 0x008
-#define NFSSVC_AUTHIN 0x010
-#define NFSSVC_GOTAUTH 0x040
+#define NFSSVC_BIOD 0x002
+#define NFSSVC_NFSD 0x004
+#define NFSSVC_ADDSOCK 0x008
+#define NFSSVC_AUTHIN 0x010
+#define NFSSVC_GOTAUTH 0x040
#define NFSSVC_AUTHINFAIL 0x080
-#define NFSSVC_MNTD 0x100
+#define NFSSVC_MNTD 0x100
/* fs.nfs sysctl(3) identifiers */
@@ -129,8 +129,7 @@
#define NFSINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
sigmask(SIGHUP)|sigmask(SIGQUIT))
-/*
- * Socket errors ignored for connectionless sockets??
+/* Socket errors ignored for connectionless sockets??
* For now, ignore them all
*/
@@ -316,7 +315,7 @@ struct nfssvc_sock
int ns_solock; /* lock for connected socket */
int ns_cc; /* actual chars queued */
int ns_reclen; /* length of first queued record */
- uint32_t ns_sref; /* # of refs to this struct */
+ uint32_t ns_sref; /* # of refs to this struct */
};
/* One of these structures is allocated for each nfsd. */
@@ -324,19 +323,127 @@ struct nfssvc_sock
struct nfsd
{
//TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */
- int nfsd_flag; /* NFSD_ flags */
- struct nfssvc_sock *nfsd_slp; /* Current socket */
- struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
+ int nfsd_flag; /* NFSD_ flags */
+ struct nfssvc_sock *nfsd_slp; /* Current socket */
+ struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
};
/* This structure is used by the server for describing each request. */
struct nfsrv_descript
{
- unsigned int nd_procnum; /* RPC # */
- int nd_flag; /* nd_flag */
- int nd_repstat; /* Reply status */
- uint32_t nd_retxid; /* Reply xid */
+ unsigned int nd_procnum; /* RPC # */
+ int nd_flag; /* nd_flag */
+ int nd_repstat; /* Reply status */
+ uint32_t nd_retxid; /* Reply xid */
+};
+
+/* NFS procedures args */
+
+struct wcc_attr
+{
+ nfsuint64 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+}
+
+struct wcc_data
+{
+ wcc_attr before;
+ nfs_fattr after;
+};
+
+struct diropargs3
+{
+ nfsfh_t dir;
+ const char name;
+};
+
+struct CREATE3args
+{
+ diropargs3 where;
+ nfsv3_sattr how;
+};
+
+struct CREATE3resok
+{
+ const char handle;
+ nfs_fattr attributes;
+ wcc_data dir_wcc;
+};
+
+struct READ3args
+{
+ nfstype file;
+ uint64_t offset;
+ uint32_t count;
+};
+
+struct READ3resok
+{
+ nfs_fattr file_attributes;
+ uint32_t count;
+ bool eof;
+ const char data;
+};
+
+enum stable_how
+{
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2
+};
+
+struct WRITE3args
+{
+ nfstype file;
+ uint64_t offset;
+ uint32_t count;
+ stable_how stable;
+ const char data;
+};
+
+struct WRITE3resok
+{
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ unsigned char verf;
+};
+
+struct REMOVE3args
+{
+ diropargs3 object;
+};
+
+struct REMOVE3resok
+{
+ wcc_data dir_wcc;
+};
+
+struct RENAME3args
+{
+ diropargs3 from;
+ diropargs3 to;
+};
+
+struct RENAME3resok
+{
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+struct MKDIR3args
+{
+ diropargs3 where;
+ nfsv3_sattr attributes;
+};
+
+struct MKDIR3resok
+{
+ const char handle;
+ nfs_fattr obj_attributes;
+ wcc_data dir_wcc;
};
/****************************************************************************
@@ -352,6 +459,7 @@ extern struct pool nfs_node_pool;
extern TAILQ_HEAD(nfsdhead, nfsd) nfsd_head;
extern int nfsd_head_flag;
*/
+
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
diff --git a/nuttx/fs/nfs/nfs_mount.h b/nuttx/fs/nfs/nfs_mount.h
index 1cc96963d2..5c0e5a5fd6 100644
--- a/nuttx/fs/nfs/nfs_mount.h
+++ b/nuttx/fs/nfs/nfs_mount.h
@@ -98,7 +98,7 @@ struct nfsmount
int nm_acregmin; /* Reg file attr cache min lifetime */
int nm_acregmax; /* Reg file attr cache max lifetime */
unsigned char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */
- char nm_mntonname[90]; /* directory on which mounted */
+//char nm_mntonname[90]; /* directory on which mounted */
uint8_t *nm_buffer; /* This is an allocated buffer to hold one sector*/
};
diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h
index 5a04765724..dd7fe12a89 100644
--- a/nuttx/fs/nfs/nfs_node.h
+++ b/nuttx/fs/nfs/nfs_node.h
@@ -115,7 +115,6 @@ struct nfsnode
bool n_open; /* true: The file is (still) open */
uint64_t n_size; /* Current size of file */
struct nfs_fattr n_fattr; /* nfs file attribute cache */
- struct nfsv3_sattr n_sattr;
nfstype nfsv3_type; /* File type */
time_t n_attrstamp; /* Attr. cache timestamp */
struct timespec n_mtime; /* Prev modify time. */
diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c
index c1953369c7..663cf8e260 100644
--- a/nuttx/fs/nfs/nfs_socket.c
+++ b/nuttx/fs/nfs/nfs_socket.c
@@ -61,11 +61,13 @@
/* Flag translations */
-#define nfsmnt_to_rpcclnt(nf, rf, name) do { \
- if (nf & NFSMNT_##name) { \
- rf |= RPCCLNT_##name; \
- } \
-} while(0)
+#define nfsmnt_to_rpcclnt(nf, rf, name) do \
+ { \
+ if (nf & NFSMNT_##name) \
+ { \
+ rf |= RPCCLNT_##name; \
+ } \
+ } while(0)
/****************************************************************************
* Private Variables
@@ -101,15 +103,18 @@ int nfsx_connect(struct nfsmount *nmp)
int error = 0;
if (nmp == NULL)
- return EFAULT;
+ {
+ return EFAULT;
+ }
rpc = &nmp->nm_rpcclnt;
rpc->rc_prog = &nfs3_program;
- printf("nfsxconnect!\n");
+ nvdbg("nfsxconnect!\n");
/* translate nfsmnt flags -> rpcclnt flags */
+
rpc->rc_flag = 0;
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, SOFT);
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, INT);
@@ -132,11 +137,14 @@ int nfsx_connect(struct nfsmount *nmp)
rpc->rc_retry = nmp->nm_retry;
/* XXX v2,3 need to use this */
+
rpc->rc_proctlen = 0;
rpc->rc_proct = NULL;
if (error)
- return error;
+ {
+ return error;
+ }
return rpcclnt_connect(rpc);
}
@@ -155,7 +163,7 @@ void nfsx_safedisconnect(struct nfsmount *nmp)
}
#endif
-int nfsx_request_xx(struct nfsmount *nm, int procnum, void *data)
+int nfsx_request_xx(struct nfsmount *nm, int procnum,void *datain, void *dataout)
{
int error;
struct nfsmount *nmp;
@@ -170,10 +178,12 @@ tryagain:
memset(reply, 0, sizeof(struct rpc_reply));
- if ((error = rpcclnt_request(clnt, procnum, reply)) != 0)
- goto out;
+ if ((error = rpcclnt_request(clnt, procnum, reply, datain)) != 0)
+ {
+ goto out;
+ }
- data = reply->stat.where;
+ dataout = reply->stat.where;
if (reply->rpc_verfi.authtype != 0)
{
@@ -190,22 +200,27 @@ tryagain:
goto tryagain;
}
- /*
- ** If the File Handle was stale, invalidate the
- ** lookup cache, just in case.
- **/
+ /* If the File Handle was stale, invalidate the
+ * lookup cache, just in case.
+ */
+
if (error == ESTALE)
- printf("%s: ESTALE on mount from server \n",
- nmp->nm_rpcclnt.rc_prog->prog_name);
+ {
+ ndbg("%s: ESTALE on mount from server \n",
+ nmp->nm_rpcclnt.rc_prog->prog_name);
+ }
else
- printf("%s: unknown error %d from server \n",
+ {
+ ndbg("%s: unknown error %d from server \n",
nmp->nm_rpcclnt.rc_prog->prog_name, error);
+ }
+
goto out;
}
- return (0);
+ return 0;
out:
- return (error);
+ return error;
}
/* terminate any outstanding RPCs. */
diff --git a/nuttx/fs/nfs/nfs_socket.h b/nuttx/fs/nfs/nfs_socket.h
index f1be14aa2c..e668e85fb8 100644
--- a/nuttx/fs/nfs/nfs_socket.h
+++ b/nuttx/fs/nfs/nfs_socket.h
@@ -53,17 +53,17 @@ int nfsx_sigintr(struct nfsmount *, struct nfsreq *, cthread_t *);
void nfsx_safedisconnect(struct nfsmount *);
#define nfs_safedisconnect nfsx_safedisconnect
#endif
-int nfsx_request_xx(struct nfsmount *, int, void*);
+int nfsx_request_xx(struct nfsmount *, int, void*, void*);
int nfsx_nmcancelreqs(struct nfsmount *);
#define nfs_connect nfs_connect_nfsx
#define nfs_disconnect nfs_disconnect_nfsx
#define nfs_nmcancelreqs nfsx_nmcancelreqs
-#define nfsx_request(nmp, m, s) \
- nfsx_request_xx(nmp, m, s)
+#define nfsx_request(nmp, m, i, o) \
+ nfsx_request_xx(nmp, m, i, o)
#ifdef CONFIG_NFS_TCPIP
-#define nfs_sigintr nfs_sigintr_nfsx
+# define nfs_sigintr nfs_sigintr_nfsx
#endif
#endif /* __FS_NFS_NFS_SOCKET_H */
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index 345b80bb75..4d14feac9e 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -48,9 +48,12 @@
#include <sys/socketvar.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
-
#include <sys/statfs>
+
#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
#include <nuttx/fs/dirent.h>
#include <nuttx/fs/fs.h>
@@ -140,21 +143,17 @@ const struct mountpt_operations nfs_ops = {
*/
int
-nfs_open(FAR struct file *filp, FAR const char *relpath,
+nfs_open(FAR struct file *filp, FAR const char *relpath, // done but check variable how
int oflags, mode_t mode)
{
- // struct vop_create_args *ap = v;
struct inode *in;
- struct nfsv3_sattr *vap;
- // struct componentname *cnp = ap->a_cnp;
+ struct nfs_fattr *vap;
struct nfsv3_sattr *sp;
struct nfsmount *nmp;
- // struct nfsm_info info;
- //uint32_t *tl;
- //int32_t t1;
struct nfsnode *np;
+ struct CREATE3args *create;
+ struct CREATE3resok *resok;
void *replydata;
- int info_v3;
int error = 0;
/* Sanity checks */
@@ -167,8 +166,7 @@ nfs_open(FAR struct file *filp, FAR const char *relpath,
in = filep->f_inode;
nmp = (struct nfsmount*)in->i_private;
- info_v3 = (nmp->nm_flag & NFSMNT_NFSV3);
- vap = nmp->nm_head->n_sattr;
+ np = (struct nfsnode*)filep->f_priv;
DEBUGASSERT(nmp != NULL);
@@ -183,24 +181,28 @@ nfs_open(FAR struct file *filp, FAR const char *relpath,
if (oflags == O_CREAT)
{
- /* Sanity checks */
+ /* Sanity checks */
DEBUGASSERT(filep->f_priv == NULL);
- again:
+again:
nfsstats.rpccnt[NFSPROC_CREATE]++;
-
+ vap = nmp->nm_head->n_fattr;
sp->sa_modetrue = nfs_true;
- sp->sa_mode = txdr_unsigned(vap->sa_mode);
+ sp->sa_mode = txdr_unsigned(vap->fa_mode);
sp->sa_uid = nfs_xdrneg1;
sp->sa_gid = nfs_xdrneg1;
sp->sa_size = nfs_xdrneg1;
sp->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
sp->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
- txdr_nfsv3time(&vap->sa_atime, &sp->sa_atime);
- txdr_nfsv3time(&vap->sa_mtime, &sp->sa_mtime);
+ txdr_nfsv3time(&vap->fa_atime, &sp->sa_atime);
+ txdr_nfsv3time(&vap->fa_mtime, &sp->sa_mtime);
- error = nfs_request(in, NFSPROC_CREATE, replydata);
+ create->how = sp;
+ create->where->dir= nmp->nm_fh;
+ create->where->name = relpath;
+
+ error = nfs_request(in, NFSPROC_CREATE, (void *) create, replydata);
if (!error)
{
/* Create an instance of the file private data to describe the opened
@@ -219,9 +221,13 @@ nfs_open(FAR struct file *filp, FAR const char *relpath,
* non-zero elements)
*/
+ resok = (struct CREATE3resok *) replydata;
np->n_open = true;
- np->n_size = sp->sa_size;
- np->n_sattr = sp;
+ np->nfsv3_type = NFREG;
+ np->n_size = (struct uint64_t *)resok->attributes->nfsv3fa_size;
+ np->n_fattr = resok->attributes;
+ np->n_mtime = (struct timespec*) resok->attributes->nfsv3fa_mtime
+ np->n_ctime = (struct time_t*) resok->attributes->nfsv3fa_ctime
/* Attach the private date to the struct file instance */
@@ -244,6 +250,7 @@ nfs_open(FAR struct file *filp, FAR const char *relpath,
goto again;
}
}
+
np->n_flag |= NMODIFIED;
}
else
@@ -254,10 +261,12 @@ nfs_open(FAR struct file *filp, FAR const char *relpath,
return EACCES;
}
- NFS_INVALIDATE_ATTRCACHE(np);
- if (np->nfsv3_type == NFDIR)
+ if (np->n_flag & NMODIFIED)
{
- np->n_direofoffset = 0;
+ if (np->nfsv3_type == NFDIR)
+ {
+ np->n_direofoffset = 0;
+ }
}
}
@@ -307,21 +316,21 @@ int nfs_close(FAR struct file *filep) //done
* Name: nfs_read
****************************************************************************/
-int nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
+static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) //done
{
struct nfsmount *nmp;
struct nfsnode *np;
- unsigned int bytesread;
unsigned int readsize;
- int biosize, diff;
+ int bytesleft;
+ uint64_t offset;
void *datareply;
- void baddr;
+ struct READ3args *read;
+ struct READ3resok *resok;
+ uint8_t *userbuffer = (uint8_t*)buffer;
int info_v3;
int error = 0;
int len;
- int retlen;
- int tsiz;
- int eof;
+ bool eof;
fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos);
@@ -331,11 +340,10 @@ int nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
/* Recover our private data from the struct file instance */
- np = filep->f_priv;
- nmp = filep->f_inode->i_private;
- info_v3 = (nmp->nm_flag & NFSMNT_NFSV3);
- eof = 0;
- tsiz = (int) buflen;
+ np = (struct nfsnode*) filep->f_priv;
+ nmp = (struct nfsmount*) filep->f_inode->i_private;
+ eof = false;
+ offset = 0;
DEBUGASSERT(nmp != NULL);
@@ -360,9 +368,10 @@ int nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
(void)nfs_fsinfo(nmp);
}
- /* Get the number of bytes left in the file */
+ /* Get the number of bytes left in the file */
bytesleft = np->n_size - filep->f_pos;
+ readsize = 0;
/* Truncate read count so that it does not exceed the number
* of bytes left in the file.
@@ -373,78 +382,83 @@ int nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
buflen = bytesleft;
}
- readsize = 0;
- while (tsiz > 0)
- {
+ len = nmp->nm_rsize;
+ if (len < buflen)
+ {
+ error = EFBIG
+ goto errout_with_semaphore;
+
+ }
+
nfsstats.rpccnt[NFSPROC_READ]++;
- len = nmp->nm_rsize;
+again:
+ read->file = np->nfsv3_type;
+ read->count = buflen;
+ read->offset = offset;
- error = nfs_request(vp, NFSPROC_READ, datareply);
+ error = nfs_request(nmp, NFSPROC_READ, read, datareply);
if (error)
{
goto errout_with_semaphore;
}
- if (info_v3)
+ resok = (struct READ3resok *) datareply;
+ eof = resok->eof;
+ if (eof == true)
{
- eof = fxdr_unsigned(int, datareply);
- }
+ readsize = resok->count;
+ np->n_fattr = resok->file_attributes;
+ memcpy(userbuffer, resok->data, (struct size_t)readsize);
- retlen = fxdr_unsigned(int, nmp->nm_rsize);
- tsiz -= retlen;
- if (info_v3)
- {
- if (eof || retlen == 0)
- {
- tsiz = 0;
- }
}
- else if (retlen < len)
+ else
{
- tsiz = 0;
+ goto again;
}
- }
- nfs_semgive(nmp);
+nfs_semgive(nmp);
return readsize;
errout_with_semaphore:
nfs_semgive(nmp);
- return (error);
+ return error;
}
+/****************************************************************************
+ * Name: nfs_write
+ ****************************************************************************/
-/* nfs write call */
-
-int
-nfs_writerpc(FAR struct file *filep, const char *buffer, size_t buflen)
+static ssize_t
+nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) // done
{
- struct nfsm_info info;
+ /*struct nfsm_info info;
uint32_t *tl;
int32_t t1, backup;
- caddr_t cp2;
+ caddr_t cp2;*/
+ struct inode *inode;
struct nfsmount *nmp;
struct nfsnode *np;
+ unsigned int writesize;
void *datareply;
+ struct WRITE3args *write;
+ struct WRITE3resok resok;
+ uint8_t *userbuffer = (uint8_t*)buffer;
int error = 0;
+ uint64_t offset;
int len;
- int tsiz;
- int wccflag = NFSV3_WCCRATTR;
- int rlen;
- int commit;
+ struct stable_how commit;
int committed = NFSV3WRITE_FILESYNC;
- info.nmi_v3 = NFS_ISV3(vp);
-
- /* Sanity checks */
+ /* Sanity checks */
DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
/* Recover our private data from the struct file instance */
- np = filep->f_priv;
- inode = filep->f_inode;
- nmp = inode->i_private;
+ np = (struct nfsnode *)filep->f_priv;
+ inode = filep->f_inode;
+ nmp = (struct nfsmount *)inode->i_private;
+ offset = 0;
DEBUGASSERT(nmp != NULL);
@@ -465,84 +479,68 @@ nfs_writerpc(FAR struct file *filep, const char *buffer, size_t buflen)
goto errout_with_semaphore;
}
- //*must_commit = 0;
- tsiz = (int) buflen;
-
- while (tsiz > 0)
+ len = nmp->nm_wsize;
+ if (len < buflen)
{
- nfsstats.rpccnt[NFSPROC_WRITE]++;
- len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
-
- error = nfs_request(vp, NFSPROC_WRITE, datareply);
+ error = -EFBIG
+ goto errout_with_semaphore;
+ }
+ writesize = 0;
- if (error)
- {
- goto errout_with_semaphore;
- }
+ nfsstats.rpccnt[NFSPROC_WRITE]++;
+ write->file = np->nfsv3_type;
+ write->offset = offset;
+ write->count = buflen;
+ write->stable = committed;
+ memcpy(write->data, userbuffer, buflen);
- if (info.nmi_v3)
- {
- wccflag = NFSV3_WCCCHK;
- nfsm_dissect(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF);
- rlen = fxdr_unsigned(int, *tl++);
- if (rlen == 0)
- {
- error = NFSERR_IO;
- goto errout_with_semaphore;
- }
- else if (rlen < len)
- {
- backup = len - rlen;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base - backup;
- uiop->uio_iov->iov_len += backup;
- uiop->uio_offset -= backup;
- uiop->uio_resid += backup;
- len = rlen;
- }
- commit = fxdr_unsigned(int, *tl++);
+ error = nfs_request(nmp, NFSPROC_WRITE, write, datareply);
+ if (error)
+ {
+ goto errout_with_semaphore;
+ }
- /* Return the lowest committment level
- * obtained by any of the RPCs.
- */
+ resok = (struct WRITE3resok *)datareply;
+ writesize = resok->count;
+ if (writesize == 0)
+ {
+ error = -NFSERR_IO;
+ goto errout_with_semaphore;
+ }
- if (committed == NFSV3WRITE_FILESYNC)
- {
- committed = commit;
- }
- else if (committed == NFSV3WRITE_DATASYNC &&
- commit == NFSV3WRITE_UNSTABLE)
- {
- committed = commit;
- }
+ commit = resok->committed;
+ np->n_fattr = resok->file_wcc->after;
- if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
- {
- bcopy((void) datareply, (void) nmp->nm_verf, NFSX_V3WRITEVERF);
- nmp->nm_flag |= NFSMNT_HASWRITEVERF;
- }
- else if (bcmp((void) datareply, (void) nmp->nm_verf, NFSX_V3WRITEVERF))
- {
- //*must_commit = 1;
- bcopy((void) datareply, (void) nmp->nm_verf, NFSX_V3WRITEVERF);
- }
- }
- else
- {
- nfsm_loadattr(vp, NULL);
- }
+ /* Return the lowest committment level obtained by any of the RPCs. */
- if (wccflag)
- {
- VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
- }
+ if (committed == NFSV3WRITE_FILESYNC)
+ {
+ committed = commit;
+ }
+ else if (committed == NFSV3WRITE_DATASYNC &&
+ commit == NFSV3WRITE_UNSTABLE)
+ {
+ committed = commit;
+ }
- tsiz -= len;
+ if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
+ {
+ bcopy((void) resok->verf, (void) nmp->nm_verf, NFSX_V3WRITEVERF);
+ nmp->nm_flag |= NFSMNT_HASWRITEVERF;
+ }
+ else if (strncmp((char) resok->verf, (char) nmp->nm_verf, NFSX_V3WRITEVERF))
+ {
+ bcopy((void) resok->verf, (void) nmp->nm_verf, NFSX_V3WRITEVERF);
}
+ np->n_mtime = np->n_fattr.nfsv3fa_mtime;
+
+ nfs_semgive(nmp);
+ return writesize;
+
errout_with_semaphore:
nfs_semgive(nmp);
- return (error);
+ return error;
}
/* nfs file remove call
@@ -555,147 +553,134 @@ errout_with_semaphore:
* else
* do the remove rpc
*/
+/****************************************************************************
+ * Name: nfs_remove
+ *
+ * Description: Remove a file
+ *
+ ****************************************************************************/
-int nfs_remove(void *v)
+int nfs_remove(struct inode *mountpt, const char *relpath) //done
{
- struct vop_remove_args *ap = v;
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- struct nfsnode *np = VTONFS(vp);
+ struct nsfmount *nmp;
+ struct nfsnode *np;
+ void *datreply;
+ struct REMOVE3args *remove;
+ struct REMOVE3resok resok;
int error = 0;
- struct vattr vattr;
- if (np->n_type == NDIR)
- {
- error = EPERM;
- goto errout_with_semaphore;
- }
+ /* Sanity checks */
- /* Do the rpc */
+ DEBUGASSERT(mountpt && mountpt->i_private);
- error = nfs_removerpc(dvp, cnp->cn_nameptr,
- cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc);
+ /* Get the mountpoint private data from the inode structure */
- /* Kludge City: If the first reply to the remove rpc is lost..
- * the reply to the retransmitted request will be ENOENT
- * since the file was in fact removed
- * Therefore, we cheat and return success.
- */
+ nmp = (struct nfsmount *)mountpt->i_private;
+ np = nmp->nm_head;
- if (error == ENOENT)
- {
- error = 0;
- }
+ /* Check if the mount is still healthy */
- NFS_INVALIDATE_ATTRCACHE(np);
+ nfs_semtake(nmp);
+ error = fat_checkmount(nmp);
+ if (error == 0)
+ {
+ /* If the file is open, the correct behavior is to remove the file
+ * name, but to keep the file cluster chain in place until the last
+ * open reference to the file is closed.
+ */
- /* VN_KNOTE(vp, NOTE_DELETE);
- VN_KNOTE(dvp, NOTE_WRITE);*/
+ /* Remove the file */
-errout_with_semaphore:
- nfs_semgive(nmp);
- return (error);
-}
+ if (np->n_type != NFREG)
+ {
+ error = EPERM;
+ goto errout_with_semaphore;
+ }
-/* Nfs remove rpc, called from nfs_remove() and nfs_removeit(). */
+ /* Do the rpc */
-int
-nfs_removerpc(struct vnode *dvp, char *name, int namelen, struct ucred *cred,
- struct proc *proc)
-{
- struct nfsm_info info;
- uint32_t *tl;
- int32_t t1;
- caddr_t cp2;
- int error = 0, wccflag = NFSV3_WCCRATTR;
+ nfsstats.rpccnt[NFSPROC_REMOVE]++;
+ remove->dir = nmp->nm_fh;
+ remove->name = relpath;
- info.nmi_v3 = NFS_ISV3(dvp);
+ error = nfs_request(nmp, NFSPROC_REMOVE, remove, datareply);
- nfsstats.rpccnt[NFSPROC_REMOVE]++;
- nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
+ /* Kludge City: If the first reply to the remove rpc is lost..
+ * the reply to the retransmitted request will be ENOENT
+ * since the file was in fact removed
+ * Therefore, we cheat and return success.
+ */
- error = nfs_request(dvp, NFSPROC_REMOVE, &info);
- if (info.nmi_v3)
- nfsm_wcc_data(dvp, wccflag);
+ if (error == ENOENT)
+ {
+ error = 0;
+ }
-nfsmout:
- VTONFS(dvp)->n_flag |= NMODIFIED;
- if (!wccflag)
- NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
- return error;
-}
+ if (error)
+ {
+ goto errout_with_semaphore;
+ }
-/* nfs file rename call */
+ resok = (struct REMOVE3resok *)datareply;
+ np->n_fattr = resok->dir_wcc->after;
+ np->n_flag |= NMODIFIED;
+ }
+ NFS_INVALIDATE_ATTRCACHE(np);
-int nfs_rename(void *v)
-{
- struct vop_rename_args *ap = v;
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tdvp = ap->a_tdvp;
- struct componentname *tcnp = ap->a_tcnp;
- struct componentname *fcnp = ap->a_fcnp;
- int error;
+errout_with_semaphore:
+ nfs_semgive(nmp);
+ return error;
+}
-#ifdef DIAGNOSTIC
- if ((tcnp->cn_flags & HASBUF) == 0 || (fcnp->cn_flags & HASBUF) == 0)
- panic("nfs_rename: no name");
-#endif
+/****************************************************************************
+ * Name: nfs_rename
+ *
+ * Description: Rename a file or directory
+ *
+ ****************************************************************************/
- /* Check for cross-device rename */
+int nfs_rename(struct inode *mountpt, const char *oldrelpath,
+ const char *newrelpath)
+{
+ struct nsfmount *nmp;
+ struct nfsnode *np;
+ void *datreply;
+ struct RENAME3args *rename;
+ struct RENAME3resok resok;
+ int error = 0;
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount)))
- {
- error = EXDEV;
- goto out;
- }
+ /* Sanity checks */
- /* If the tvp exists and is in use, sillyrename it before doing the
- * rename of the new file over it.
- */
+ DEBUGASSERT(mountpt && mountpt->i_private);
- if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename &&
- tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp))
- {
- VN_KNOTE(tvp, NOTE_DELETE);
- vrele(tvp);
- tvp = NULL;
- }
+ /* Get the mountpoint private data from the inode structure */
- error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
- tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
- tcnp->cn_proc);
+ nmp = (struct nfsmount *)mountpt->i_private;
+ np = nmp->nm_head;
- VN_KNOTE(fdvp, NOTE_WRITE);
- VN_KNOTE(tdvp, NOTE_WRITE);
+ /* Check if the mount is still healthy */
- if (fvp->v_type == VDIR)
+ nfs_semtake(nmp);
+ error = nfs_checkmount(nmp);
+ if (error != 0)
{
- if (tvp != NULL && tvp->v_type == VDIR)
- cache_purge(tdvp);
- cache_purge(fdvp);
+ goto errout_with_semaphore;
}
-out:
- if (tdvp == tvp)
- {
- vrele(tdvp);
- }
- else
+ if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR)
{
- vput(tdvp);
+ fdbg("open eacces typ=%d\n", np->nfsv3_type);
+ error= -EACCES;
+ goto errout_with_semaphore;
}
- if (tvp)
- {
- vput(tvp);
- }
+ nfsstats.rpccnt[NFSPROC_RENAME]++;
+ rename->from->dir = nmp->nm_fh;
+ rename->from->name = oldrelpath;
+ rename->to->dir = nmp->nm_fh;
+ rename->to->name = oldrelpath;
- vrele(fdvp);
- vrele(fvp);
+ error = nfs_request(fdvp, NFSPROC_RENAME, rename, datareply);
/* Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. */
@@ -704,100 +689,50 @@ out:
error = 0;
}
- return error;
-}
-
-/* nfs file rename rpc called from nfs_remove() above */
-
-int
-nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
- struct sillyrename *sp)
-{
- return nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen,
- sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred,
- curproc);
-}
-
-/* Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). */
-
-int
-nfs_renamerpc(struct vnode *fdvp, char *fnameptr, int fnamelen,
- struct vnode *tdvp, char *tnameptr, int tnamelen)
-{
- struct nfsm_info info;
- uint32_t *tl;
- int32_t t1;
- caddr_t cp2;
- int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
-
- info.nmi_v3 = NFS_ISV3(fdvp);
-
- nfsstats.rpccnt[NFSPROC_RENAME]++;
- info.nmi_mb = info.nmi_mreq = nfsm_reqhead((NFSX_FH(info.nmi_v3) +
- NFSX_UNSIGNED) * 2 +
- nfsm_rndup(fnamelen) +
- nfsm_rndup(tnamelen));
- nfsm_fhtom(&info, fdvp, info.nmi_v3);
- nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
- nfsm_fhtom(&info, tdvp, info.nmi_v3);
- nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
-
- error = nfs_request(fdvp, NFSPROC_RENAME, &info);
- if (info.nmi_v3)
- {
- nfsm_wcc_data(fdvp, fwccflag);
- nfsm_wcc_data(tdvp, twccflag);
- }
-
-nfsmout:
- VTONFS(fdvp)->n_flag |= NMODIFIED;
- VTONFS(tdvp)->n_flag |= NMODIFIED;
-
- if (!fwccflag)
+ if (error)
{
- NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp));
+ goto errout_with_semaphore;
}
- if (!twccflag)
- {
- NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp));
- }
+ resok = (struct RENAME3resok *) datareply;
+ np->n_fattr = resok->todir_wcc->after
+ np->n_flag |= NMODIFIED;
+ NFS_INVALIDATE_ATTRCACHE(np);
- return error;
+errout_with_semaphore:
+ nfs_semgive(nmp);
+ return error;
}
-/* nfs make dir call */
+/****************************************************************************
+ * Name: nfs_mkdir
+ *
+ * Description: Create a directory
+ *
+ ****************************************************************************/
int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
{
- //struct vnode *dvp = ap->a_dvp;
struct nfsv3_sattr *vap;
+ struct nfsv3_sattr *sp;
struct nfsmount *nmp;
struct nfsnode *np;
- struct componentname *cnp = ap->a_cnp;
- struct nfsv3_sattr *sp;
- int info_v3;
+ struct MKDIR3args *mkdir;
+ struct MKDIR3resok resok;
void *datareply;
- //struct nfsm_info info;
- //uint32_t *tl;
- //int32_t t1;
int len;
struct nfsnode *npL;
- struct file *newfilep ;
- //caddr_t cp2;
- int error = 0, wccflag = NFSV3_WCCRATTR;
- int gotvp = 0;
+ int error = 0;
- /* Sanity checks */
+ /* Sanity checks */
DEBUGASSERT(mountpt && mountpt->i_private);
/* Get the mountpoint private data from the inode structure */
- nmp = mountpt->i_private;
+ nmp = (struct nfsmount*) mountpt->i_private;
np = nmp->nm_head;
vap = np->n_fattr;
- info_v3 = (nmp->nm_flag & NFSMNT_NFSV3);
/* Check if the mount is still healthy */
@@ -809,6 +744,8 @@ int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
}
nfsstats.rpccnt[NFSPROC_MKDIR]++;
+ mkdir->dir = nmp->nm_fh;
+ mkdir->name = relpath;
sp->sa_modetrue = nfs_true;
sp->sa_mode = txdr_unsigned(vap->sa_mode);
@@ -821,37 +758,18 @@ int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
txdr_nfsv3time(&vap->sa_atime, &sp->sa_atime);
txdr_nfsv3time(&vap->sa_mtime, &sp->sa_mtime);
- error = nfs_request(nmp, NFSPROC_MKDIR, datareply);
-
-
-nfsmout:
- nmp->n_flag |= NMODIFIED;
- if (!wccflag)
- {
- NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
- }
+ mkdir->attributes = sp;
+ error = nfs_request(nmp, NFSPROC_MKDIR, mkdir, datareply);
if (error)
{
- if (newvp)
- {
- vrele(newvp);
- }
- }
- else
- {
- VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
- if (cnp->cn_flags & MAKEENTRY)
- {
- nfs_cache_enter(dvp, newvp, cnp);
- }
-
- *ap->a_vpp = newvp;
+ goto errout_with_semaphore;
}
- return error;
+ nmp->n_flag |= NMODIFIED;
+ NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
- errout_with_semaphore:
+errout_with_semaphore:
nfs_semgive(nmp);
return error;
}
@@ -1203,9 +1121,9 @@ int nfs_print(struct file *filep)
//struct vnode *vp = ap->a_vp;
struct nfsnode *np = VTONFS(filep);
- printf("tag VT_NFS, fileid %ld fsid 0x%lx",
- np->n_fattr.nfsv3fa_fileid, np->n_fattr.nfsv3fa_fsid);
- printf("\n");
+ nvdbg("tag VT_NFS, fileid %ld fsid 0x%lx",
+ np->n_fattr.nfsv3fa_fileid, np->n_fattr.nfsv3fa_fsid);
+ nvdbg("\n");
return 0;
}
*/
@@ -1488,7 +1406,7 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) //done
if (nmp->nm_sotype == SOCK_DGRAM)
while (nfs_connect(nmp))
{
- printf("nfs_args: retrying connect\n");
+ nvdbg("nfs_args: retrying connect\n");
}
}
}
@@ -1504,12 +1422,11 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) //done
*
****************************************************************************/
-int nfs_mount(struct inode *blkdriver, const char *path, void *data, void **handle) //done
+int nfs_mount(struct inode *blkdriver, void *data, void **handle) //done
{
int error;
struct nfs_args args;
struct sockaddr *nam;
- char pth[90];
nfsfh_t nfh[NFSX_V3FHMAX];
bcopy(data, &args, sizeof(args.version));
@@ -1556,8 +1473,6 @@ int nfs_mount(struct inode *blkdriver, const char *path, void *data, void **hand
}
bcopy(args.fh, nfh, args.fhsize);
- memset(&pth[90], 0, sizeof(*pth[90]));
- bcopy(path, pth, 90 - 1);
bcopy(args.addr, nam, sizeof(args.addr));
args.fh = nfh;
error = mountnfs(&args, blkdriver, nam);
@@ -1630,7 +1545,7 @@ int mountnfs(struct nfs_args *argp, struct inode *blkdriver,
memmove(nmp->nm_fh, argp->fh, argp->fhsize);
//strncpy(&mp->mnt_stat.f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
//memmove(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
- bcopy(pth, nmp->nm_mntonname, 90);
+ // bcopy(pth, nmp->nm_mntonname, 90);
//memmove(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp));
nmp->nm_nam = nam;
nfs_decode_args(nmp, argp);
@@ -1777,9 +1692,9 @@ int nfs_sync(struct file *filep) //falta
/* Check if the has been modified in any way */
if ((np->n_flag & NMODIFIED) != 0)
- {
- error = VOP_FSYNC(vp, cred, waitfor, p); ///////////////////////////////
- }
+ {
+ error = VOP_FSYNC(vp, cred, waitfor, p); ///////////////////////////////
+ }
return allerror;
diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h
index 6e1d9d0565..39b2040c21 100644
--- a/nuttx/fs/nfs/rpc.h
+++ b/nuttx/fs/nfs/rpc.h
@@ -144,6 +144,7 @@ struct rpc_call
uint32_t rp_prog; /* program */
uint32_t rp_vers; /* version */
uint32_t rp_proc; /* procedure */
+ void *data;
struct rpc_auth_info rpc_auth;
struct auth_unix rpc_unix;
struct rpc_auth_info rpc_verf;
@@ -248,7 +249,7 @@ int rpcclnt_connect(struct rpcclnt *);
int rpcclnt_reconnect(struct rpctask *);
void rpcclnt_disconnect(struct rpcclnt *);
void rpcclnt_safedisconnect(struct rpcclnt *);
-int rpcclnt_request(struct rpcclnt *, int, struct rpc_reply *);
+int rpcclnt_request(struct rpcclnt *, int, struct rpc_reply *, void *);
int rpcclnt_cancelreqs(struct rpcclnt *);
#endif /* _RPCCLNT_H_ */
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index 0463e74da8..7f54c6965e 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -41,10 +41,10 @@
*
* Copyright (c) 1989, 1991, 1993, 1995 The Regents of the University of
* California. All rights reserved.
- *
+ *
* This code is derived from software contributed to Berkeley by Rick Macklem at
* The University of Guelph.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -58,7 +58,7 @@
* name of the University nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -194,7 +194,7 @@ struct rpc_reply *replymsg;
/* Queue head for rpctask's */
static dq_queue_t *rpctask_q;
-//struct callout_handle rpcclnt_timer_handle;
+//struct callout_handle rpcclnt_timer_handle;
/****************************************************************************
* Private Function Prototypes
@@ -217,7 +217,7 @@ static int rpcclnt_sigintr(struct rpcclnt *, struct rpctask *, cthread_t *);
static void rpcclnt_softterm(struct rpctask *task);
static uint32_t rpcclnt_proct(struct rpcclnt *, uint32_t);
-static int rpcclnt_buildheader(struct rpcclnt *, int, int, struct rpc_call *);
+static int rpcclnt_buildheader(struct rpcclnt *, int, int, void *, struct rpc_call *);
/****************************************************************************
* Private Functions
@@ -246,27 +246,40 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, struct rpc_call *call,
{
RPC_RETURN(EINTR);
}
+
if ((so = rep->r_rpcclnt->rc_so) == NULL)
{
rep->r_flags |= TASK_MUSTRESEND;
RPC_RETURN(0);
}
+
rep->r_flags &= ~TASK_MUSTRESEND;
soflags = rep->r_rpcclnt->rc_soflags;
}
else
- soflags = so->s_flags;
+ {
+ soflags = so->s_flags;
+ }
+
#ifdef CONFIG_NFS_TCPIP
if ((soflags & PR_CONNREQUIRED))
- sendnam = NULL;
+ {
+ sendnam = NULL;
+ {
else
#endif
- sendnam = nam;
+ {
+ sendnam = nam;
+ }
if (so->s_type == SOCK_SEQPACKET)
- flags = MSG_EOR;
+ {
+ flags = MSG_EOR;
+ }
else
- flags = 0;
+ {
+ flags = 0;
+ }
error =
psock_sendto(so, call, sizeof(*call), flags, sendnam, sizeof(*sendnam));
@@ -275,25 +288,32 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, struct rpc_call *call,
{
if (rep != NULL)
{
- printf("rpc send error %d for service %s\n", error,
- rep->r_rpcclnt->rc_prog->prog_name);
- /*
- * Deal with errors for the client side.
- */
+ ndbg("rpc send error %d for service %s\n", error,
+ rep->r_rpcclnt->rc_prog->prog_name);
+
+ /* Deal with errors for the client side. */
+
if (rep->r_flags & TASK_SOFTTERM)
- error = EINTR;
+ {
+ error = EINTR;
+ }
else
- rep->r_flags |= TASK_MUSTRESEND;
+ {
+ rep->r_flags |= TASK_MUSTRESEND;
+ }
}
else
- printf("rpc service send error %d\n", error);
+ {
+ ndbg("rpc service send error %d\n", error);
+ }
+
+ /* Handle any recoverable (soft) socket errors here. */
- /*
- * Handle any recoverable (soft) socket errors here.
- */
if (error != EINTR && error != ERESTART &&
error != EWOULDBLOCK && error != EPIPE)
- error = 0;
+ {
+ error = 0;
+ }
}
RPC_RETURN(error);
@@ -331,8 +351,12 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
{
error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep);
if (error != 0)
- return (error);
+ {
+ return error;
+ }
+
tryagain:
+
/* Check for fatal errors and resending request.
*
* Ugh: If a reconnect attempt just happened, rc_so would
@@ -343,8 +367,9 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (rep->r_flags & TASK_SOFTTERM)
{
rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- return (EINTR);
+ return EINTR;
}
+
so = rep->r_rpcclnt->rc_so;
if (so == NULL)
{
@@ -352,8 +377,9 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (error)
{
rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- return (error);
+ return error;
}
+
goto tryagain;
}
while (rep->r_flags & TASK_MUSTRESEND)
@@ -366,8 +392,9 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
(error = rpcclnt_reconnect(rep)) != 0)
{
rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- return (error);
+ return error;
}
+
goto tryagain;
}
}
@@ -382,14 +409,16 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
&rcvflg, rep->r_rpcclnt->rc_name,
sizeof(*rep->r_rpcclnt->rc_name));
if (error == EWOULDBLOCK && rep && (rep->r_flags & TASK_SOFTTERM))
- RPC_RETURN(EINTR);
+ {
+ RPC_RETURN(EINTR);
+ }
}
while (error == EWOULDBLOCK);
if (error == 0)
{
- printf("short receive from rpc server %s\n",
- rep->r_rpcclnt->rc_prog->prog_name);
+ ndbg("short receive from rpc server %s\n",
+ rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE;
}
@@ -402,9 +431,9 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (len > RPC_MAXPACKET)
{
- printf("%s (%d) from rpc server %s\n",
- "impossible packet length",
- len, rep->r_rpcclnt->rc_prog->prog_name);
+ ndbg("%s (%d) from rpc server %s\n",
+ "impossible packet length",
+ len, rep->r_rpcclnt->rc_prog->prog_name);
error = EFBIG;
goto errout;
}
@@ -419,14 +448,15 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (error == 0)
{
- printf("short receive from rpc server %s\n",
- rep->r_rpcclnt->rc_prog->prog_name);
+ ndbg("short receive from rpc server %s\n",
+ rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE;
}
if (error != 0)
- goto errout;
-
+ {
+ goto errout;
+ }
}
else
{
@@ -447,36 +477,51 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
{
if (rep->r_flags & TASK_SOFTTERM)
{
- return (EINTR);
+ return EINTR;
}
}
}
while (error == EWOULDBLOCK || (!error));
if ((rcvflg & MSG_EOR) == 0)
- printf("Egad!!\n");
+ {
+ ndbg("Egad!!\n");
+ }
+
if (error == 0)
- error = EPIPE;
+ {
+ error = EPIPE;
+ }
}
errout:
if (error != 0 && error != EINTR && error != ERESTART)
{
if (error != EPIPE)
- printf("receive error %d from rpc server %s\n",
+ {
+ ndbg("receive error %d from rpc server %s\n",
error, rep->r_rpcclnt->rc_prog->prog_name);
+ }
+
error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep);
if (error == 0)
- error = rpcclnt_reconnect(rep);
+ {
+ error = rpcclnt_reconnect(rep);
+ }
+
if (error == 0)
- goto tryagain;
+ {
+ goto tryagain;
+ }
}
}
else
{
#endif
if ((so = rep->r_rpcclnt->rc_so) == NULL)
- RPC_RETURN(EACCES);
+ {
+ RPC_RETURN(EACCES);
+ }
do
{
@@ -529,9 +574,11 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
#ifdef CONFIG_NFS_TCPIP
error = rpcclnt_rcvlock(myrep);
if (error)
- return (error);
+ {
+ return error;
+ }
#endif
- /*
+ /*
* Get the next Rpc reply off the socket
*/
error = rpcclnt_receive(myrep, nam, reply, call);
@@ -549,8 +596,11 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
if (RPCIGNORE_SOERROR(rpc->rc_soflags, error))
{
if (myrep->r_flags & TASK_GETONEREP)
- RPC_RETURN(0);
- dbg("ingoring routing error on connectionless protocol.");
+ {
+ RPC_RETURN(0);
+ }
+
+ ndbg("ingoring routing error on connectionless protocol.");
continue;
}
RPC_RETURN(error);
@@ -563,7 +613,10 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
{
rpcstats.rpcinvalid++;
if (myrep->r_flags & TASK_GETONEREP)
- RPC_RETURN(0);
+ {
+ RPC_RETURN(0);
+ }
+
continue;
}
@@ -586,7 +639,9 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
(RPC_CWNDSCALE * RPC_CWNDSCALE +
(rpc->rc_cwnd >> 1)) / rpc->rc_cwnd;
if (rpc->rc_cwnd > RPC_MAXCWND)
- rpc->rc_cwnd = RPC_MAXCWND;
+ {
+ rpc->rc_cwnd = RPC_MAXCWND;
+ }
}
rep->r_flags &= ~TASK_SENT;
@@ -610,10 +665,14 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
t1 -= (RPC_SRTT(rpc, rep) >> 3);
RPC_SRTT(rpc, rep) += t1;
if (t1 < 0)
- t1 = -t1;
+ {
+ t1 = -t1;
+ }
+
t1 -= (RPC_SDRTT(rpc, rep) >> 2);
RPC_SDRTT(rpc, rep) += t1;
}
+
rpc->rc_timeouts = 0;
break;
}
@@ -632,8 +691,11 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
{
RPC_RETURN(0);
}
+
if (myrep->r_flags & TASK_GETONEREP)
- RPC_RETURN(0);
+ {
+ RPC_RETURN(0);
+ }
}
}
@@ -644,22 +706,32 @@ rpcclnt_sigintr( struct rpcclnt *rpc, struct rpctask *task, cthread_t *td)
struct proc *p;
sigset_t tmpset;
- if (rpc == NULL)
- return EFAULT;
+ if (rpc == NULL)
+ {
+ return EFAULT;
+ }
- if (ISSET(rpc->rc_flag, RPCCLNT_REDIRECT)) /* Should signal? */
- return (0);
+ if (ISSET(rpc->rc_flag, RPCCLNT_REDIRECT))
+ {
+ return 0;
+ }
/* XXX deal with forced unmounts */
if (task && ISSET(task->r_flags, TASK_SOFTTERM))
- RPC_RETURN(EINTR);
+ {
+ RPC_RETURN(EINTR);
+ }
if (!ISSET(rpc->rc_flag, RPCCLNT_INT))
- RPC_RETURN(0);
+ {
+ RPC_RETURN(0);
+ }
if (td == NULL)
- return (0);
+ {
+ return 0;
+ }
p = cthread_proc(td);
@@ -669,11 +741,13 @@ rpcclnt_sigintr( struct rpcclnt *rpc, struct rpctask *task, cthread_t *td)
mtx_lock(&p->p_sigacts->ps_mtx);
SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
mtx_unlock(&p->p_sigacts->ps_mtx);
+
if (SIGNOTEMPTY(p->p_siglist) && RPCCLNTINT_SIGMASK(tmpset))
{
PROC_UNLOCK(p);
RPC_RETURN(EINTR);
}
+
PROC_UNLOCK(p);
RPC_RETURN(0);
}
@@ -696,7 +770,10 @@ static int rpcclnt_sndlock(int *flagp, struct rpctask *task)
while (*flagp & RPCCLNT_SNDLOCK)
{
if (rpcclnt_sigintr(task->r_rpcclnt, task, p))
- return (EINTR);
+ {
+ return EINTR;
+ }
+
*flagp |= RPCCLNT_WANTSND;
if (slpflag == PCATCH)
{
@@ -706,7 +783,7 @@ static int rpcclnt_sndlock(int *flagp, struct rpctask *task)
}
*flagp |= RPCCLNT_SNDLOCK;
- return (0);
+ return 0;
}
/* Unlock the stream socket for others. */
@@ -731,14 +808,21 @@ static int rpcclnt_rcvlock(struct rpctask *task)
int slpflag, slptimeo = 0;
if (*flagp & RPCCLNT_INT)
- slpflag = PCATCH;
+ {
+ slpflag = PCATCH;
+ }
else
- slpflag = 0;
+ {
+ slpflag = 0;
+ }
while (*flagp & RPCCLNT_RCVLOCK)
{
if (rpcclnt_sigintr(task->r_rpcclnt, task, task->r_td))
- return (EINTR);
+ {
+ return EINTR;
+ }
+
*flagp |= RPCCLNT_WANTRCV;
tsleep((caddr_t) flagp, slpflag | (PZERO - 1), "rpcrcvlk", slptimeo);
if (slpflag == PCATCH)
@@ -749,7 +833,7 @@ static int rpcclnt_rcvlock(struct rpctask *task)
}
*flagp |= RPCCLNT_RCVLOCK;
- return (0);
+ return 0;
}
/* Unlock the stream socket for others. */
@@ -774,9 +858,11 @@ static uint32_t rpcclnt_proct(struct rpcclnt *rpc, uint32_t procid)
{
if (rpc->rc_proctlen != 0 && rpc->rc_proct != NULL &&
procid < rpc->rc_proctlen)
- return (rpc->rc_proct[procid]);
+ {
+ return rpc->rc_proct[procid];
+ }
- return (0);
+ return 0;
}
static void rpcclnt_softterm(struct rpctask *task)
@@ -797,7 +883,10 @@ void rpcclnt_init(void)
{
rpcclnt_ticks = (CLOCKS_PER_SEC * RPC_TICKINTVL + 500) / 1000;
if (rpcclnt_ticks < 1)
- rpcclnt_ticks = 1;
+ {
+ rpcclnt_ticks = 1;
+ }
+
rpcstats.rpcretries = 0;
rpcstats.rpcrequests = 0;
rpcstats.rpctimeouts = 0;
@@ -822,7 +911,7 @@ void rpcclnt_init(void)
rpcclnt_timer(NULL, callmgs);
- printf("rpc initialed");
+ nvdbg("rpc initialed");
return;
}
@@ -830,9 +919,8 @@ void rpcclnt_init(void)
void
rpcclnt_uninit(void)
{
- printf("uninit");
- untimeout(rpcclnt_timer, (void *)NULL, rpcclnt_timer_handle);
-
+ nvdbg("uninit");
+ untimeout(rpcclnt_timer, (void *)NULL, rpcclnt_timer_handle);
}
*/
@@ -849,7 +937,8 @@ int rpcclnt_connect(struct rpcclnt *rpc)
struct timeval *tv = NULL;
uint16_t tport;
- /* create the socket */
+ /* Create the socket */
+
rpc->rc_so = NULL;
saddr = rpc->rc_name;
rpc->rc_sotype = SOCK_DGRAM;
@@ -859,7 +948,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
if (error != 0)
{
- printf("error %d in psock_socket()", error);
+ ndbg("error %d in psock_socket()", error);
RPC_RETURN(error);
}
@@ -885,7 +974,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
if (error)
{
- printf("bind failed\n");
+ ndbg("bind failed\n");
goto bad;
}
@@ -962,7 +1051,9 @@ int rpcclnt_reconnect(struct rpctask *rep)
while ((error = rpcclnt_connect(rpc)) != 0)
{
if (error == EINTR || error == ERESTART)
- return (EINTR);
+ {
+ return EINTR;
+ }
}
/* Loop through outstanding request list and fix up all
@@ -973,9 +1064,11 @@ int rpcclnt_reconnect(struct rpctask *rep)
rp = (struct rpctask *)rp->r_chain.blink)
{
if (rp->r_rpcclnt == rpc)
- rp->r_flags |= TASK_MUSTRESEND;
+ {
+ rp->r_flags |= TASK_MUSTRESEND;
+ }
}
- return (0);
+ return 0;
}
void rpcclnt_disconnect(struct rpcclnt *rpc)
@@ -1010,16 +1103,16 @@ void rpcclnt_safedisconnect(struct rpcclnt *rpc)
* nfs_receive() to get reply - fills in reply (which should be initialized
* prior to calling), which is valid when 0 is returned and is NEVER freed in
* this function
- *
+ *
* always frees the request header, but NEVER frees 'mrest'
- *
+ *
*
* note that reply->result_* are invalid unless reply->type ==
* RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_*
* are invalid unless reply->type == RPC_MSGACCEPTED
*/
-int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
+int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, void *datain)
{
struct rpc_call *call = NULL;
struct rpc_reply *replysvr = NULL;
@@ -1033,25 +1126,34 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
task->r_rpcclnt = rpc;
task->r_procnum = procnum;
- error = rpcclnt_buildheader(rpc, procnum, xid, call);
+ error = rpcclnt_buildheader(rpc, procnum, xid, datain, call);
if (error)
{
- printf("building call header error");
+ ndbg("building call header error");
goto rpcmout;
}
task->r_xid = fxdr_unsigned(uint32_t, xid);
if (rpc->rc_flag & RPCCLNT_SOFT)
- task->r_retry = rpc->rc_retry;
+ {
+ task->r_retry = rpc->rc_retry;
+ }
else
- task->r_retry = RPC_MAXREXMIT + 1; /* past clip limit */
+ {
+ task->r_retry = RPC_MAXREXMIT + 1; /* past clip limit */
+ }
+
task->r_rtt = task->r_rexmit = 0;
if (rpcclnt_proct(rpc, procnum) > 0)
- task->r_flags = TASK_TIMING;
+ {
+ task->r_flags = TASK_TIMING;
+ }
else
- task->r_flags = 0;
+ {
+ task->r_flags = 0;
+ }
/* Do the client side RPC. */
@@ -1072,10 +1174,11 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
(rpc->rc_flag & RPCCLNT_DUMBTIMR) ||
rpc->rc_sent < rpc->rc_cwnd))
{
-
#ifdef CONFIG_NFS_TCPIP
if (rpc->rc_soflags & PR_CONNREQUIRED)
- error = rpcclnt_sndlock(&rpc->rc_flag, task);
+ {
+ error = rpcclnt_sndlock(&rpc->rc_flag, task);
+ }
#endif
if (error == 0)
@@ -1084,7 +1187,9 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
#ifdef CONFIG_NFS_TCPIP
if (rpc->rc_soflags & PR_CONNREQUIRED)
- rpcclnt_sndunlock(&rpc->rc_flag);
+ {
+ rpcclnt_sndunlock(&rpc->rc_flag);
+ }
#endif
}
if (error == 0 && (task->r_flags & TASK_MUSTRESEND) == 0)
@@ -1101,7 +1206,9 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
/* Wait for the reply from our send. */
if (error == 0 || error == EPIPE)
- error = rpcclnt_reply(task, call, replysvr);
+ {
+ error = rpcclnt_reply(task, call, replysvr);
+ }
/* RPC done, unlink the request. */
@@ -1116,7 +1223,9 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
}
if (error != 0)
- goto rpcmout;
+ {
+ goto rpcmout;
+ }
/* Break down the rpc header and check if ok */
@@ -1131,14 +1240,16 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
fxdr_unsigned(uint32_t, replysvr->stat.mismatch_info.low);
reply->stat.mismatch_info.high =
fxdr_unsigned(uint32_t, replysvr->stat.mismatch_info.high);
- printf("RPC_MSGDENIED: RPC_MISMATCH error");
+ ndbg("RPC_MSGDENIED: RPC_MISMATCH error");
error = EOPNOTSUPP;
break;
+
case RPC_AUTHERR:
reply->stat.autherr = fxdr_unsigned(uint32_t, replysvr->stat.autherr);
- printf("RPC_MSGDENIED: RPC_AUTHERR error");
+ ndbg("RPC_MSGDENIED: RPC_AUTHERR error");
error = EACCES;
break;
+
default:
error = EOPNOTSUPP;
break;
@@ -1160,7 +1271,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
if (reply->stat.status == RPC_SUCCESS)
{
- printf("RPC_SUCCESS");
+ nvdbg("RPC_SUCCESS");
reply->stat.where = replysvr->stat.where;
}
else if (reply->stat.status == RPC_PROGMISMATCH)
@@ -1169,7 +1280,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply)
fxdr_unsigned(uint32_t, replysvr->stat.mismatch_info.low);
reply->stat.mismatch_info.high =
fxdr_unsigned(uint32_t, replysvr->stat.mismatch_info.high);
- printf("RPC_MSGACCEPTED: RPC_PROGMISMATCH error");
+ ndbg("RPC_MSGACCEPTED: RPC_PROGMISMATCH error");
error = EOPNOTSUPP; /* XXXMARIUS */
}
else if (reply->stat.status > 5)
@@ -1199,20 +1310,36 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
{
rpc = rep->r_rpcclnt;
if (rep->r_flags & TASK_SOFTTERM)
- continue;
+ {
+ continue;
+ }
+
if (rep->r_rtt >= 0)
{
rep->r_rtt++;
if (rpc->rc_flag & RPCCLNT_DUMBTIMR)
- timeo = rpc->rc_timeo;
+ {
+ timeo = rpc->rc_timeo;
+ }
else
- timeo = RPC_RTO(rpc, rpcclnt_proct(rep->r_rpcclnt, rep->r_procnum));
+ {
+ timeo = RPC_RTO(rpc, rpcclnt_proct(rep->r_rpcclnt, rep->r_procnum));
+ }
+
if (rpc->rc_timeouts > 0)
- timeo *= rpcclnt_backoff[rpc->rc_timeouts - 1];
+ {
+ timeo *= rpcclnt_backoff[rpc->rc_timeouts - 1];
+ }
+
if (rep->r_rtt <= timeo)
- continue;
+ {
+ continue;
+ }
+
if (rpc->rc_timeouts < 8)
- rpc->rc_timeouts++;
+ {
+ rpc->rc_timeouts++;
+ }
}
/* Check for server not responding */
@@ -1220,23 +1347,30 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
if ((rep->r_flags & TASK_TPRINTFMSG) == 0 &&
rep->r_rexmit > rpc->rc_deadthresh)
{
- printf("Server is not responding");
+ ndbg("Server is not responding");
rep->r_flags |= TASK_TPRINTFMSG;
}
+
if (rep->r_rexmit >= rep->r_retry)
{ /* too many */
rpcstats.rpctimeouts++;
rep->r_flags |= TASK_SOFTTERM;
continue;
}
+
if (rpc->rc_sotype != SOCK_DGRAM)
{
if (++rep->r_rexmit > RPC_MAXREXMIT)
- rep->r_rexmit = RPC_MAXREXMIT;
+ {
+ rep->r_rexmit = RPC_MAXREXMIT;
+ }
continue;
}
+
if ((so = rpc->rc_so) == NULL)
- continue;
+ {
+ continue;
+ }
/* If there is enough space and the window allows.. Resend it
* Set r_rtt to -1 in case we fail to send it now.
@@ -1248,11 +1382,15 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
{
if ((rpc->rc_flag & RPCCLNT_NOCONN) == 0)
- error = psock_sendto(so, call, sizeof(*call), 0, NULL, 0);
+ {
+ error = psock_sendto(so, call, sizeof(*call), 0, NULL, 0);
+ }
else
- error =
- psock_sendto(so, call, sizeof(*call), 0, rpc->rc_name,
- sizeof(*rpc->rc_name));
+ {
+ error =
+ psock_sendto(so, call, sizeof(*call), 0, rpc->rc_name,
+ sizeof(*rpc->rc_name));
+ }
if (!error)
{
@@ -1265,10 +1403,16 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
{
rep->r_flags &= ~TASK_TIMING;
if (++rep->r_rexmit > RPC_MAXREXMIT)
- rep->r_rexmit = RPC_MAXREXMIT;
+ {
+ rep->r_rexmit = RPC_MAXREXMIT;
+ }
+
rpc->rc_cwnd >>= 1;
if (rpc->rc_cwnd < RPC_CWNDSCALE)
- rpc->rc_cwnd = RPC_CWNDSCALE;
+ {
+ rpc->rc_cwnd = RPC_CWNDSCALE;
+ }
+
rpcstats.rpcretries++;
}
else
@@ -1276,6 +1420,7 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
rep->r_flags |= TASK_SENT;
rpc->rc_sent += RPC_CWNDSCALE;
}
+
rep->r_rtt = 0;
}
}
@@ -1287,7 +1432,7 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
/* Build the RPC header and fill in the authorization info. */
int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
- int xidp, struct rpc_call *call)
+ int xidp, void *datain, struct rpc_call *call)
{
struct timeval *tv = NULL;
srand(time(NULL));
@@ -1317,6 +1462,7 @@ int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
call->rp_prog = txdr_unsigned(rc->rc_prog->prog_id);
call->rp_vers = txdr_unsigned(rc->rc_prog->prog_version);
call->rp_proc = txdr_unsigned(procid);
+ call->data = datain;
/* rpc_auth part (auth_unix as root) */
@@ -1337,7 +1483,7 @@ int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
call->rpc_verf.authtype = 0;
call->rpc_verf.authlen = 0;
- return (0);
+ return 0;
}
int rpcclnt_cancelreqs(struct rpcclnt *rpc)
@@ -1349,7 +1495,10 @@ int rpcclnt_cancelreqs(struct rpcclnt *rpc)
task = (struct rpctask *)task->r_chain.flink)
{
if (rpc != task->r_rpcclnt || (task->r_flags & TASK_SOFTTERM))
- continue;
+ {
+ continue;
+ }
+
rpcclnt_softterm(task);
}
@@ -1359,12 +1508,17 @@ int rpcclnt_cancelreqs(struct rpcclnt *rpc)
task = (struct rpctask *)task->r_chain.flink)
{
if (rpc == task->r_rpcclnt)
- break;
+ {
+ break;
+ }
}
+
if (task == NULL)
- return (0);
+ {
+ return 0;
+ }
}
- return (EBUSY);
+ return EBUSY;
}
#endif