aboutsummaryrefslogtreecommitdiff
path: root/nuttx/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/fs/nfs')
-rw-r--r--nuttx/fs/nfs/Make.defs9
-rw-r--r--nuttx/fs/nfs/nfs_node.h3
-rw-r--r--nuttx/fs/nfs/nfs_util.c9
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c163
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c28
5 files changed, 149 insertions, 63 deletions
diff --git a/nuttx/fs/nfs/Make.defs b/nuttx/fs/nfs/Make.defs
index fc4682f85..ec2177fcf 100644
--- a/nuttx/fs/nfs/Make.defs
+++ b/nuttx/fs/nfs/Make.defs
@@ -1,7 +1,7 @@
############################################################################
# Make.defs
#
-# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,10 @@ CSRCS +=
ASRCS +=
CSRCS += rpc_clnt.c nfs_util.c nfs_vfsops.c
-# Argument for dependency checking
+# Include NFS build support
+
+DEPPATH += --dep-path nfs
+VPATH += :nfs
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)nfs}
-NFSDEPPATH = --dep-path nfs
endif
diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h
index 4ae9e162c..408bd1993 100644
--- a/nuttx/fs/nfs/nfs_node.h
+++ b/nuttx/fs/nfs/nfs_node.h
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_node.h
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
* Gregory Nutt <gnutt@nuttx.org>
@@ -70,6 +70,7 @@
struct nfsnode
{
struct nfsnode *n_next; /* Retained in a singly linked list. */
+ uint8_t n_crefs; /* Reference count (for nfs_dup) */
uint8_t n_type; /* File type */
uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_flags; /* Node flags */
diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c
index 73fda72a7..e7d28b3d7 100644
--- a/nuttx/fs/nfs/nfs_util.c
+++ b/nuttx/fs/nfs/nfs_util.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_util.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -213,7 +213,6 @@ int nfs_request(struct nfsmount *nmp, int procnum,
{
struct rpcclnt *clnt = nmp->nm_rpcclnt;
struct nfs_reply_header replyh;
- int trylater_delay;
int error;
tryagain:
@@ -250,12 +249,6 @@ tryagain:
if (error == EAGAIN)
{
error = 0;
- trylater_delay *= NFS_TIMEOUTMUL;
- if (trylater_delay > NFS_MAXTIMEO)
- {
- trylater_delay = NFS_MAXTIMEO;
- }
-
goto tryagain;
}
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index 3cd5a47dc..2ff4ff9d3 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_vfsops.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
* Gregory Nutt <gnutt@nuttx.org>
@@ -133,6 +133,7 @@ static int nfs_close(FAR struct file *filep);
static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen);
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
size_t buflen);
+static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp);
static int nfs_opendir(struct inode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
@@ -166,7 +167,9 @@ const struct mountpt_operations nfs_operations =
nfs_write, /* write */
NULL, /* seek */
NULL, /* ioctl */
+
NULL, /* sync */
+ nfs_dup, /* dup */
nfs_opendir, /* opendir */
NULL, /* closedir */
@@ -357,7 +360,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Save the attributes in the file data structure */
- tmp = *ptr++; /* handle_follows */
+ tmp = *ptr; /* handle_follows */
if (!tmp)
{
fdbg("WARNING: no file attributes\n");
@@ -367,7 +370,6 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Initialize the file attributes */
nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
- ptr += uint32_increment(sizeof(struct nfs_fattr));
}
/* Any following dir_wcc data is ignored for now */
@@ -410,7 +412,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
reqlen += (int)np->n_fhsize;
ptr += uint32_increment(np->n_fhsize);
- /* Copy the variable-length attribtes */
+ /* Copy the variable-length attributes */
*ptr++ = nfs_false; /* Don't change mode */
*ptr++ = nfs_false; /* Don't change uid */
@@ -421,7 +423,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
*ptr++ = nfs_false; /* No guard value */
- reqlen += 9*sizeof(uint32_t)
+ reqlen += 9 * sizeof(uint32_t);
/* Perform the SETATTR RPC */
@@ -551,9 +553,9 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
static int nfs_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
- struct nfsmount *nmp;
- struct nfsnode *np = NULL;
- int error;
+ struct nfsmount *nmp;
+ struct nfsnode *np;
+ int error;
/* Sanity checks */
@@ -632,6 +634,8 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
* non-zero elements)
*/
+ np->n_crefs = 1;
+
/* Attach the private data to the struct file instance */
filep->f_priv = np;
@@ -654,6 +658,7 @@ errout_with_semaphore:
{
kfree(np);
}
+
nfs_semgive(nmp);
return -error;
}
@@ -675,6 +680,7 @@ static int nfs_close(FAR struct file *filep)
FAR struct nfsnode *np;
FAR struct nfsnode *prev;
FAR struct nfsnode *curr;
+ int ret;
/* Sanity checks */
@@ -691,42 +697,64 @@ static int nfs_close(FAR struct file *filep)
nfs_semtake(nmp);
- /* Find our file structure in the list of file structures containted in the
- * mount structure.
+ /* Decrement the reference count. If the reference count would not
+ * decrement to zero, then that is all we have to do.
*/
- for (prev = NULL, curr = nmp->nm_head; curr; prev = curr, curr = curr->n_next)
- {
- /* Check if this node is ours */
+ if (np->n_crefs > 1)
+ {
+ np->n_crefs--;
+ ret = OK;
+ }
- if (np == curr)
- {
- /* Yes.. remove it from the list of file structures */
+ /* There are no more references to the file structure. Now we need to
+ * free up all resources associated with the open file.
+ *
+ * First, find our file structure in the list of file structures
+ * containted in the mount structure.
+ */
+
+ else
+ {
+ /* Assume file structure will not be found. This should never happen. */
+
+ ret = -EINVAL;
+
+ for (prev = NULL, curr = nmp->nm_head;
+ curr;
+ prev = curr, curr = curr->n_next)
+ {
+ /* Check if this node is ours */
- if (prev)
- {
- /* Remove from mid-list */
+ if (np == curr)
+ {
+ /* Yes.. remove it from the list of file structures */
- prev->n_next = np->n_next;
- }
- else
- {
- /* Remove from the head of the list */
+ if (prev)
+ {
+ /* Remove from mid-list */
- nmp->nm_head = np->n_next;
- }
+ prev->n_next = np->n_next;
+ }
+ else
+ {
+ /* Remove from the head of the list */
- /* Then deallocate the file structure and return success */
+ nmp->nm_head = np->n_next;
+ }
- kfree(np);
- nfs_semgive(nmp);
- return OK;
- }
- }
+ /* Then deallocate the file structure and return success */
- fdbg("ERROR: file structure not found in list: %p\n", np);
+ kfree(np);
+ ret = OK;
+ break;
+ }
+ }
+ }
+
+ filep->f_priv = NULL;
nfs_semgive(nmp);
- return EINVAL;
+ return ret;
}
/****************************************************************************
@@ -757,8 +785,8 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
/* Recover our private data from the struct file instance */
- nmp = (struct nfsmount*) filep->f_inode->i_private;
- np = (struct nfsnode*) filep->f_priv;
+ nmp = (struct nfsmount*)filep->f_inode->i_private;
+ np = (struct nfsnode*)filep->f_priv;
DEBUGASSERT(nmp != NULL);
@@ -1092,6 +1120,66 @@ errout_with_semaphore:
}
/****************************************************************************
+ * Name: binfs_dup
+ *
+ * Description:
+ * Duplicate open file data in the new file structure.
+ *
+ ****************************************************************************/
+
+static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp)
+{
+ struct nfsmount *nmp;
+ FAR struct nfsnode *np;
+ int error;
+
+ fvdbg("Dup %p->%p\n", oldp, newp);
+
+ /* Sanity checks */
+
+ DEBUGASSERT(oldp->f_priv != NULL && oldp->f_inode != NULL);
+
+ /* Recover our private data from the struct file instance */
+
+ nmp = (struct nfsmount*)oldp->f_inode->i_private;
+ np = (struct nfsnode*)oldp->f_priv;
+
+ DEBUGASSERT(nmp != NULL);
+
+ /* Check if the mount is still healthy */
+
+ nfs_semtake(nmp);
+ error = nfs_checkmount(nmp);
+ if (error != OK)
+ {
+ fdbg("ERROR: nfs_checkmount failed: %d\n", error);
+ nfs_semgive(nmp);
+ return -error;
+ }
+
+ /* Increment the reference count on the NFS node structure */
+
+ DEBUGASSERT(np->n_crefs < 0xff);
+ np->n_crefs++;
+
+ /* And save this as the file data for the new node */
+
+ newp->f_priv = np;
+
+ /* Then insert the new instance at the head of the list in the mountpoint
+ * tructure. It needs to be there (1) to handle error conditions that effect
+ * all files, and (2) to inform the umount logic that we are busy. We
+ * cannot unmount the file system if this list is not empty!
+ */
+
+ np->n_next = nmp->nm_head;
+ nmp->nm_head = np;
+
+ nfs_semgive(nmp);
+ return OK;
+}
+
+/****************************************************************************
* Name: nfs_opendir
*
* Description:
@@ -1754,12 +1842,15 @@ bad:
{
kfree(nmp->nm_so);
}
+
if (nmp->nm_rpcclnt)
{
kfree(nmp->nm_rpcclnt);
}
+
kfree(nmp);
}
+
return error;
}
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index 0e2a394ba..9c2ada4f2 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/rpc_clnt.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
* Gregory Nutt <gnutt@nuttx.org>
@@ -224,8 +224,6 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
FAR void *reply, size_t resplen)
{
- FAR struct rpc_reply_header *replyheader;
- uint32_t rxid;
int error;
/* Get the next RPC reply from the socket */
@@ -235,22 +233,22 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
{
fdbg("ERROR: rpcclnt_receive returned: %d\n", error);
- /* If we failed because of a timeout, then try sending the CALL
- * message again.
- */
+ /* If we failed because of a timeout, then try sending the CALL
+ * message again.
+ */
- if (error == EAGAIN || error == ETIMEDOUT)
- {
- rpc->rc_timeout = true;
- }
- }
+ if (error == EAGAIN || error == ETIMEDOUT)
+ {
+ rpc->rc_timeout = true;
+ }
+ }
/* Get the xid and check that it is an RPC replysvr */
else
{
- replyheader = (FAR struct rpc_reply_header *)reply;
- rxid = replyheader->rp_xid;
+ FAR struct rpc_reply_header *replyheader =
+ (FAR struct rpc_reply_header *)reply;
if (replyheader->rp_direction != rpc_reply)
{
@@ -260,7 +258,7 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
}
}
- return OK;
+ return error;
}
/****************************************************************************
@@ -275,7 +273,6 @@ static uint32_t rpcclnt_newxid(void)
{
static uint32_t rpcclnt_xid = 0;
static uint32_t rpcclnt_xid_touched = 0;
- int xidp = 0;
srand(time(NULL));
if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0))
@@ -285,6 +282,7 @@ static uint32_t rpcclnt_newxid(void)
}
else
{
+ int xidp = 0;
do
{
xidp = rand();