mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
Fix PL2303 typo checked in a long time ago; NFS update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4832 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -2900,4 +2900,6 @@
|
|||||||
Fix an error when the trapezoid is only 1 line high. In this case, a
|
Fix an error when the trapezoid is only 1 line high. In this case, a
|
||||||
divide by zero error would occur. The fix is to draw the 1 line high
|
divide by zero error would occur. The fix is to draw the 1 line high
|
||||||
trapezoid as a run.
|
trapezoid as a run.
|
||||||
|
* drivers/usbdev/pl2303.c: Fixe a cut'n'paste error that snuck into
|
||||||
|
the PL2303 emulation driver several months back.
|
||||||
|
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv)
|
|||||||
/* Get the maximum number of bytes that will fit into one bulk IN request */
|
/* Get the maximum number of bytes that will fit into one bulk IN request */
|
||||||
|
|
||||||
#ifdef CONFIG_PL2303_BULKREQLEN
|
#ifdef CONFIG_PL2303_BULKREQLEN
|
||||||
reqlen = MAX(CONFIG_CDCACM_BULKREQLEN, ep->maxpacket);
|
reqlen = MAX(CONFIG_PL2303_BULKREQLEN, ep->maxpacket);
|
||||||
#else
|
#else
|
||||||
reqlen = ep->maxpacket;
|
reqlen = ep->maxpacket;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+9
-8
@@ -360,22 +360,23 @@ extern "C" {
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN void nfs_semtake(struct nfsmount *nmp);
|
EXTERN void nfs_semtake(FAR struct nfsmount *nmp);
|
||||||
EXTERN void nfs_semgive(struct nfsmount *nmp);
|
EXTERN void nfs_semgive(FAR struct nfsmount *nmp);
|
||||||
EXTERN int nfs_checkmount(struct nfsmount *nmp);
|
EXTERN int nfs_checkmount(FAR struct nfsmount *nmp);
|
||||||
EXTERN int nfs_fsinfo(struct nfsmount *nmp);
|
EXTERN int nfs_fsinfo(FAR struct nfsmount *nmp);
|
||||||
EXTERN int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
|
EXTERN int nfs_lookup(FAR struct nfsmount *nmp, FAR const char *filename,
|
||||||
FAR struct file_handle *fhandle,
|
FAR struct file_handle *fhandle,
|
||||||
FAR struct nfs_fattr *obj_attributes,
|
FAR struct nfs_fattr *obj_attributes,
|
||||||
FAR struct nfs_fattr *dir_attributes);
|
FAR struct nfs_fattr *dir_attributes);
|
||||||
EXTERN int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
|
EXTERN int nfs_findnode(FAR struct nfsmount *nmp, FAR const char *relpath,
|
||||||
FAR struct file_handle *fhandle,
|
FAR struct file_handle *fhandle,
|
||||||
FAR struct nfs_fattr *obj_attributes,
|
FAR struct nfs_fattr *obj_attributes,
|
||||||
FAR struct nfs_fattr *dir_attributes);
|
FAR struct nfs_fattr *dir_attributes);
|
||||||
EXTERN int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
|
EXTERN int nfs_finddir(FAR struct nfsmount *nmp, FAR const char *relpath,
|
||||||
FAR struct file_handle *fhandle,
|
FAR struct file_handle *fhandle,
|
||||||
FAR struct nfs_fattr *attributes, FAR char *filename);
|
FAR struct nfs_fattr *attributes, FAR char *filename);
|
||||||
|
EXTERN void nfs_attrupdate(FAR struct nfsnode *np,
|
||||||
|
FAR struct nfs_fattr *attributes);
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -65,9 +65,6 @@
|
|||||||
|
|
||||||
/* There is a unique nfsnode allocated for each active file. An nfsnode is
|
/* There is a unique nfsnode allocated for each active file. An nfsnode is
|
||||||
* 'named' by its file handle.
|
* 'named' by its file handle.
|
||||||
*
|
|
||||||
* NOTE: n_size, n_mtime, and n_ctime are duplicted withing n_attr. We could
|
|
||||||
* eliminate those fields and save some memory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct nfsnode
|
struct nfsnode
|
||||||
@@ -77,9 +74,8 @@ struct nfsnode
|
|||||||
uint8_t n_fhsize; /* Size in bytes of the file handle */
|
uint8_t n_fhsize; /* Size in bytes of the file handle */
|
||||||
uint8_t n_flags; /* Node flags */
|
uint8_t n_flags; /* Node flags */
|
||||||
uint16_t n_buflen; /* Size of I/O buffer */
|
uint16_t n_buflen; /* Size of I/O buffer */
|
||||||
struct nfs_fattr n_fattr; /* nfs file attribute cache (network order) */
|
struct timespec n_mtime; /* File modification time (see NOTE) */
|
||||||
struct timespec n_mtime; /* Prev modify time (see NOTE) */
|
time_t n_ctime; /* File creation time (see NOTE) */
|
||||||
time_t n_ctime; /* Prev create time (see NOTE) */
|
|
||||||
nfsfh_t n_fhandle; /* NFS File Handle */
|
nfsfh_t n_fhandle; /* NFS File Handle */
|
||||||
uint64_t n_size; /* Current size of file (see NOTE) */
|
uint64_t n_size; /* Current size of file (see NOTE) */
|
||||||
|
|
||||||
|
|||||||
@@ -616,3 +616,24 @@ int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nfs_attrupdate
|
||||||
|
*
|
||||||
|
* Desciption:
|
||||||
|
* Update file attributes on write or after the file is modified.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void nfs_attrupdate(FAR struct nfsnode *np, FAR struct nfs_fattr *attributes)
|
||||||
|
{
|
||||||
|
/* Save a few of the files attribute values in file structur (host order) */
|
||||||
|
|
||||||
|
np->n_type = fxdr_unsigned(uint32_t, attributes->fa_type);
|
||||||
|
np->n_size = fxdr_hyper(&attributes->fa_size);
|
||||||
|
fxdr_nfsv3time(&attributes->fa_mtime, &np->n_mtime)
|
||||||
|
np->n_ctime = fxdr_hyper(&attributes->fa_ctime);
|
||||||
|
}
|
||||||
|
|||||||
+161
-115
@@ -200,6 +200,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
FAR const char *relpath, mode_t mode)
|
FAR const char *relpath, mode_t mode)
|
||||||
{
|
{
|
||||||
struct file_handle fhandle;
|
struct file_handle fhandle;
|
||||||
|
struct nfs_fattr fattr;
|
||||||
char filename[NAME_MAX + 1];
|
char filename[NAME_MAX + 1];
|
||||||
struct CREATE3args request;
|
struct CREATE3args request;
|
||||||
struct rpc_reply_create resok;
|
struct rpc_reply_create resok;
|
||||||
@@ -211,7 +212,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
|
|
||||||
/* Find the NFS node of the directory containing the file to be created */
|
/* Find the NFS node of the directory containing the file to be created */
|
||||||
|
|
||||||
error = nfs_finddir(nmp, relpath, &fhandle, &np->n_fattr, filename);
|
error = nfs_finddir(nmp, relpath, &fhandle, &fattr, filename);
|
||||||
if (error != OK)
|
if (error != OK)
|
||||||
{
|
{
|
||||||
fdbg("ERROR: nfs_finddir returned: %d\n", error);
|
fdbg("ERROR: nfs_finddir returned: %d\n", error);
|
||||||
@@ -329,7 +330,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
{
|
{
|
||||||
/* Parse the returned data */
|
/* Parse the returned data */
|
||||||
|
|
||||||
ptr = (FAR uint32_t *)&resok;
|
ptr = (FAR uint32_t *)&resok.create;
|
||||||
|
|
||||||
/* Save the file handle in the file data structure */
|
/* Save the file handle in the file data structure */
|
||||||
|
|
||||||
@@ -357,15 +358,10 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(&np->n_fattr, ptr, sizeof(struct nfs_fattr));
|
/* Initialize the file attributes */
|
||||||
ptr += uint32_increment(sizeof(struct nfs_fattr));
|
|
||||||
|
|
||||||
/* Put a few of the attribute values in host order */
|
nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
|
||||||
|
ptr += uint32_increment(sizeof(struct nfs_fattr));
|
||||||
np->n_type = fxdr_unsigned(uint32_t, np->n_fattr.fa_type);
|
|
||||||
np->n_size = fxdr_hyper(&np->n_fattr.fa_size);
|
|
||||||
fxdr_nfsv3time(&np->n_fattr.fa_mtime, &np->n_mtime)
|
|
||||||
np->n_ctime = fxdr_hyper(&np->n_fattr.fa_ctime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any following dir_wcc data is ignored for now */
|
/* Any following dir_wcc data is ignored for now */
|
||||||
@@ -390,12 +386,13 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
FAR const char *relpath, int oflags, mode_t mode)
|
FAR const char *relpath, int oflags, mode_t mode)
|
||||||
{
|
{
|
||||||
struct file_handle fhandle;
|
struct file_handle fhandle;
|
||||||
|
struct nfs_fattr fattr;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/* Find the NFS node associate with the path */
|
/* Find the NFS node associate with the path */
|
||||||
|
|
||||||
error = nfs_findnode(nmp, relpath, &fhandle, &np->n_fattr, NULL);
|
error = nfs_findnode(nmp, relpath, &fhandle, &fattr, NULL);
|
||||||
if (error != OK)
|
if (error != OK)
|
||||||
{
|
{
|
||||||
fdbg("ERROR: nfs_findnode returned: %d\n", error);
|
fdbg("ERROR: nfs_findnode returned: %d\n", error);
|
||||||
@@ -404,7 +401,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
|
|
||||||
/* Check if the object is a directory */
|
/* Check if the object is a directory */
|
||||||
|
|
||||||
tmp = fxdr_unsigned(uint32_t, np->n_fattr.fa_type);
|
tmp = fxdr_unsigned(uint32_t, fattr.fa_type);
|
||||||
if (tmp == NFDIR)
|
if (tmp == NFDIR)
|
||||||
{
|
{
|
||||||
/* Exit with EISDIR if we attempt to open a directory */
|
/* Exit with EISDIR if we attempt to open a directory */
|
||||||
@@ -422,7 +419,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
* able to write).
|
* able to write).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = fxdr_unsigned(uint32_t, np->n_fattr.fa_mode);
|
tmp = fxdr_unsigned(uint32_t, fattr.fa_mode);
|
||||||
if ((tmp & (NFSMODE_IWOTH|NFSMODE_IWGRP|NFSMODE_IWUSR)) == 0)
|
if ((tmp & (NFSMODE_IWOTH|NFSMODE_IWGRP|NFSMODE_IWUSR)) == 0)
|
||||||
{
|
{
|
||||||
fdbg("ERROR: File is read-only: %08x\n", tmp);
|
fdbg("ERROR: File is read-only: %08x\n", tmp);
|
||||||
@@ -463,15 +460,9 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
|
|||||||
np->n_fhsize = (uint8_t)fhandle.length;
|
np->n_fhsize = (uint8_t)fhandle.length;
|
||||||
memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length);
|
memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length);
|
||||||
|
|
||||||
/* Get a convenience versions of file type, size, and modification time
|
/* Save the file attributes */
|
||||||
* in host byte order.
|
|
||||||
*/
|
|
||||||
|
|
||||||
np->n_type = fxdr_unsigned(uint32_t, np->n_fattr.fa_type);
|
|
||||||
np->n_size = fxdr_hyper(&np->n_fattr.fa_size);
|
|
||||||
fxdr_nfsv3time(&np->n_fattr.fa_mtime, &np->n_mtime)
|
|
||||||
np->n_ctime = fxdr_hyper(&np->n_fattr.fa_ctime);
|
|
||||||
|
|
||||||
|
nfs_attrupdate(np, &fattr);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,7 +744,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
|
|||||||
ptr = (FAR uint32_t*)&request;
|
ptr = (FAR uint32_t*)&request;
|
||||||
reqlen = 0;
|
reqlen = 0;
|
||||||
|
|
||||||
/* Copy the variable length, directory file handle */
|
/* Copy the variable length, file handle */
|
||||||
|
|
||||||
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
|
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
|
||||||
reqlen += sizeof(uint32_t);
|
reqlen += sizeof(uint32_t);
|
||||||
@@ -858,19 +849,20 @@ errout_with_semaphore:
|
|||||||
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
|
||||||
struct nfsmount *nmp;
|
struct nfsmount *nmp;
|
||||||
struct nfsnode *np;
|
struct nfsnode *np;
|
||||||
unsigned int writesize;
|
|
||||||
struct rpc_reply_write resok;
|
struct rpc_reply_write resok;
|
||||||
uint64_t offset;
|
ssize_t writesize;
|
||||||
uint8_t *userbuffer = (uint8_t*)buffer;
|
ssize_t bufsize;
|
||||||
|
ssize_t byteswritten;
|
||||||
size_t reqlen;
|
size_t reqlen;
|
||||||
uint32_t *ptr;
|
FAR uint32_t *ptr;
|
||||||
int len;
|
uint32_t tmp;
|
||||||
int commit = 0;
|
int commit = 0;
|
||||||
int committed = NFSV3WRITE_FILESYNC;
|
int committed = NFSV3WRITE_FILESYNC;
|
||||||
int error = 0;
|
int error;
|
||||||
|
|
||||||
|
fvdbg("Write %d bytes to offset %d\n", buflen, filep->f_pos);
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
|
||||||
@@ -878,10 +870,8 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
|||||||
|
|
||||||
/* Recover our private data from the struct file instance */
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
np = (struct nfsnode *)filep->f_priv;
|
nmp = (struct nfsmount*)filep->f_inode->i_private;
|
||||||
inode = filep->f_inode;
|
np = (struct nfsnode*)filep->f_priv;
|
||||||
nmp = (struct nfsmount *)inode->i_private;
|
|
||||||
offset = 0;
|
|
||||||
|
|
||||||
DEBUGASSERT(nmp != NULL);
|
DEBUGASSERT(nmp != NULL);
|
||||||
|
|
||||||
@@ -891,7 +881,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
|||||||
error = nfs_checkmount(nmp);
|
error = nfs_checkmount(nmp);
|
||||||
if (error != OK)
|
if (error != OK)
|
||||||
{
|
{
|
||||||
fdbg("ERROR: nfs_checkmount failed: %d\n", error);
|
fdbg("nfs_checkmount failed: %d\n", error);
|
||||||
goto errout_with_semaphore;
|
goto errout_with_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,87 +893,144 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
|||||||
goto errout_with_semaphore;
|
goto errout_with_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = nmp->nm_wsize;
|
/* Now loop until we send the entire user buffer */
|
||||||
if (len < buflen)
|
|
||||||
|
for (byteswritten = 0; byteswritten < buflen; )
|
||||||
{
|
{
|
||||||
error = EFBIG;
|
/* Make sure that the attempted write size does not exceed the RPC maximum */
|
||||||
goto errout_with_semaphore;
|
|
||||||
|
writesize = buflen;
|
||||||
|
if (writesize > nmp->nm_wsize)
|
||||||
|
{
|
||||||
|
writesize = nmp->nm_wsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure that the attempted read size does not exceed the IO buffer size */
|
||||||
|
|
||||||
|
bufsize = SIZEOF_rpc_call_write(writesize);
|
||||||
|
if (bufsize > np->n_buflen)
|
||||||
|
{
|
||||||
|
writesize -= (bufsize - np->n_buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the request. Here we need an offset pointer to the write
|
||||||
|
* arguments, skipping over the RPC header. Write is unique among the
|
||||||
|
* RPC calls in that the entry RPC calls messasge lies in the I/O buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
ptr = (FAR uint32_t *)&((FAR struct rpc_call_write *)np->n_iobuffer)->write;
|
||||||
|
reqlen = 0;
|
||||||
|
|
||||||
|
/* Copy the variable length, file handle */
|
||||||
|
|
||||||
|
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
|
||||||
|
reqlen += sizeof(uint32_t);
|
||||||
|
|
||||||
|
memcpy(ptr, &np->n_fhandle, np->n_fhsize);
|
||||||
|
reqlen += (int)np->n_fhsize;
|
||||||
|
ptr += uint32_increment((int)np->n_fhsize);
|
||||||
|
|
||||||
|
/* Copy the file offset */
|
||||||
|
|
||||||
|
txdr_hyper((uint64_t)filep->f_pos, ptr);
|
||||||
|
ptr += 2;
|
||||||
|
reqlen += 2*sizeof(uint32_t);
|
||||||
|
|
||||||
|
/* Copy the count and stable values */
|
||||||
|
|
||||||
|
*ptr++ = txdr_unsigned(buflen);
|
||||||
|
*ptr++ = txdr_unsigned(committed);
|
||||||
|
reqlen += 2*sizeof(uint32_t);
|
||||||
|
|
||||||
|
/* Copy a chunk of the user data into the I/O buffer */
|
||||||
|
|
||||||
|
*ptr++ = txdr_unsigned(buflen);
|
||||||
|
reqlen += sizeof(uint32_t);
|
||||||
|
memcpy(ptr, buffer, writesize);
|
||||||
|
reqlen += writesize;
|
||||||
|
|
||||||
|
/* Perform the write */
|
||||||
|
|
||||||
|
nfsstats.rpccnt[NFSPROC_WRITE]++;
|
||||||
|
error = nfs_request(nmp, NFSPROC_WRITE,
|
||||||
|
(FAR const void *)np->n_iobuffer, reqlen,
|
||||||
|
(FAR void *)&resok, sizeof(struct rpc_reply_write));
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fdbg("ERROR: nfs_request failed: %d\n", error);
|
||||||
|
goto errout_with_semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a pointer to the WRITE reply data */
|
||||||
|
|
||||||
|
ptr = (FAR uint32_t *)&resok.write;
|
||||||
|
|
||||||
|
/* Parse file_wcc. First, check if WCC attributes follow. */
|
||||||
|
|
||||||
|
tmp = *ptr++;
|
||||||
|
if (tmp != 0)
|
||||||
|
{
|
||||||
|
/* Yes.. WCC attributes follow. But we just skip over them. */
|
||||||
|
|
||||||
|
ptr += uint32_increment(sizeof(struct wcc_attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if normal file attributes follow */
|
||||||
|
|
||||||
|
tmp = *ptr++;
|
||||||
|
if (tmp != 0)
|
||||||
|
{
|
||||||
|
/* Yes.. Update the cached file status in the file structure. */
|
||||||
|
|
||||||
|
nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
|
||||||
|
ptr += uint32_increment(sizeof(struct nfs_fattr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the count of bytes actually written */
|
||||||
|
|
||||||
|
tmp = fxdr_unsigned(uint32_t, *ptr);
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if (tmp < 1 || tmp > writesize)
|
||||||
|
{
|
||||||
|
error = EIO;
|
||||||
|
goto errout_with_semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
writesize = tmp;
|
||||||
|
|
||||||
|
/* Determine the lowest committment level obtained by any of the RPCs. */
|
||||||
|
|
||||||
|
commit = *ptr++;
|
||||||
|
if (committed == NFSV3WRITE_FILESYNC)
|
||||||
|
{
|
||||||
|
committed = commit;
|
||||||
|
}
|
||||||
|
else if (committed == NFSV3WRITE_DATASYNC &&
|
||||||
|
commit == NFSV3WRITE_UNSTABLE)
|
||||||
|
{
|
||||||
|
committed = commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the verifier if needed or if it has change*/
|
||||||
|
|
||||||
|
if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
|
||||||
|
{
|
||||||
|
memcpy(nmp->nm_verf, ptr, NFSX_V3WRITEVERF);
|
||||||
|
nmp->nm_flag |= NFSMNT_HASWRITEVERF;
|
||||||
|
}
|
||||||
|
else if (memcmp(ptr, nmp->nm_verf, NFSX_V3WRITEVERF) != 0)
|
||||||
|
{
|
||||||
|
memcpy(nmp->nm_verf, ptr, NFSX_V3WRITEVERF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the read state data */
|
||||||
|
|
||||||
|
filep->f_pos += writesize;
|
||||||
|
byteswritten += writesize;
|
||||||
|
buffer += writesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
writesize = 0;
|
|
||||||
|
|
||||||
/* Initialize the request */
|
|
||||||
|
|
||||||
ptr = (FAR uint32_t*)&np->n_iobuffer;
|
|
||||||
reqlen = 0;
|
|
||||||
|
|
||||||
/* Copy the variable length, directory file handle */
|
|
||||||
|
|
||||||
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
|
|
||||||
reqlen += sizeof(uint32_t);
|
|
||||||
|
|
||||||
memcpy(ptr, &np->n_fhandle, np->n_fhsize);
|
|
||||||
reqlen += (int)np->n_fhsize;
|
|
||||||
ptr += uint32_increment((int)np->n_fhsize);
|
|
||||||
|
|
||||||
/* Copy the file offset */
|
|
||||||
|
|
||||||
txdr_hyper((uint64_t)filep->f_pos, ptr);
|
|
||||||
ptr += 2;
|
|
||||||
reqlen += 2*sizeof(uint32_t);
|
|
||||||
|
|
||||||
/* Copy the count and stable values */
|
|
||||||
|
|
||||||
*ptr++ = txdr_unsigned(buflen);
|
|
||||||
*ptr++ = txdr_unsigned(committed);
|
|
||||||
reqlen += 2*sizeof(uint32_t);
|
|
||||||
|
|
||||||
memcpy(ptr, userbuffer, buflen);
|
|
||||||
reqlen += buflen;
|
|
||||||
|
|
||||||
nfsstats.rpccnt[NFSPROC_WRITE]++;
|
|
||||||
error = nfs_request(nmp, NFSPROC_WRITE,
|
|
||||||
(FAR const void *)np->n_iobuffer, reqlen,
|
|
||||||
(FAR void *)&resok, sizeof(struct rpc_reply_write));
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
goto errout_with_semaphore;
|
|
||||||
}
|
|
||||||
|
|
||||||
writesize = resok.write.count;
|
|
||||||
if (writesize == 0)
|
|
||||||
{
|
|
||||||
error = EIO;
|
|
||||||
goto errout_with_semaphore;
|
|
||||||
}
|
|
||||||
|
|
||||||
commit = resok.write.committed;
|
|
||||||
memcpy(&np->n_fattr, &resok.write.file_wcc.after, sizeof(struct nfs_fattr));
|
|
||||||
|
|
||||||
/* Return the lowest committment level obtained by any of the RPCs. */
|
|
||||||
|
|
||||||
if (committed == NFSV3WRITE_FILESYNC)
|
|
||||||
{
|
|
||||||
committed = commit;
|
|
||||||
}
|
|
||||||
else if (committed == NFSV3WRITE_DATASYNC &&
|
|
||||||
commit == NFSV3WRITE_UNSTABLE)
|
|
||||||
{
|
|
||||||
committed = commit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
|
|
||||||
{
|
|
||||||
memcpy((void*) nmp->nm_verf, (void*) resok.write.verf, NFSX_V3WRITEVERF);
|
|
||||||
nmp->nm_flag |= NFSMNT_HASWRITEVERF;
|
|
||||||
}
|
|
||||||
else if (strncmp((char*) resok.write.verf, (char*) nmp->nm_verf, NFSX_V3WRITEVERF))
|
|
||||||
{
|
|
||||||
memcpy((void*) nmp->nm_verf, (void*) resok.write.verf, NFSX_V3WRITEVERF);
|
|
||||||
}
|
|
||||||
|
|
||||||
fxdr_nfsv3time(&np->n_fattr.fa_mtime, &np->n_mtime)
|
|
||||||
|
|
||||||
nfs_semgive(nmp);
|
nfs_semgive(nmp);
|
||||||
return writesize;
|
return writesize;
|
||||||
|
|
||||||
@@ -1664,8 +1711,8 @@ int mountnfs(struct nfs_args *argp, void **handle)
|
|||||||
|
|
||||||
/* Save the file attributes */
|
/* Save the file attributes */
|
||||||
|
|
||||||
memcpy(&np->n_fattr, &resok.attr, sizeof(struct nfs_fattr));
|
|
||||||
memcpy(&nmp->nm_fattr, &resok.attr, sizeof(struct nfs_fattr));
|
memcpy(&nmp->nm_fattr, &resok.attr, sizeof(struct nfs_fattr));
|
||||||
|
nfs_attrupdate(np, &resok.attr);
|
||||||
|
|
||||||
/* Mounted! */
|
/* Mounted! */
|
||||||
|
|
||||||
@@ -1852,7 +1899,6 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
|
|||||||
goto errout_with_semaphore;
|
goto errout_with_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
nmp->nm_head->n_fattr = sfp.fsstat.obj_attributes;
|
|
||||||
sbp->f_bsize = NFS_FABLKSIZE;
|
sbp->f_bsize = NFS_FABLKSIZE;
|
||||||
tquad = fxdr_hyper(&sfp.fsstat.sf_tbytes);
|
tquad = fxdr_hyper(&sfp.fsstat.sf_tbytes);
|
||||||
sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE;
|
sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE;
|
||||||
@@ -2275,7 +2321,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format the RENAME RPC arguements */
|
/* Format the RENAME RPC arguments */
|
||||||
|
|
||||||
ptr = (FAR uint32_t *)&request;
|
ptr = (FAR uint32_t *)&request;
|
||||||
reqlen = 0;
|
reqlen = 0;
|
||||||
|
|||||||
+1
-1
@@ -434,7 +434,7 @@ struct rpc_reply_write
|
|||||||
{
|
{
|
||||||
struct rpc_reply_header rh;
|
struct rpc_reply_header rh;
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
struct WRITE3resok write;
|
struct WRITE3resok write; /* Variable length */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpc_reply_read
|
struct rpc_reply_read
|
||||||
|
|||||||
+35
-10
@@ -1143,12 +1143,12 @@ static int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int ve
|
|||||||
|
|
||||||
case NFSPROC_WRITE:
|
case NFSPROC_WRITE:
|
||||||
{
|
{
|
||||||
/* Copy the variable length, caller-provided data into the call
|
/* The WRITE message is a unique case: The write data is already
|
||||||
* message structure.
|
* provided in an I/O buffer at the correct offset. Here we
|
||||||
|
* merely have to inititlized the RPC header fields.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct rpc_call_write *callmsg = (struct rpc_call_write *)msgbuf;
|
struct rpc_call_write *callmsg = (struct rpc_call_write *)request;
|
||||||
memcpy(&callmsg->write, request, *reqlen);
|
|
||||||
|
|
||||||
/* Return the full size of the message (the size of variable data
|
/* Return the full size of the message (the size of variable data
|
||||||
* plus the size of the messages header).
|
* plus the size of the messages header).
|
||||||
@@ -1790,7 +1790,11 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
|||||||
struct xidr value;
|
struct xidr value;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/* Set aside memory on the stack to hold the largest call message */
|
/* Set aside memory on the stack to hold the largest call message. NOTE
|
||||||
|
* that the write call message does not appear in this list. It is a
|
||||||
|
* special case because the full write call message will be provided in
|
||||||
|
* user-provided I/O vuffer.
|
||||||
|
*/
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@@ -1798,7 +1802,6 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
|||||||
struct rpc_call_mount mountd;
|
struct rpc_call_mount mountd;
|
||||||
struct rpc_call_create create;
|
struct rpc_call_create create;
|
||||||
struct rpc_call_lookup lookup;
|
struct rpc_call_lookup lookup;
|
||||||
struct rpc_call_write write;
|
|
||||||
struct rpc_call_read read;
|
struct rpc_call_read read;
|
||||||
struct rpc_call_remove removef;
|
struct rpc_call_remove removef;
|
||||||
struct rpc_call_rename renamef;
|
struct rpc_call_rename renamef;
|
||||||
@@ -1807,10 +1810,32 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
|||||||
struct rpc_call_readdir readdir;
|
struct rpc_call_readdir readdir;
|
||||||
struct rpc_call_fs fs;
|
struct rpc_call_fs fs;
|
||||||
} u;
|
} u;
|
||||||
|
FAR void *callmsg;
|
||||||
|
|
||||||
/* Clear the call message memory */
|
/* Handle a nasty special case... the NFS WRITE call message will reside
|
||||||
|
* in a use provided I/O buffer, not in our local call message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
memset(&u, 0, sizeof(u));
|
if (prog == NFS_PROG && procnum == NFSPROC_WRITE)
|
||||||
|
{
|
||||||
|
/* User the caller provided I/O buffer. The data to be written has
|
||||||
|
* already been copied into the correct offset by the calling.
|
||||||
|
* rpcclnt_buildheader will need only to initialize the header and
|
||||||
|
* update the call messsage size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
callmsg = request;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear the local call message memory. rpcclnt_buildheader will
|
||||||
|
* need to initialie the header and copy the user RPC arguments into
|
||||||
|
* this buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
memset(&u, 0, sizeof(u));
|
||||||
|
callmsg = (FAR void *)&u;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create an instance of the task state structure */
|
/* Create an instance of the task state structure */
|
||||||
|
|
||||||
@@ -1822,7 +1847,7 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error = rpcclnt_buildheader(rpc, procnum, prog, version, &value,
|
error = rpcclnt_buildheader(rpc, procnum, prog, version, &value,
|
||||||
request, &reqlen, (FAR void*)&u);
|
request, &reqlen, callmsg);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
fdbg("ERROR: Building call header error\n");
|
fdbg("ERROR: Building call header error\n");
|
||||||
@@ -1881,7 +1906,7 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
|||||||
if (error == 0)
|
if (error == 0)
|
||||||
{
|
{
|
||||||
error = rpcclnt_send(rpc->rc_so, rpc->rc_name, procnum, prog,
|
error = rpcclnt_send(rpc->rc_so, rpc->rc_name, procnum, prog,
|
||||||
(FAR void*)&u, reqlen, task);
|
callmsg, reqlen, task);
|
||||||
|
|
||||||
#ifdef CONFIG_NFS_TCPIP
|
#ifdef CONFIG_NFS_TCPIP
|
||||||
if (rpc->rc_soflags & PR_CONNREQUIRED)
|
if (rpc->rc_soflags & PR_CONNREQUIRED)
|
||||||
|
|||||||
Reference in New Issue
Block a user