From 00ce66b041e8f3705e859f6bc1c6a2db8feaf100 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 14 Jun 2012 18:04:39 +0000 Subject: [PATCH] NFS... add logic to truncate files if needed on open git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4843 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/fs/nfs/nfs_mount.h | 1 + nuttx/fs/nfs/nfs_proto.h | 12 ++++++ nuttx/fs/nfs/nfs_vfsops.c | 90 +++++++++++++++++++++++++++++++++------ nuttx/fs/nfs/rpc.h | 13 ++++++ 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/nuttx/fs/nfs/nfs_mount.h b/nuttx/fs/nfs/nfs_mount.h index 302cd9370..30b644db6 100644 --- a/nuttx/fs/nfs/nfs_mount.h +++ b/nuttx/fs/nfs/nfs_mount.h @@ -102,6 +102,7 @@ struct nfsmount struct rpc_call_rmdir rmdir; struct rpc_call_readdir readdir; struct rpc_call_fs fsstat; + struct rpc_call_setattr setattr; struct rpc_call_fs fs; struct rpc_reply_write write; } nm_msgbuffer; diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h index cc53d8218..676ee6232 100644 --- a/nuttx/fs/nfs/nfs_proto.h +++ b/nuttx/fs/nfs/nfs_proto.h @@ -410,6 +410,18 @@ struct LOOKUP3args struct LOOKUP3filename name; /* Variable length */ }; +struct SETATTR3args +{ + struct file_handle fhandle; /* Variable length */ + struct nfsv3_sattr new_attributes; /* Variable length */ + uint32_t guard; /* Guard value */ +}; + +struct SETATTR3resok +{ + struct wcc_data wcc_data; +}; + /* Actual size of LOOKUP3args */ #define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3)) diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c index dc6294368..4e444423e 100644 --- a/nuttx/fs/nfs/nfs_vfsops.c +++ b/nuttx/fs/nfs/nfs_vfsops.c @@ -113,6 +113,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, FAR const char *relpath, mode_t mode); +static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np); static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, FAR const char *relpath, int oflags, mode_t mode); static int nfs_open(FAR struct file *filep, const char *relpath, @@ -320,7 +321,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, { /* Parse the returned data */ - ptr = (FAR uint32_t *)nmp->nm_iobuffer; + ptr = (FAR uint32_t *)&((FAR struct rpc_reply_create *)nmp->nm_iobuffer)->create; /* Save the file handle in the file data structure */ @@ -360,6 +361,70 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, return error; } +/**************************************************************************** + * Name: nfs_fileopen + * + * Description: + * Truncate an open file to zero length. + * + * Returned Value: + * 0 on success; a positive errno value on failure. + * + ****************************************************************************/ + +static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np) +{ + FAR uint32_t *ptr; + int reqlen; + int error; + + fvdbg("Truncating file\n"); + + /* Create the SETATTR RPC call arguments */ + + ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.setattr.setattr; + reqlen = 0; + + /* Copy the variable length, directory file handle */ + + *ptr++ = txdr_unsigned(np->n_fhsize); + reqlen += sizeof(uint32_t); + + memcpy(ptr, &np->n_fhandle, np->n_fhsize); + reqlen += (int)np->n_fhsize; + ptr += uint32_increment(np->n_fhsize); + + /* Copy the variable-length attribtes */ + + *ptr++ = nfs_false; /* Don't change mode */ + *ptr++ = nfs_false; /* Don't change uid */ + *ptr++ = nfs_false; /* Don't change gid */ + *ptr++ = nfs_true; /* Use the following size */ + *ptr++ = 0; /* Truncate to zero length */ + *ptr++ = 0; + *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) + + /* Perform the SETATTR RPC */ + + nfs_statistics(NFSPROC_SETATTR); + error = nfs_request(nmp, NFSPROC_SETATTR, + (FAR void *)&nmp->nm_msgbuffer.setattr, reqlen, + (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen); + if (error != OK) + { + fdbg("ERROR: nfs_request failed: %d\n", error); + return error; + } + + /* Indicate that the file now has zero length */ + + np->n_size = 0; + return OK; +} + /**************************************************************************** * Name: nfs_fileopen * @@ -427,6 +492,16 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, return EEXIST; } + /* Initialize the file private data */ + /* Copy the file handle */ + + np->n_fhsize = (uint8_t)fhandle.length; + memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length); + + /* Save the file attributes */ + + nfs_attrupdate(np, &fattr); + /* If O_TRUNC is specified and the file is opened for writing, * then truncate the file. This operation requires that the file is * writable, but we have already checked that. O_TRUNC without write @@ -439,20 +514,9 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, * the SETATTR call by setting the length to zero. */ - fvdbg("Truncating file\n"); -#warning "Missing logic" - return ENOSYS; + return nfs_filetruncate(nmp, np); } - /* Initialize the file private data */ - /* Copy the file handle */ - - np->n_fhsize = (uint8_t)fhandle.length; - memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length); - - /* Save the file attributes */ - - nfs_attrupdate(np, &fattr); return OK; } diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h index 15b340ee4..653802b10 100644 --- a/nuttx/fs/nfs/rpc.h +++ b/nuttx/fs/nfs/rpc.h @@ -360,6 +360,12 @@ struct rpc_call_readdir struct READDIR3args readdir; }; +struct rpc_call_setattr +{ + struct rpc_call_header ch; + struct SETATTR3args setattr; +}; + struct rpc_call_fs { struct rpc_call_header ch; @@ -489,6 +495,13 @@ struct rpc_reply_getattr struct nfs_fattr attr; }; +struct rpc_reply_setattr +{ + struct rpc_reply_header rh; + uint32_t status; + struct SETATTR3resok setattr; +}; + struct rpcclnt { nfsfh_t rc_fh; /* File handle of root dir */