* [PATCH 000 of 5] knfsd: Introduction - Assorted bugfixes
@ 2007-01-23 0:22 ` NeilBrown
0 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Following are 5 patches for kNFSd suitable for inclusion in 2.6.20.
A couple should go to 2.6.19-stable, but I'll send those separately.
NeilBrown
[PATCH 001 of 5] knfsd: Update email address and status for NFSD in MAINTAINERS.
[PATCH 002 of 5] knfsd: Fix setting of ACL server versions.
[PATCH 003 of 5] knfsd: Fix an NFSD bug with full sized, non-page-aligned reads.
[PATCH 004 of 5] knfsd: Replace some warning ins nfsfh.h with BUG_ON or WARN_ON
[PATCH 005 of 5] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 001 of 5] knfsd: Update email address and status for NFSD in MAINTAINERS.
2007-01-23 0:22 ` NeilBrown
@ 2007-01-23 0:22 ` NeilBrown
-1 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./MAINTAINERS | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff .prev/MAINTAINERS ./MAINTAINERS
--- .prev/MAINTAINERS 2007-01-23 11:13:46.000000000 +1100
+++ ./MAINTAINERS 2007-01-23 11:14:14.000000000 +1100
@@ -1941,11 +1941,10 @@ S: Maintained
KERNEL NFSD
P: Neil Brown
-M: neilb@cse.unsw.edu.au
+M: neilb@suse.de
L: nfs@lists.sourceforge.net
W: http://nfs.sourceforge.net/
-W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
-S: Maintained
+S: Supported
KERNEL VIRTUAL MACHINE (KVM)
P: Avi Kivity
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 002 of 5] knfsd: Fix setting of ACL server versions.
2007-01-23 0:22 ` NeilBrown
@ 2007-01-23 0:22 ` NeilBrown
-1 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Due to silly typos, if the nfs versions are explicitly set,
no NFSACL versions get enabled.
Also improve an error message that would have made this bug
a little easier to find.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/nfssvc.c | 8 ++++----
./net/sunrpc/svc.c | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c 2007-01-23 11:13:46.000000000 +1100
+++ ./fs/nfsd/nfssvc.c 2007-01-23 11:14:49.000000000 +1100
@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_progr
.pg_prog = NFS_ACL_PROGRAM,
.pg_nvers = NFSD_ACL_NRVERS,
.pg_vers = nfsd_acl_versions,
- .pg_name = "nfsd",
+ .pg_name = "nfsacl",
.pg_class = "nfsd",
.pg_stats = &nfsd_acl_svcstats,
.pg_authenticate = &svc_set_client,
@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op cha
switch(change) {
case NFSD_SET:
nfsd_versions[vers] = nfsd_version[vers];
- break;
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
if (vers < NFSD_ACL_NRVERS)
- nfsd_acl_version[vers] = nfsd_acl_version[vers];
+ nfsd_acl_versions[vers] = nfsd_acl_version[vers];
#endif
+ break;
case NFSD_CLEAR:
nfsd_versions[vers] = NULL;
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
if (vers < NFSD_ACL_NRVERS)
- nfsd_acl_version[vers] = NULL;
+ nfsd_acl_versions[vers] = NULL;
#endif
break;
case NFSD_TEST:
diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c 2007-01-23 11:13:46.000000000 +1100
+++ ./net/sunrpc/svc.c 2007-01-23 11:14:49.000000000 +1100
@@ -910,7 +910,8 @@ err_bad_prog:
err_bad_vers:
#ifdef RPC_PARANOIA
- printk("svc: unknown version (%d)\n", vers);
+ printk("svc: unknown version (%d for prog %d, %s)\n",
+ vers, prog, progp->pg_name);
#endif
serv->sv_stats->rpcbadfmt++;
svc_putnl(resv, RPC_PROG_MISMATCH);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 002 of 5] knfsd: Fix setting of ACL server versions.
@ 2007-01-23 0:22 ` NeilBrown
0 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
Due to silly typos, if the nfs versions are explicitly set,
no NFSACL versions get enabled.
Also improve an error message that would have made this bug
a little easier to find.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/nfssvc.c | 8 ++++----
./net/sunrpc/svc.c | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c 2007-01-23 11:13:46.000000000 +1100
+++ ./fs/nfsd/nfssvc.c 2007-01-23 11:14:49.000000000 +1100
@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_progr
.pg_prog = NFS_ACL_PROGRAM,
.pg_nvers = NFSD_ACL_NRVERS,
.pg_vers = nfsd_acl_versions,
- .pg_name = "nfsd",
+ .pg_name = "nfsacl",
.pg_class = "nfsd",
.pg_stats = &nfsd_acl_svcstats,
.pg_authenticate = &svc_set_client,
@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op cha
switch(change) {
case NFSD_SET:
nfsd_versions[vers] = nfsd_version[vers];
- break;
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
if (vers < NFSD_ACL_NRVERS)
- nfsd_acl_version[vers] = nfsd_acl_version[vers];
+ nfsd_acl_versions[vers] = nfsd_acl_version[vers];
#endif
+ break;
case NFSD_CLEAR:
nfsd_versions[vers] = NULL;
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
if (vers < NFSD_ACL_NRVERS)
- nfsd_acl_version[vers] = NULL;
+ nfsd_acl_versions[vers] = NULL;
#endif
break;
case NFSD_TEST:
diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c 2007-01-23 11:13:46.000000000 +1100
+++ ./net/sunrpc/svc.c 2007-01-23 11:14:49.000000000 +1100
@@ -910,7 +910,8 @@ err_bad_prog:
err_bad_vers:
#ifdef RPC_PARANOIA
- printk("svc: unknown version (%d)\n", vers);
+ printk("svc: unknown version (%d for prog %d, %s)\n",
+ vers, prog, progp->pg_name);
#endif
serv->sv_stats->rpcbadfmt++;
svc_putnl(resv, RPC_PROG_MISMATCH);
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 003 of 5] knfsd: Fix an NFSD bug with full sized, non-page-aligned reads.
2007-01-23 0:22 ` NeilBrown
@ 2007-01-23 0:22 ` NeilBrown
-1 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
NFSd assumes that largest number of pages that will be needed
for a request+response is 2+N where N pages is the size of the largest
permitted read/write request. The '2' are 1 for the non-data part of
the request, and 1 for the non-data part of the reply.
However, when a read request is not page-aligned, and we choose to use
->sendfile to send it directly from the page cache, we may need N+1
pages to hold the whole reply. This can overflow and array and cause
an Oops.
This patch increases size of the array for holding pages by one and
makes sure that entry is NULL when it is not in use.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/vfs.c | 3 ++-
./include/linux/sunrpc/svc.h | 5 ++++-
./net/sunrpc/svcsock.c | 2 ++
3 files changed, 8 insertions(+), 2 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2007-01-23 11:13:45.000000000 +1100
+++ ./fs/nfsd/vfs.c 2007-01-23 11:14:54.000000000 +1100
@@ -822,7 +822,8 @@ nfsd_read_actor(read_descriptor_t *desc,
rqstp->rq_res.page_len = size;
} else if (page != pp[-1]) {
get_page(page);
- put_page(*pp);
+ if (*pp)
+ put_page(*pp);
*pp = page;
rqstp->rq_resused++;
rqstp->rq_res.page_len += size;
diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h 2007-01-23 11:13:45.000000000 +1100
+++ ./include/linux/sunrpc/svc.h 2007-01-23 11:14:54.000000000 +1100
@@ -144,8 +144,11 @@ extern u32 svc_max_payload(const struct
*
* Each request/reply pair can have at most one "payload", plus two pages,
* one for the request, and one for the reply.
+ * We using ->sendfile to return read data, we might need one extra page
+ * if the request is not page-aligned. So add another '1'.
*/
-#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
+#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \
+ + 2 + 1)
static inline u32 svc_getnl(struct kvec *iov)
{
diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c 2007-01-23 11:13:45.000000000 +1100
+++ ./net/sunrpc/svcsock.c 2007-01-23 11:14:54.000000000 +1100
@@ -1306,6 +1306,8 @@ svc_recv(struct svc_rqst *rqstp, long ti
schedule_timeout_uninterruptible(msecs_to_jiffies(500));
rqstp->rq_pages[i] = p;
}
+ rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */
+ BUG_ON(pages >= RPCSVC_MAXPAGES);
/* Make arg->head point to first page and arg->pages point to rest */
arg = &rqstp->rq_arg;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 003 of 5] knfsd: Fix an NFSD bug with full sized, non-page-aligned reads.
@ 2007-01-23 0:22 ` NeilBrown
0 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel
NFSd assumes that largest number of pages that will be needed
for a request+response is 2+N where N pages is the size of the largest
permitted read/write request. The '2' are 1 for the non-data part of
the request, and 1 for the non-data part of the reply.
However, when a read request is not page-aligned, and we choose to use
->sendfile to send it directly from the page cache, we may need N+1
pages to hold the whole reply. This can overflow and array and cause
an Oops.
This patch increases size of the array for holding pages by one and
makes sure that entry is NULL when it is not in use.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/vfs.c | 3 ++-
./include/linux/sunrpc/svc.h | 5 ++++-
./net/sunrpc/svcsock.c | 2 ++
3 files changed, 8 insertions(+), 2 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2007-01-23 11:13:45.000000000 +1100
+++ ./fs/nfsd/vfs.c 2007-01-23 11:14:54.000000000 +1100
@@ -822,7 +822,8 @@ nfsd_read_actor(read_descriptor_t *desc,
rqstp->rq_res.page_len = size;
} else if (page != pp[-1]) {
get_page(page);
- put_page(*pp);
+ if (*pp)
+ put_page(*pp);
*pp = page;
rqstp->rq_resused++;
rqstp->rq_res.page_len += size;
diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h 2007-01-23 11:13:45.000000000 +1100
+++ ./include/linux/sunrpc/svc.h 2007-01-23 11:14:54.000000000 +1100
@@ -144,8 +144,11 @@ extern u32 svc_max_payload(const struct
*
* Each request/reply pair can have at most one "payload", plus two pages,
* one for the request, and one for the reply.
+ * We using ->sendfile to return read data, we might need one extra page
+ * if the request is not page-aligned. So add another '1'.
*/
-#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
+#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \
+ + 2 + 1)
static inline u32 svc_getnl(struct kvec *iov)
{
diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c 2007-01-23 11:13:45.000000000 +1100
+++ ./net/sunrpc/svcsock.c 2007-01-23 11:14:54.000000000 +1100
@@ -1306,6 +1306,8 @@ svc_recv(struct svc_rqst *rqstp, long ti
schedule_timeout_uninterruptible(msecs_to_jiffies(500));
rqstp->rq_pages[i] = p;
}
+ rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */
+ BUG_ON(pages >= RPCSVC_MAXPAGES);
/* Make arg->head point to first page and arg->pages point to rest */
arg = &rqstp->rq_arg;
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 004 of 5] knfsd: Replace some warning ins nfsfh.h with BUG_ON or WARN_ON
2007-01-23 0:22 ` NeilBrown
@ 2007-01-23 0:22 ` NeilBrown
-1 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel, Adrian Bunk
A couple of the warning will be followed by an Oops if they ever fire,
so may as well be BUG_ON. Another isn't obviously fatal but has never
been known to fire, so make it a WARN_ON.
Cc: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./include/linux/nfsd/nfsfh.h | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff .prev/include/linux/nfsd/nfsfh.h ./include/linux/nfsd/nfsfh.h
--- .prev/include/linux/nfsd/nfsfh.h 2007-01-23 11:13:44.000000000 +1100
+++ ./include/linux/nfsd/nfsfh.h 2007-01-23 11:15:00.000000000 +1100
@@ -217,11 +217,7 @@ void fh_put(struct svc_fh *);
static __inline__ struct svc_fh *
fh_copy(struct svc_fh *dst, struct svc_fh *src)
{
- if (src->fh_dentry || src->fh_locked) {
- struct dentry *dentry = src->fh_dentry;
- printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
- }
+ WARN_ON(src->fh_dentry || src->fh_locked);
*dst = *src;
return dst;
@@ -300,10 +296,8 @@ fh_lock_nested(struct svc_fh *fhp, unsig
dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
SVCFH_fmt(fhp), fhp->fh_locked);
- if (!fhp->fh_dentry) {
- printk(KERN_ERR "fh_lock: fh not verified!\n");
- return;
- }
+ BUG_ON(!dentry);
+
if (fhp->fh_locked) {
printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -328,8 +322,7 @@ fh_lock(struct svc_fh *fhp)
static inline void
fh_unlock(struct svc_fh *fhp)
{
- if (!fhp->fh_dentry)
- printk(KERN_ERR "fh_unlock: fh not verified!\n");
+ BUG_ON(!fhp->fh_dentry);
if (fhp->fh_locked) {
fill_post_wcc(fhp);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 004 of 5] knfsd: Replace some warning ins nfsfh.h with BUG_ON or WARN_ON
@ 2007-01-23 0:22 ` NeilBrown
0 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel, Adrian Bunk
A couple of the warning will be followed by an Oops if they ever fire,
so may as well be BUG_ON. Another isn't obviously fatal but has never
been known to fire, so make it a WARN_ON.
Cc: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./include/linux/nfsd/nfsfh.h | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff .prev/include/linux/nfsd/nfsfh.h ./include/linux/nfsd/nfsfh.h
--- .prev/include/linux/nfsd/nfsfh.h 2007-01-23 11:13:44.000000000 +1100
+++ ./include/linux/nfsd/nfsfh.h 2007-01-23 11:15:00.000000000 +1100
@@ -217,11 +217,7 @@ void fh_put(struct svc_fh *);
static __inline__ struct svc_fh *
fh_copy(struct svc_fh *dst, struct svc_fh *src)
{
- if (src->fh_dentry || src->fh_locked) {
- struct dentry *dentry = src->fh_dentry;
- printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
- }
+ WARN_ON(src->fh_dentry || src->fh_locked);
*dst = *src;
return dst;
@@ -300,10 +296,8 @@ fh_lock_nested(struct svc_fh *fhp, unsig
dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
SVCFH_fmt(fhp), fhp->fh_locked);
- if (!fhp->fh_dentry) {
- printk(KERN_ERR "fh_lock: fh not verified!\n");
- return;
- }
+ BUG_ON(!dentry);
+
if (fhp->fh_locked) {
printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -328,8 +322,7 @@ fh_lock(struct svc_fh *fhp)
static inline void
fh_unlock(struct svc_fh *fhp)
{
- if (!fhp->fh_dentry)
- printk(KERN_ERR "fh_unlock: fh not verified!\n");
+ BUG_ON(!fhp->fh_dentry);
if (fhp->fh_locked) {
fill_post_wcc(fhp);
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 005 of 5] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
2007-01-23 0:22 ` NeilBrown
@ 2007-01-23 0:22 ` NeilBrown
-1 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: Peter Staubach, nfs, linux-kernel
From: Peter Staubach <staubach@redhat.com>
NFS V3 (and V4) support exclusive create by passing a 'cookie' which
can get stored with the file. If the file exists but has exactly the
right cookie stored, then we assume this is a retransmit and the
exclusive create was successful.
The cookie is 64bits and is traditionally stored in the mtime and
atime fields. This causes a problem with Solaris7 as negative mtime
or atime confuse it. So we moved two bits into the mode word instead.
But inherited ACLs sometimes overwrite the mode word on create, so
this is a problem.
So we give up and just store 62 of the 64 bits and assume that is
close enough.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/vfs.c | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2007-01-23 11:14:54.000000000 +1100
+++ ./fs/nfsd/vfs.c 2007-01-23 11:15:06.000000000 +1100
@@ -1249,7 +1249,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
__be32 err;
int host_err;
__u32 v_mtime=0, v_atime=0;
- int v_mode=0;
err = nfserr_perm;
if (!flen)
@@ -1286,16 +1285,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
goto out;
if (createmode == NFS3_CREATE_EXCLUSIVE) {
- /* while the verifier would fit in mtime+atime,
- * solaris7 gets confused (bugid 4218508) if these have
- * the high bit set, so we use the mode as well
+ /* solaris7 gets confused (bugid 4218508) if these have
+ * the high bit set, so just clear the high bits.
*/
v_mtime = verifier[0]&0x7fffffff;
v_atime = verifier[1]&0x7fffffff;
- v_mode = S_IFREG
- | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
- | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
- ;
}
if (dchild->d_inode) {
@@ -1323,7 +1317,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
case NFS3_CREATE_EXCLUSIVE:
if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
&& dchild->d_inode->i_atime.tv_sec == v_atime
- && dchild->d_inode->i_mode == v_mode
&& dchild->d_inode->i_size == 0 )
break;
/* fallthru */
@@ -1345,26 +1338,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
}
if (createmode == NFS3_CREATE_EXCLUSIVE) {
- /* Cram the verifier into atime/mtime/mode */
+ /* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME
- | ATTR_MTIME_SET|ATTR_ATIME_SET
- | ATTR_MODE;
+ | ATTR_MTIME_SET|ATTR_ATIME_SET;
/* XXX someone who knows this better please fix it for nsec */
iap->ia_mtime.tv_sec = v_mtime;
iap->ia_atime.tv_sec = v_atime;
iap->ia_mtime.tv_nsec = 0;
iap->ia_atime.tv_nsec = 0;
- iap->ia_mode = v_mode;
}
/* Set file attributes.
- * Mode has already been set but we might need to reset it
- * for CREATE_EXCLUSIVE
* Irix appears to send along the gid when it tries to
* implement setgid directories via NFS. Clear out all that cruft.
*/
set_attr:
- if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
+ if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
__be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
if (err2)
err = err2;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 005 of 5] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
@ 2007-01-23 0:22 ` NeilBrown
0 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2007-01-23 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nfs, linux-kernel, Peter Staubach
From: Peter Staubach <staubach@redhat.com>
NFS V3 (and V4) support exclusive create by passing a 'cookie' which
can get stored with the file. If the file exists but has exactly the
right cookie stored, then we assume this is a retransmit and the
exclusive create was successful.
The cookie is 64bits and is traditionally stored in the mtime and
atime fields. This causes a problem with Solaris7 as negative mtime
or atime confuse it. So we moved two bits into the mode word instead.
But inherited ACLs sometimes overwrite the mode word on create, so
this is a problem.
So we give up and just store 62 of the 64 bits and assume that is
close enough.
Signed-off-by: Neil Brown <neilb@suse.de>
### Diffstat output
./fs/nfsd/vfs.c | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c 2007-01-23 11:14:54.000000000 +1100
+++ ./fs/nfsd/vfs.c 2007-01-23 11:15:06.000000000 +1100
@@ -1249,7 +1249,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
__be32 err;
int host_err;
__u32 v_mtime=0, v_atime=0;
- int v_mode=0;
err = nfserr_perm;
if (!flen)
@@ -1286,16 +1285,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
goto out;
if (createmode == NFS3_CREATE_EXCLUSIVE) {
- /* while the verifier would fit in mtime+atime,
- * solaris7 gets confused (bugid 4218508) if these have
- * the high bit set, so we use the mode as well
+ /* solaris7 gets confused (bugid 4218508) if these have
+ * the high bit set, so just clear the high bits.
*/
v_mtime = verifier[0]&0x7fffffff;
v_atime = verifier[1]&0x7fffffff;
- v_mode = S_IFREG
- | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
- | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
- ;
}
if (dchild->d_inode) {
@@ -1323,7 +1317,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
case NFS3_CREATE_EXCLUSIVE:
if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
&& dchild->d_inode->i_atime.tv_sec == v_atime
- && dchild->d_inode->i_mode == v_mode
&& dchild->d_inode->i_size == 0 )
break;
/* fallthru */
@@ -1345,26 +1338,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
}
if (createmode == NFS3_CREATE_EXCLUSIVE) {
- /* Cram the verifier into atime/mtime/mode */
+ /* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME
- | ATTR_MTIME_SET|ATTR_ATIME_SET
- | ATTR_MODE;
+ | ATTR_MTIME_SET|ATTR_ATIME_SET;
/* XXX someone who knows this better please fix it for nsec */
iap->ia_mtime.tv_sec = v_mtime;
iap->ia_atime.tv_sec = v_atime;
iap->ia_mtime.tv_nsec = 0;
iap->ia_atime.tv_nsec = 0;
- iap->ia_mode = v_mode;
}
/* Set file attributes.
- * Mode has already been set but we might need to reset it
- * for CREATE_EXCLUSIVE
* Irix appears to send along the gid when it tries to
* implement setgid directories via NFS. Clear out all that cruft.
*/
set_attr:
- if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
+ if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
__be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
if (err2)
err = err2;
^ permalink raw reply [flat|nested] 12+ messages in thread