NFS update

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4808 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-06-06 21:51:03 +00:00
parent 976c9cf3ad
commit 1e5f276ad9
8 changed files with 236 additions and 163 deletions

21
TODO
View File

@ -35,7 +35,7 @@ nuttx/
(3) AVR (arch/avr) (3) AVR (arch/avr)
(0) Intel x86 (arch/x86) (0) Intel x86 (arch/x86)
(4) 8051 / MCS51 (arch/8051/) (4) 8051 / MCS51 (arch/8051/)
(2) MIPS/PIC32 (arch/mips) (3) MIPS/PIC32 (arch/mips)
(1) Hitachi/Renesas SH-1 (arch/sh/src/sh1) (1) Hitachi/Renesas SH-1 (arch/sh/src/sh1)
(4) Renesas M16C/26 (arch/sh/src/m16c) (4) Renesas M16C/26 (arch/sh/src/m16c)
(10) z80/z8/ez80 (arch/z80/) (10) z80/z8/ez80 (arch/z80/)
@ -1487,6 +1487,25 @@ o MIPS/PIC32(arch/mips)
Status: Open Status: Open
Priority: Medium Priority: Medium
Title: POSSIBLE INTERRUPT CONTROL ISSUE
Description: There is a kludge in the file arch/mips/src/common/up_idle.c.
Basically, if there is nothing else going on in the IDLE loop,
you have to disable then re-enable interrupts. Logically nothing
changes, but if you don't do this interrupts will be be disabled
in the IDLE loop which is a very bad thing to happen.
Some odd behavior in the interrupt setup on the IDLE loop is
not really a big concern, but what I do not understand is if
this behavior is occurring on all threads after all context
switches: Are interrupts always disabled until re-enabled?
This requires some further investigation at some point; it
may be nothing but may also be a symptom of some changes
required to the interrupt return logic (perhaps some CP0
status hazard?)
Status: Open
Priority: Low. Puzzling and needs some investigation, but there there
is no known misbehavior.
o Hitachi/Renesas SH-1 (arch/sh/src/sh1) o Hitachi/Renesas SH-1 (arch/sh/src/sh1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -69,15 +69,15 @@
struct nfsmount struct nfsmount
{ {
int nm_flag; /* Flags for soft/hard... */ uint32_t nm_flag; /* Flags for soft/hard... */
int nm_state; /* Internal state flags */ uint32_t nm_state; /* Internal state flags */
struct nfsnode *nm_head; /* A list to all files opened on this mountpoint */ struct nfsnode *nm_head; /* A list to all files opened on this mountpoint */
bool nm_mounted; /* true: The file system is ready */ bool nm_mounted; /* true: The file system is ready */
sem_t nm_sem; /* Used to assume thread-safe access */ sem_t nm_sem; /* Used to assume thread-safe access */
int nm_numgrps; /* Max. size of groupslist */ uint32_t nm_numgrps; /* Max. size of groupslist */
nfsfh_t nm_fh; /* File handle of root dir */ nfsfh_t nm_fh; /* File handle of root dir */
char nm_path[90]; /* server's path of the directory being mount */ char nm_path[90]; /* server's path of the directory being mount */
int nm_fhsize; /* Size of root file handle */ uint32_t nm_fhsize; /* Size of root file handle */
struct nfs_fattr nm_fattr; /* nfs file attribute cache */ struct nfs_fattr nm_fattr; /* nfs file attribute cache */
struct rpcclnt *nm_rpcclnt; /* rpc state */ struct rpcclnt *nm_rpcclnt; /* rpc state */
struct socket *nm_so; /* Rpc socket */ struct socket *nm_so; /* Rpc socket */
@ -85,23 +85,23 @@ struct nfsmount
uint8_t nm_soproto; /* and protocol */ uint8_t nm_soproto; /* and protocol */
uint8_t nm_soflags; /* pr_flags for socket protocol */ uint8_t nm_soflags; /* pr_flags for socket protocol */
struct sockaddr nm_nam; /* Addr of server */ struct sockaddr nm_nam; /* Addr of server */
int nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */ uint32_t nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
int nm_retry; /* Max retries */ uint32_t nm_retry; /* Max retries */
int nm_srtt[4]; /* Timers for rpcs */ uint32_t nm_srtt[4]; /* Timers for rpcs */
int nm_sdrtt[4]; uint32_t nm_sdrtt[4];
int nm_sent; /* Request send count */ uint32_t nm_sent; /* Request send count */
int nm_cwnd; /* Request send window */ uint32_t nm_cwnd; /* Request send window */
int nm_timeouts; /* Request timeouts */ uint32_t nm_timeouts; /* Request timeouts */
int nm_deadthresh; /* Threshold of timeouts-->dead server */ uint32_t nm_deadthresh; /* Threshold of timeouts-->dead server */
int nm_rsize; /* Max size of read rpc */ uint32_t nm_rsize; /* Max size of read rpc */
int nm_wsize; /* Max size of write rpc */ uint32_t nm_wsize; /* Max size of write rpc */
int nm_readdirsize; /* Size of a readdir rpc */ uint32_t nm_readdirsize; /* Size of a readdir rpc */
int nm_readahead; /* Num. of blocks to readahead */ uint32_t nm_readahead; /* Num. of blocks to readahead */
int nm_acdirmin; /* Directory attr cache min lifetime */ uint32_t nm_acdirmin; /* Directory attr cache min lifetime */
int nm_acdirmax; /* Directory attr cache max lifetime */ uint32_t nm_acdirmax; /* Directory attr cache max lifetime */
int nm_acregmin; /* Reg file attr cache min lifetime */ uint32_t nm_acregmin; /* Reg file attr cache min lifetime */
int nm_acregmax; /* Reg file attr cache max lifetime */ uint32_t nm_acregmax; /* Reg file attr cache max lifetime */
unsigned char *nm_verf; /* V3 write verifier */ unsigned char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */
}; };
#endif #endif

View File

@ -92,18 +92,6 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* Silly rename structure that hangs off the nfsnode until the name
* can be removed by nfs_inactive()
struct sillyrename
{
struct ucred *s_cred;
struct vnode *s_dvp;
long s_namlen;
char s_name[24];
};
*/
/* The nfsnode is the nfs equivalent to ufs's inode. Any similarity /* The nfsnode is the nfs equivalent to ufs's inode. Any similarity
* is purely coincidental. * is purely coincidental.
* There is a unique nfsnode allocated for each active file, * There is a unique nfsnode allocated for each active file,
@ -128,8 +116,7 @@ struct nfsnode
struct timespec n_mtime; /* Prev modify time. */ struct timespec n_mtime; /* Prev modify time. */
time_t n_ctime; /* Prev create time. */ time_t n_ctime; /* Prev create time. */
nfsfh_t n_fhp; /* NFS File Handle */ nfsfh_t n_fhp; /* NFS File Handle */
struct inode *n_inode; /* associated inode */ uint32_t n_error; /* Save write error value */
int n_error; /* Save write error value */
union union
{ {
struct timespec nf_atim; /* Special file times */ struct timespec nf_atim; /* Special file times */
@ -140,7 +127,7 @@ struct nfsnode
struct timespec nf_mtim; struct timespec nf_mtim;
off_t nd_direof; /* Directory EOF offset cache */ off_t nd_direof; /* Directory EOF offset cache */
} n_un2; } n_un2;
int n_fhsize; /* size in bytes, of fh */ uint32_t n_fhsize; /* size in bytes, of fh */
short n_flag; /* Flag for locking.. */ short n_flag; /* Flag for locking.. */
//nfsfh_t n_fh; /* Small File Handle */ //nfsfh_t n_fh; /* Small File Handle */
time_t n_accstamp; /* Access cache timestamp */ time_t n_accstamp; /* Access cache timestamp */

View File

@ -456,12 +456,14 @@ struct nfsv3_sattr
uint32_t sa_modetrue; uint32_t sa_modetrue;
uint32_t sa_mode; uint32_t sa_mode;
uint32_t sa_uidfalse; uint32_t sa_uidfalse;
//uint32_t sa_uid;
uint32_t sa_gidfalse; uint32_t sa_gidfalse;
//uint32_t sa_gid;
uint32_t sa_sizefalse; uint32_t sa_sizefalse;
uint32_t sa_atimetype; uint32_t sa_atimetype;
nfstime3 sa_atime; //nfstime3 sa_atime;
uint32_t sa_mtimetype; uint32_t sa_mtimetype;
nfstime3 sa_mtime; //nfstime3 sa_mtime;
}; };
struct nfs_statfs struct nfs_statfs
@ -503,19 +505,26 @@ struct nfs_statfs
#define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles #define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles
#define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec #define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec
struct post_attr
{
uint32_t obj_attributesfalse;
struct nfs_fattr attributes;
};
struct nfsv3_fsinfo struct nfsv3_fsinfo
{ {
struct nfs_fattr obj_attributes; //struct post_attr obj_attributes;
uint32_t fs_rtmax; uint32_t obj_attributesfalse;
uint32_t fs_rtpref; uint32_t fs_rtmax;
uint32_t fs_rtmult; uint32_t fs_rtpref;
uint32_t fs_wtmax; uint32_t fs_rtmult;
uint32_t fs_wtpref; uint32_t fs_wtmax;
uint32_t fs_wtmult; uint32_t fs_wtpref;
uint32_t fs_dtpref; uint32_t fs_wtmult;
nfsuint64 fs_maxfilesize; uint32_t fs_dtpref;
nfstime3 fs_timedelta; nfsuint64 fs_maxfilesize;
uint32_t fs_properties; nfstime3 fs_timedelta;
uint32_t fs_properties;
}; };
/* NFS procedures args */ /* NFS procedures args */
@ -630,6 +639,7 @@ struct MKDIR3args
struct MKDIR3resok struct MKDIR3resok
{ {
struct file_handle fshandle; struct file_handle fshandle;
uint32_t obj_attributesfalse;
struct nfs_fattr obj_attributes; struct nfs_fattr obj_attributes;
struct wcc_data dir_wcc; struct wcc_data dir_wcc;
}; };
@ -677,4 +687,5 @@ struct FS3args
{ {
struct file_handle fsroot; struct file_handle fsroot;
}; };
#endif #endif

View File

@ -124,13 +124,13 @@ int nfs_connect(struct nfsmount *nmp)
rpc = (struct rpcclnt *)kzalloc(sizeof(struct rpcclnt)); rpc = (struct rpcclnt *)kzalloc(sizeof(struct rpcclnt));
if (!rpc) if (!rpc)
{ {
ndbg("Failed to allocate rpc structure\n"); fdbg("Failed to allocate rpc structure\n");
return -ENOMEM; return -ENOMEM;
} }
rpc->rc_prog = &nfs3_program; rpc->rc_prog = &nfs3_program;
nvdbg("nfs connect!\n"); fvdbg("nfs connect!\n");
/* translate nfsmnt flags -> rpcclnt flags */ /* translate nfsmnt flags -> rpcclnt flags */
@ -224,12 +224,12 @@ tryagain:
if (error == ESTALE) if (error == ESTALE)
{ {
ndbg("%s: ESTALE on mount from server \n", fdbg("%s: ESTALE on mount from server \n",
nmp->nm_rpcclnt->rc_prog->prog_name); nmp->nm_rpcclnt->rc_prog->prog_name);
} }
else else
{ {
ndbg("%s: unknown error %d from server \n", fdbg("%s: unknown error %d from server \n",
nmp->nm_rpcclnt->rc_prog->prog_name, error); nmp->nm_rpcclnt->rc_prog->prog_name, error);
} }
@ -251,4 +251,4 @@ int nfs_nmcancelreqs(struct nfsmount *nmp)
{ {
return 0; //rpcclnt_cancelreqs(nmp->nm_rpcclnt); return 0; //rpcclnt_cancelreqs(nmp->nm_rpcclnt);
} }
#endif #endif

View File

@ -248,7 +248,7 @@ again:
np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode)); np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
if (!np) if (!np)
{ {
ndbg("Failed to allocate private data\n", error); fdbg("Failed to allocate private data\n", error);
error = -ENOMEM; error = -ENOMEM;
goto errout_with_semaphore; goto errout_with_semaphore;
} }
@ -307,7 +307,7 @@ again:
{ {
if (np->nfsv3_type != NFREG) if (np->nfsv3_type != NFREG)
{ {
ndbg("open eacces typ=%d\n", np->nfsv3_type); fdbg("open eacces typ=%d\n", np->nfsv3_type);
return EACCES; return EACCES;
} }
@ -342,7 +342,7 @@ static int nfs_close(FAR struct file *filep) done
struct nfsnode *np; struct nfsnode *np;
int error = 0; int error = 0;
nvdbg("Closing\n"); fvdbg("Closing\n");
/* Sanity checks */ /* Sanity checks */
@ -384,7 +384,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
int len; int len;
bool eof; bool eof;
nvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos); fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos);
/* Sanity checks */ /* Sanity checks */
@ -405,13 +405,13 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
error = nfs_checkmount(nmp); error = nfs_checkmount(nmp);
if (error != 0) if (error != 0)
{ {
ndbg("nfs_checkmount failed: %d\n", error); fdbg("nfs_checkmount failed: %d\n", error);
goto errout_with_semaphore; goto errout_with_semaphore;
} }
if (np->nfsv3_type != NFREG) if (np->nfsv3_type != NFREG)
{ {
ndbg("read eacces typ=%d\n", np->nfsv3_type); fdbg("read eacces typ=%d\n", np->nfsv3_type);
return EACCES; return EACCES;
} }
@ -604,12 +604,10 @@ static int nfs_opendir(struct inode *mountpt, const char *relpath,
{ {
struct nfsmount *nmp; struct nfsmount *nmp;
struct nfsnode *np; struct nfsnode *np;
struct nfsv3_fsinfo fsp;
struct FS3args attributes;
//struct nfs_dirinfo_s dirinfo; //struct nfs_dirinfo_s dirinfo;
int ret; int ret;
fvdbg("relpath: '%s'\n", relpath); fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
/* Sanity checks */ /* Sanity checks */
@ -632,36 +630,32 @@ static int nfs_opendir(struct inode *mountpt, const char *relpath,
/* The entry is a directory */ /* The entry is a directory */
if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) if (np->nfsv3_type != NFDIR)
{ {
ndbg("open eacces type=%d\n", np->nfsv3_type); fdbg("open eacces type=%d\n", np->nfsv3_type);
nfs_semgive(nmp); nfs_semgive(nmp);
return EACCES; return EACCES;
} }
/* The requested directory must be the volume-relative "root" directory */
if (relpath && relpath[0] != '\0')
{
ret = -ENOENT;
goto errout_with_semaphore;
}
if (np->n_flag & NMODIFIED) if (np->n_flag & NMODIFIED)
{ {
if (np->nfsv3_type == NFDIR) if (np->nfsv3_type == NFDIR)
{ {
np->n_direofoffset = 0; np->n_direofoffset = 0;
dir->u.nfs.nd_direoffset = false; dir->u.nfs.nd_direoffset = 0;
dir->u.nfs.cookie[0] = 0; dir->u.nfs.cookie[0] = 0;
dir->u.nfs.cookie[1] = 0; dir->u.nfs.cookie[1] = 0;
} }
} }
attributes.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
attributes.fsroot.handle = nmp->nm_fh;
ret = nfs_request(nmp, NFSPROC_FSINFO, (FAR const void *)&attributes,
(FAR void *)&fsp);
if (ret)
{
goto errout_with_semaphore;
}
nmp->nm_fattr = fsp.obj_attributes;
nfs_semgive(nmp); nfs_semgive(nmp);
return OK; return OK;
@ -767,7 +761,7 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
* special error -ENOENT * special error -ENOENT
*/ */
ndbg("End of directory\n"); fdbg("End of directory\n");
error = -ENOENT; error = -ENOENT;
} }
@ -790,7 +784,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
bool eof = false; bool eof = false;
//struct nfs_dirent *ndp; //struct nfs_dirent *ndp;
nvdbg("Entry\n"); fvdbg("Entry\n");
/* Sanity checks */ /* Sanity checks */
@ -808,7 +802,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
error = nfs_checkmount(nmp); error = nfs_checkmount(nmp);
if (error != 0) if (error != 0)
{ {
ndbg("nfs_checkmount failed: %d\n", error); fdbg("nfs_checkmount failed: %d\n", error);
goto errout_with_semaphore; goto errout_with_semaphore;
} }
@ -1073,7 +1067,7 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
{ {
while (nfs_connect(nmp)) while (nfs_connect(nmp))
{ {
nvdbg("nfs_args: retrying connect\n"); fvdbg("nfs_args: retrying connect\n");
} }
} }
} }
@ -1090,6 +1084,8 @@ int mountnfs(struct nfs_args *argp, void **handle)
{ {
struct nfsmount *nmp; struct nfsmount *nmp;
struct nfsnode *np; struct nfsnode *np;
struct FS3args getattr;
struct rpc_reply_getattr resok;
int error = 0; int error = 0;
/* Create an instance of the mountpt state structure */ /* Create an instance of the mountpt state structure */
@ -1097,7 +1093,7 @@ int mountnfs(struct nfs_args *argp, void **handle)
nmp = (struct nfsmount *)kzalloc(sizeof(struct nfsmount)); nmp = (struct nfsmount *)kzalloc(sizeof(struct nfsmount));
if (!nmp) if (!nmp)
{ {
ndbg("Failed to allocate mountpoint structure\n"); fdbg("Failed to allocate mountpoint structure\n");
return -ENOMEM; return -ENOMEM;
} }
@ -1147,22 +1143,44 @@ int mountnfs(struct nfs_args *argp, void **handle)
np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode)); np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
if (!np) if (!np)
{ {
ndbg("Failed to allocate private data\n", error); fdbg("Failed to allocate private data\n");
return -ENOMEM; return -ENOMEM;
} }
np->nfsv3_type = NFDIR; np->nfsv3_type = NFDIR;
np->n_open = true; np->n_open = true;
np->n_flag |= NMODIFIED;
nmp->nm_head = np; nmp->nm_head = np;
/* Mounted! */
nmp->nm_mounted = true; nmp->nm_mounted = true;
nmp->nm_fh = nmp->nm_rpcclnt->rc_fh; nmp->nm_fh = nmp->nm_rpcclnt->rc_fh;
nmp->nm_fhsize = NFSX_V2FH; nmp->nm_fhsize = NFSX_V2FH;
nmp->nm_head->n_fhp = nmp->nm_fh; nmp->nm_head->n_fhp = nmp->nm_fh;
nmp->nm_head->n_fhsize = nmp->nm_fhsize; nmp->nm_head->n_fhsize = nmp->nm_fhsize;
nmp->nm_so = nmp->nm_rpcclnt->rc_so; nmp->nm_so = nmp->nm_rpcclnt->rc_so;
memset(&getattr, 0, sizeof(struct FS3args));
memset(&resok, 0, sizeof(struct rpc_reply_getattr));
getattr.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
getattr.fsroot.handle = nmp->nm_fh;
error = nfs_request(nmp, NFSPROC_GETATTR, (FAR const void *)&getattr,
(FAR void*)&resok);
if (error)
{
goto bad;
}
memcpy(&np->n_fattr, &resok, sizeof(struct rpc_reply_getattr));
memcpy(&nmp->nm_fattr, &resok, sizeof(struct rpc_reply_getattr));
fvdbg("value %d \n", sizeof(struct rpc_reply_getattr));
/* fvdbg("type %d \n", fxdr_unsigned(uint32_t, resok.attr.fa_type));
fvdbg("mode %d \n", fxdr_unsigned(uint32_t, resok.attr.fa_mode));
fvdbg("Type %d \n", fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_type));
fvdbg("mode %d \n", fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode));*/
/* Mounted! */
*handle = (void*)nmp; *handle = (void*)nmp;
nfs_semgive(nmp); nfs_semgive(nmp);
@ -1226,7 +1244,7 @@ int nfs_unbind(void *handle, struct inode **blkdriver)
struct nfsmount *nmp = (struct nfsmount *)handle; struct nfsmount *nmp = (struct nfsmount *)handle;
int error; int error;
nvdbg("Entry\n"); fvdbg("Entry\n");
if (!nmp) if (!nmp)
{ {
@ -1238,7 +1256,7 @@ int nfs_unbind(void *handle, struct inode **blkdriver)
error = rpcclnt_umount(nmp->nm_rpcclnt); error = rpcclnt_umount(nmp->nm_rpcclnt);
if (error) if (error)
{ {
ndbg("Umounting fails %d\n", error); fdbg("Umounting fails %d\n", error);
goto bad; goto bad;
} }
@ -1285,7 +1303,7 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
error = nfs_checkmount(nmp); error = nfs_checkmount(nmp);
if (error < 0) if (error < 0)
{ {
ndbg("nfs_checkmount failed: %d\n", error); fdbg("nfs_checkmount failed: %d\n", error);
goto errout_with_semaphore; goto errout_with_semaphore;
} }
@ -1460,8 +1478,8 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
sp.sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); sp.sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);
sp.sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); sp.sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);
memset(&sp.sa_atime, 0, sizeof(nfstime3)); //memset(&sp.sa_atime, 0, sizeof(nfstime3));
memset(&sp.sa_mtime, 0, sizeof(nfstime3)); //memset(&sp.sa_mtime, 0, sizeof(nfstime3));
mkir.attributes = sp; mkir.attributes = sp;
@ -1594,7 +1612,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR)
{ {
ndbg("open eacces typ=%d\n", np->nfsv3_type); fdbg("open eacces typ=%d\n", np->nfsv3_type);
error= -EACCES; error= -EACCES;
goto errout_with_semaphore; goto errout_with_semaphore;
} }
@ -1678,7 +1696,7 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b
goto errout_with_semaphore; goto errout_with_semaphore;
} }
nmp->nm_fattr = fsp.obj_attributes; //nmp->nm_fattr = fsp.obj_attributes;
pref = fxdr_unsigned(uint32_t, fsp.fs_wtpref); pref = fxdr_unsigned(uint32_t, fsp.fs_wtpref);
if (pref < nmp->nm_wsize) if (pref < nmp->nm_wsize)
{ {
@ -1724,13 +1742,13 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b
} }
} }
buf->st_mode = fxdr_hyper(&fsp.obj_attributes.fa_mode); buf->st_mode = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode);
buf->st_size = fxdr_hyper(&fsp.obj_attributes.fa3_size); buf->st_size = fxdr_hyper(&nmp->nm_fattr.fa3_size);
buf->st_blksize = 0; buf->st_blksize = 0;
buf->st_blocks = 0; buf->st_blocks = 0;
buf->st_mtime = fxdr_hyper(&fsp.obj_attributes.fa3_mtime); buf->st_mtime = fxdr_hyper(&nmp->nm_fattr.fa3_mtime);
buf->st_atime = fxdr_hyper(&fsp.obj_attributes.fa3_atime); buf->st_atime = fxdr_hyper(&nmp->nm_fattr.fa3_atime);
buf->st_ctime = fxdr_hyper(&fsp.obj_attributes.fa3_ctime); buf->st_ctime = fxdr_hyper(&nmp->nm_fattr.fa3_ctime);
nmp->nm_flag |= NFSMNT_GOTFSINFO; nmp->nm_flag |= NFSMNT_GOTFSINFO;
errout_with_semaphore: errout_with_semaphore:

View File

@ -378,32 +378,10 @@ struct rpc_call_fs
struct rpc_reply_header struct rpc_reply_header
{ {
uint32_t rp_xid; /* request transaction id */ uint32_t rp_xid; /* request transaction id */
int32_t rp_direction; /* call direction (1) */ uint32_t rp_direction; /* call direction (1) */
uint32_t type; uint32_t type;
struct rpc_auth_info rpc_verfi; struct rpc_auth_info rpc_verfi;
uint32_t status; uint32_t status;
//enum msg_type rp_direction; /* call direction (1) */
//enum reply_stat type;
//enum accept_stat status;
/*
struct
{
uint32_t type;
uint32_t status;
*/
/* used only when reply == RPC_MSGDENIED and status == RPC_AUTHERR */
//uint32_t autherr;
/* rpc mismatch info if reply == RPC_MSGDENIED and status == RPC_MISMATCH */
/*
struct
{
uint32_t low;
uint32_t high;
} mismatch_info;
} stat;
*/
}; };
struct rpc_reply_pmap struct rpc_reply_pmap
@ -478,6 +456,13 @@ struct rpc_reply_fsstat
struct nfs_statfs fsstat; struct nfs_statfs fsstat;
}; };
struct rpc_reply_getattr
{
struct rpc_reply_header rh;
uint32_t status;
struct nfs_fattr attr;
};
/* RPC Client connection context. One allocated on every NFS mount. /* RPC Client connection context. One allocated on every NFS mount.
* Holds RPC specific information for mount. * Holds RPC specific information for mount.
*/ */
@ -532,7 +517,7 @@ struct rpcclnt
/* currently can be RPCAUTH_NULL, RPCAUTH_KERBV4, RPCAUTH_UNIX */ /* currently can be RPCAUTH_NULL, RPCAUTH_KERBV4, RPCAUTH_UNIX */
/* should be kept in XDR form */ /* should be kept in XDR form */
// int rc_authtype; /* Authenticator type */ // int rc_authtype; /* Authenticator type */
#ifdef CONFIG_NFS_UNIX_AUTH #ifdef CONFIG_NFS_UNIX_AUTH
/* RPCAUTH_UNIX*/ /* RPCAUTH_UNIX*/
@ -542,7 +527,7 @@ struct rpcclnt
struct rpc_program *rc_prog; struct rpc_program *rc_prog;
//char *rc_servername; //char *rc_servername;
int rc_proctlen; /* if == 0 then rc_proct == NULL */ int rc_proctlen; /* if == 0 then rc_proct == NULL */
int *rc_proct; int *rc_proct;

View File

@ -100,7 +100,7 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define RPC_RETURN(X) do { nvdbg("returning %d\n", X); return X; } while(0) #define RPC_RETURN(X) do { fvdbg("returning %d\n", X); return X; } while(0)
/* Estimate rto for an nfs rpc sent via. an unreliable datagram. Use the mean /* Estimate rto for an nfs rpc sent via. an unreliable datagram. Use the mean
* and mean deviation of rtt for the appropriate type of rpc for the frequent * and mean deviation of rtt for the appropriate type of rpc for the frequent
@ -366,6 +366,14 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, int procid, int prog,
} }
break; break;
case NFSPROC_GETATTR:
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)call;
error = psock_sendto(so, callmsg, sizeof(*callmsg), flags,
sendnam, sizeof(*sendnam));
}
break;
case NFSPROC_REMOVE: case NFSPROC_REMOVE:
{ {
struct rpc_call_remove *callmsg = (struct rpc_call_remove *)call; struct rpc_call_remove *callmsg = (struct rpc_call_remove *)call;
@ -415,7 +423,7 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, int procid, int prog,
{ {
if (rep != NULL) if (rep != NULL)
{ {
ndbg("rpc send error %d for service %s\n", error, fdbg("rpc send error %d for service %s\n", error,
rep->r_rpcclnt->rc_prog->prog_name); rep->r_rpcclnt->rc_prog->prog_name);
/* Deal with errors for the client side. */ /* Deal with errors for the client side. */
@ -431,7 +439,7 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, int procid, int prog,
} }
else else
{ {
ndbg("rpc service send error %d\n", error); fdbg("rpc service send error %d\n", error);
} }
RPC_RETURN(error); RPC_RETURN(error);
@ -544,7 +552,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (error == 0) if (error == 0)
{ {
ndbg("short receive from rpc server %s\n", fdbg("short receive from rpc server %s\n",
rep->r_rpcclnt->rc_prog->prog_name); rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE; error = EPIPE;
} }
@ -558,7 +566,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (len > RPC_MAXPACKET) if (len > RPC_MAXPACKET)
{ {
ndbg("%s (%d) from rpc server %s\n", fdbg("%s (%d) from rpc server %s\n",
"impossible packet length", "impossible packet length",
len, rep->r_rpcclnt->rc_prog->prog_name); len, rep->r_rpcclnt->rc_prog->prog_name);
error = EFBIG; error = EFBIG;
@ -576,7 +584,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (error == 0) if (error == 0)
{ {
ndbg("short receive from rpc server %s\n", fdbg("short receive from rpc server %s\n",
rep->r_rpcclnt->rc_prog->prog_name); rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE; error = EPIPE;
} }
@ -613,7 +621,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if ((rcvflg & MSG_EOR) == 0) if ((rcvflg & MSG_EOR) == 0)
{ {
ndbg("Egad!!\n"); fdbg("Egad!!\n");
} }
if (error == 0) if (error == 0)
@ -627,7 +635,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
{ {
if (error != EPIPE) if (error != EPIPE)
{ {
ndbg("receive error %d from rpc server %s\n", fdbg("receive error %d from rpc server %s\n",
error, rep->r_rpcclnt->rc_prog->prog_name); error, rep->r_rpcclnt->rc_prog->prog_name);
} }
@ -719,7 +727,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
case NFSPROC_READDIR: case NFSPROC_READDIR:
{ {
struct rpc_reply_readdir *replymsg = (struct rpc_reply_readdir *)reply; struct rpc_reply_readdir *replymsg = (struct rpc_reply_readdir *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg, error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen); aname, &fromlen);
} }
break; break;
@ -732,6 +740,14 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
} }
break; break;
case NFSPROC_GETATTR:
{
struct rpc_reply_getattr *replymsg = (struct rpc_reply_getattr *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_REMOVE: case NFSPROC_REMOVE:
{ {
struct rpc_reply_remove *replymsg = (struct rpc_reply_remove *)reply; struct rpc_reply_remove *replymsg = (struct rpc_reply_remove *)reply;
@ -777,7 +793,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
} }
} }
nvdbg("psock_recvfrom returns %d\n", error); fvdbg("psock_recvfrom returns %d\n", error);
if (error > 0) if (error > 0)
{ {
RPC_RETURN(0); RPC_RETURN(0);
@ -839,7 +855,7 @@ static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *repl
RPC_RETURN(0); RPC_RETURN(0);
} }
ndbg("ignoring routing error on connectionless protocol."); fdbg("ignoring routing error on connectionless protocol.");
continue; continue;
} }
RPC_RETURN(error); RPC_RETURN(error);
@ -926,7 +942,7 @@ static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *repl
if (rep == 0) if (rep == 0)
{ {
ndbg("rpc reply not matched\n"); fdbg("rpc reply not matched\n");
rpcstats.rpcunexpected++; rpcstats.rpcunexpected++;
RPC_RETURN(ENOMSG); RPC_RETURN(ENOMSG);
} }
@ -1156,7 +1172,7 @@ void rpcclnt_init(void)
//rpcclnt_timer(NULL, callmgs); //rpcclnt_timer(NULL, callmgs);
nvdbg("rpc initialized\n"); fvdbg("rpc initialized\n");
return; return;
} }
@ -1164,7 +1180,7 @@ void rpcclnt_init(void)
void void
rpcclnt_uninit(void) rpcclnt_uninit(void)
{ {
nvdbg("uninit"); fvdbg("uninit");
untimeout(rpcclnt_timer, (void *)NULL, rpcclnt_timer_handle); untimeout(rpcclnt_timer, (void *)NULL, rpcclnt_timer_handle);
} }
*/ */
@ -1197,14 +1213,14 @@ int rpcclnt_connect(struct rpcclnt *rpc)
so = (struct socket *)kzalloc(sizeof(struct socket)); so = (struct socket *)kzalloc(sizeof(struct socket));
if (!so) if (!so)
{ {
ndbg("Failed to allocate socket structure\n"); fdbg("Failed to allocate socket structure\n");
return -ENOMEM; return -ENOMEM;
} }
error = psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, so); error = psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, so);
if (error != 0) if (error != 0)
{ {
ndbg("error %d in psock_socket()", error); fdbg("error %d in psock_socket()", error);
RPC_RETURN(error); RPC_RETURN(error);
} }
@ -1245,7 +1261,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
if (error) if (error)
{ {
ndbg("bind failed\n"); fdbg("bind failed\n");
goto bad; goto bad;
} }
@ -1267,7 +1283,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
if (error) if (error)
{ {
ndbg("psock_connect to PMAP port returns %d", error); fdbg("psock_connect to PMAP port returns %d", error);
goto bad; goto bad;
} }
@ -1283,7 +1299,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
sdata.port = 0; sdata.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(void *)&rdata, (FAR const void *)&sdata); (FAR void *)&rdata, (FAR const void *)&sdata);
if (error != 0) if (error != 0)
{ {
goto bad; goto bad;
@ -1295,7 +1311,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
ndbg("psock_connect MOUNTD port returns %d\n", error); fdbg("psock_connect MOUNTD port returns %d\n", error);
goto bad; goto bad;
} }
@ -1307,7 +1323,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
mountd.len = txdr_unsigned(sizeof(mountd.rpath)); mountd.len = txdr_unsigned(sizeof(mountd.rpath));
error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1, error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1,
(void *)&mdata, (FAR const void *)&mountd); (FAR void *)&mdata, (FAR const void *)&mountd);
if (error != 0) if (error != 0)
{ {
goto bad; goto bad;
@ -1316,7 +1332,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
error = fxdr_unsigned(uint32_t, mdata.mount.status); error = fxdr_unsigned(uint32_t, mdata.mount.status);
if (error != 0) if (error != 0)
{ {
ndbg("error mounting with the server %d\n", error); fdbg("error mounting with the server %d\n", error);
goto bad; goto bad;
} }
@ -1333,7 +1349,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
ndbg("psock_connect PMAP port returns %d\n", error); fdbg("psock_connect PMAP port returns %d\n", error);
goto bad; goto bad;
} }
@ -1343,7 +1359,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
sdata.port = 0; sdata.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(void *)&rdata, (FAR const void *)&sdata); (FAR void *)&rdata, (FAR const void *)&sdata);
if (error != 0) if (error != 0)
{ {
goto bad; goto bad;
@ -1354,7 +1370,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
ndbg("psock_connect NFS port returns %d\n", error); fdbg("psock_connect NFS port returns %d\n", error);
goto bad; goto bad;
} }
} }
@ -1449,7 +1465,7 @@ int rpcclnt_umount(struct rpcclnt *rpc)
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
ndbg("psock_connect MOUNTD port returns %d\n", error); fdbg("psock_connect MOUNTD port returns %d\n", error);
goto bad; goto bad;
} }
@ -1470,7 +1486,7 @@ int rpcclnt_umount(struct rpcclnt *rpc)
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
ndbg("psock_connect MOUNTD port returns %d\n", error); fdbg("psock_connect MOUNTD port returns %d\n", error);
goto bad; goto bad;
} }
@ -1491,7 +1507,7 @@ int rpcclnt_umount(struct rpcclnt *rpc)
if ((fxdr_unsigned(uint32_t, mdata.mount.status)) != 0) if ((fxdr_unsigned(uint32_t, mdata.mount.status)) != 0)
{ {
ndbg("error unmounting with the server %d\n", error); fdbg("error unmounting with the server %d\n", error);
goto bad; goto bad;
} }
@ -1546,7 +1562,6 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
void *msgcall = NULL; void *msgcall = NULL;
int error = 0; int error = 0;
//memset(&replyheader, 0, sizeof(replyheader));
if (prog == PMAPPROG) if (prog == PMAPPROG)
{ {
@ -1641,6 +1656,13 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
} }
break; break;
case NFSPROC_GETATTR:
{
memset(&fs, 0, sizeof(struct rpc_call_fs));
msgcall = &fs;
}
break;
case NFSPROC_FSINFO: case NFSPROC_FSINFO:
{ {
memset(&fs, 0, sizeof(struct rpc_call_fs)); memset(&fs, 0, sizeof(struct rpc_call_fs));
@ -1661,14 +1683,14 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
task = (struct rpctask *)kzalloc(sizeof(struct rpctask)); task = (struct rpctask *)kzalloc(sizeof(struct rpctask));
if (!task) if (!task)
{ {
ndbg("Failed to allocate reply msg structure\n"); fdbg("Failed to allocate reply msg structure\n");
return -ENOMEM; return -ENOMEM;
} }
error = rpcclnt_buildheader(rpc, procnum, prog, version, &value, datain, msgcall); error = rpcclnt_buildheader(rpc, procnum, prog, version, &value, datain, msgcall);
if (error) if (error)
{ {
ndbg("building call header error"); fdbg("building call header error");
goto rpcmout; goto rpcmout;
} }
@ -1751,7 +1773,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
{ {
error = rpcclnt_reply(task, procnum, prog, dataout); error = rpcclnt_reply(task, procnum, prog, dataout);
} }
nvdbg("out for reply %d\n", error); fvdbg("out for reply %d\n", error);
/* RPC done, unlink the request. */ /* RPC done, unlink the request. */
@ -1784,14 +1806,14 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
/*replymgs.stat.mismatch_info.low = /*replymgs.stat.mismatch_info.low =
fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.low); fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.low);
replymgs.stat.mismatch_info.high = replymgs.stat.mismatch_info.high =
fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.high); fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.high);*/
ndbg("RPC_MSGDENIED: RPC_MISMATCH error");*/ fdbg("RPC_MSGDENIED: RPC_MISMATCH error");
error = EOPNOTSUPP; error = EOPNOTSUPP;
break; break;
case RPC_AUTHERR: case RPC_AUTHERR:
//replymgs.stat.autherr = fxdr_unsigned(uint32_t, replyheader.stat.autherr); //replymgs.stat.autherr = fxdr_unsigned(uint32_t, replyheader.stat.autherr);
ndbg("RPC_MSGDENIED: RPC_AUTHERR error\n"); fdbg("RPC_MSGDENIED: RPC_AUTHERR error\n");
error = EACCES; error = EACCES;
break; break;
@ -1816,7 +1838,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
if (replymgs.status == RPC_SUCCESS) if (replymgs.status == RPC_SUCCESS)
{ {
nvdbg("RPC_SUCCESS\n"); fvdbg("RPC_SUCCESS\n");
} }
else if (replymgs.status == RPC_PROGMISMATCH) else if (replymgs.status == RPC_PROGMISMATCH)
{ {
@ -1825,7 +1847,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
replymgs.stat.mismatch_info.high = replymgs.stat.mismatch_info.high =
fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.high);*/ fxdr_unsigned(uint32_t, replyheader.stat.mismatch_info.high);*/
ndbg("RPC_MSGACCEPTED: RPC_PROGMISMATCH error\n"); fdbg("RPC_MSGACCEPTED: RPC_PROGMISMATCH error\n");
error = EOPNOTSUPP; error = EOPNOTSUPP;
} }
else if (replymgs.status > 5) else if (replymgs.status > 5)
@ -1895,7 +1917,7 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
if ((rep->r_flags & TASK_TPRINTFMSG) == 0 && if ((rep->r_flags & TASK_TPRINTFMSG) == 0 &&
rep->r_rexmit > rpc->rc_deadthresh) rep->r_rexmit > rpc->rc_deadthresh)
{ {
ndbg("Server is not responding\n"); fdbg("Server is not responding\n");
rep->r_flags |= TASK_TPRINTFMSG; rep->r_flags |= TASK_TPRINTFMSG;
} }
@ -2306,6 +2328,37 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
callmsg->ch.rpc_auth.authtype = rpc_auth_null; callmsg->ch.rpc_auth.authtype = rpc_auth_null;
//call->rpc_auth.authlen = 0; //call->rpc_auth.authlen = 0;
#ifdef CONFIG_NFS_UNIX_AUTH
callmsg->ch.rpc_unix.stamp = txdr_unsigned(1);
callmsg->ch.rpc_unix.hostname = 0;
callmsg->ch.rpc_unix.uid = setuid;
callmsg->ch.rpc_unix.gid = setgid;
callmsg->ch.rpc_unix.gidlist = 0;
#endif
/* rpc_verf part (auth_null) */
callmsg->ch.rpc_verf.authtype = rpc_auth_null;
//call->rpc_verf.authlen = 0;
return 0;
}
case NFSPROC_GETATTR:
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
bcopy(datain, &callmsg->fs, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
callmsg->ch.rp_prog = txdr_unsigned(prog);
callmsg->ch.rp_vers = txdr_unsigned(vers);
callmsg->ch.rp_proc = txdr_unsigned(procid);
/* rpc_auth part (auth_unix as root) */
callmsg->ch.rpc_auth.authtype = rpc_auth_null;
//call->rpc_auth.authlen = 0;
#ifdef CONFIG_NFS_UNIX_AUTH #ifdef CONFIG_NFS_UNIX_AUTH
callmsg->ch.rpc_unix.stamp = txdr_unsigned(1); callmsg->ch.rpc_unix.stamp = txdr_unsigned(1);
callmsg->ch.rpc_unix.hostname = 0; callmsg->ch.rpc_unix.hostname = 0;