diff options
Diffstat (limited to 'nuttx/fs/nfs')
-rw-r--r-- | nuttx/fs/nfs/Make.defs | 9 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_node.h | 3 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_util.c | 9 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_vfsops.c | 163 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc_clnt.c | 28 |
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(); |