vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| On Mon, 27 Mar 2006, rick@snowhite.cis.uoguelph.ca wrote: > Ok, I took a look at the tcpdump and it does seem weird. OpenBSD is > returning EPERM for a setattr of mtime, when the client user does have > write permission for the file. > > Looking at the OpenBSD3.8 code, the only thing I can see that would do > this is if the IMMUTABLE flag was set on the file system? > > Otherwise, I think it must be caused by some post 3.8 change, assuming > that the server file system is ufs. > (Normally, the errors generated would be EROFS or EACCES, not EPERM.) I think the issue is that the v3 setattr timestamp NFSV3SATTRTIME_TOSERVER is governed by the same rectrictions as a setattr timestamp TOCLIENT. I would expect TOSERVER (which means "set timestamp to current server time", i.e. exactly what utimes(NULL) does), to be allowed if we have write permission to the file. I checked Solaris and Linux NFS v3 code, and both implement exactly that. To demonstrate what I mean, here's an ugly diff, which makes the access check of setattr TOSERVER behave like utimes(NULL). Han, could you try this on your server? If it works, we at least know a bit more what is going on. My touch(1) test case which i posted earlier is resolved by this. -Otto PS: my earlier comments about time coherency on linux only applies to NFS v2. Index: nfs_serv.c ================================================== ================= RCS file: /cvs/src/sys/nfs/nfs_serv.c,v retrieving revision 1.39 diff -u -p -r1.39 nfs_serv.c --- nfs_serv.c 18 Jun 2005 18:09:43 -0000 1.39 +++ nfs_serv.c 27 Mar 2006 18:43:57 -0000 @@ -224,6 +224,7 @@ nfsrv_setattr(nfsd, slp, procp, mrq) caddr_t bpos; int error = 0, rdonly, preat_ret = 1, postat_ret = 1; int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0; + int toserver; char *cp2; struct mbuf *mb, *mb2, *mreq; u_quad_t frev; @@ -233,7 +234,7 @@ nfsrv_setattr(nfsd, slp, procp, mrq) nfsm_srvmtofh(fhp); VATTR_NULL(&va); if (v3) { - nfsm_srvsattr(&va); + nfsm_srvsattr(&va, toserver); nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); gcheck = fxdr_unsigned(int, *tl); if (gcheck) { @@ -312,6 +313,8 @@ nfsrv_setattr(nfsd, slp, procp, mrq) procp, 0)) != 0) goto out; } + if (toserver == 2) + va.va_vaflags |= VA_UTIMES_NULL; error = VOP_SETATTR(vp, &va, cred, procp); postat_ret = VOP_GETATTR(vp, &va, cred, procp); if (!error) @@ -1280,6 +1283,8 @@ nfsrv_create(nfsd, slp, procp, mrq) } VATTR_NULL(&va); if (v3) { + int toserver; + nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); how = fxdr_unsigned(int, *tl); switch (how) { @@ -1289,7 +1294,7 @@ nfsrv_create(nfsd, slp, procp, mrq) break; } case NFSV3CREATE_UNCHECKED: - nfsm_srvsattr(&va); + nfsm_srvsattr(&va, toserver); break; case NFSV3CREATE_EXCLUSIVE: nfsm_dissect(cp, caddr_t, NFSX_V3CREATEVERF); @@ -1479,6 +1484,7 @@ nfsrv_mknod(nfsd, slp, procp, mrq) int32_t t1; caddr_t bpos; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; + int toserver; u_int32_t major, minor; enum vtype vtyp; char *cp2; @@ -1517,7 +1523,7 @@ nfsrv_mknod(nfsd, slp, procp, mrq) goto out; } VATTR_NULL(&va); - nfsm_srvsattr(&va); + nfsm_srvsattr(&va, toserver); if (vtyp == VCHR || vtyp == VBLK) { nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); major = fxdr_unsigned(u_int32_t, *tl++); @@ -2018,8 +2024,10 @@ nfsrv_symlink(nfsd, slp, procp, mrq) if (error) goto out; VATTR_NULL(&va); - if (v3) - nfsm_srvsattr(&va); + if (v3) { + int toserver; + nfsm_srvsattr(&va, toserver); + } nfsm_strsiz(len2, NFS_MAXPATHLEN); MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK); iv.iov_base = pathcp; @@ -2164,7 +2172,8 @@ nfsrv_mkdir(nfsd, slp, procp, mrq) } VATTR_NULL(&va); if (v3) { - nfsm_srvsattr(&va); + int toserver; + nfsm_srvsattr(&va, toserver); } else { nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); va.va_mode = nfstov_mode(*tl++); Index: nfsm_subs.h ================================================== ================= RCS file: /cvs/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.15 diff -u -p -r1.15 nfsm_subs.h --- nfsm_subs.h 24 Jun 2004 19:35:26 -0000 1.15 +++ nfsm_subs.h 27 Mar 2006 18:43:57 -0000 @@ -443,7 +443,7 @@ #define nfsm_srvpostop_attr(r, a) \ nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos) -#define nfsm_srvsattr(a) \ +#define nfsm_srvsattr(a, toserver) \ { nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ if (*tl == nfs_true) { \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ @@ -464,6 +464,7 @@ nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ (a)->va_size = fxdr_hyper(tl); \ } \ + (toserver) = 0; \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ switch (fxdr_unsigned(int, *tl)) { \ case NFSV3SATTRTIME_TOCLIENT: \ @@ -471,6 +472,7 @@ fxdr_nfsv3time(tl, &(a)->va_atime); \ break; \ case NFSV3SATTRTIME_TOSERVER: \ + (toserver)++; \ getnanotime(&(a)->va_atime); \ break; \ }; \ @@ -481,6 +483,7 @@ fxdr_nfsv3time(tl, &(a)->va_mtime); \ break; \ case NFSV3SATTRTIME_TOSERVER: \ + (toserver)++; \ getnanotime(&(a)->va_mtime); \ break; \ }; } |