J. Bruce Fields : > On Wed, Apr 06, 2011 at 05:04:50PM +0800, Mi Jinlong wrote: >> At the recent kernel(2.6.39-rc1), > > (But this is not a regression, right? This has been a problem all > along.) Yes, I think it's just a problem. > >> NFS server can't process OPEN with EXCLUSIVE4_1, >> because NFS server call nfsd_create_v3 to create file instead implement a separate >> one. But nfsd_create_v3 can't process createmode is EXCLUSIVE4_1. > > Is our handling of the attributes correct in this case? (See e.g. the > op_bmval[1] assignment a few lines down.) There is no problem of the p_bmval[1] assignment a few lines down. According to rfc5661 18.16.3, EXCLUSIVE4_1 supports the setting of attributes at file creation, we don't need to set p_bmval[1] assignment as EXCLUSIVE. I think we should have a fix at nfsd_create_v3(), not at do_open_lookup(). Please ignore the old patch, a new one is as following. -- thanks, Mi Jinlong ============================================================================= >From 7adf0213b525c02761022c7fee60f52012d32a9a Mon Sep 17 00:00:00 2001 From: Mi Jinlong <mijinlong@xxxxxxxxxxxxxx> Date: Mon, 4 Apr 2011 00:49:19 +0800 Subject: [PATCH] nfsd41: make sure nfs server process OPEN with EXCLUSIVE4_1 correcttly NFS server can't process OPEN with EXCLUSIVE4_1, because NFS server call nfsd_create_v3 to create file instead implement a separate one. But nfsd_create_v3 can't process createmode is EXCLUSIVE4_1. This patch rename nfsd_create_v3() to do_nfsd_create(), and add some codes about process EXCLUSIVE4_1. Signed-off-by: Mi Jinlong <mijinlong@xxxxxxxxxxxxxx> --- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/nfs4proc.c | 4 ++-- fs/nfsd/vfs.c | 18 +++++++++++++----- fs/nfsd/vfs.h | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 2247fc9..9095f3c 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, } /* Now create the file and set attributes */ - nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, + nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len, attr, newfhp, argp->createmode, argp->verf, NULL, NULL); diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5fcb139..e1d100f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o /* * Note: create modes (UNCHECKED,GUARDED...) are the same - * in NFSv4 as in v3. + * in NFSv4 as in v3 except EXCLUSIVE4_1. */ - status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, + status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &open->op_iattr, &resfh, open->op_createmode, (u32 *)open->op_verf.data, diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 2e1cebd..fe8b818 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1341,10 +1341,10 @@ out_nfserr: #ifdef CONFIG_NFSD_V3 /* - * NFSv3 version of nfsd_create + * NFSv3 and NFSv4 version of nfsd_create */ __be32 -nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, +do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, struct iattr *iap, struct svc_fh *resfhp, int createmode, u32 *verifier, int *truncp, int *created) @@ -1389,7 +1389,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, if (err) goto out; - if (createmode == NFS3_CREATE_EXCLUSIVE) { + if (createmode & NFS3_CREATE_EXCLUSIVE) { /* solaris7 gets confused (bugid 4218508) if these have * the high bit set, so just clear the high bits. If this is * ever changed to use different attrs for storing the @@ -1426,10 +1426,18 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, } break; case NFS3_CREATE_EXCLUSIVE: +#ifdef CONFIG_NFSD_V4 + case NFS4_CREATE_EXCLUSIVE4_1: +#endif if ( dchild->d_inode->i_mtime.tv_sec == v_mtime && dchild->d_inode->i_atime.tv_sec == v_atime && dchild->d_inode->i_size == 0 ) - break; +#ifdef CONFIG_NFSD_V4 + if (createmode == NFS4_CREATE_EXCLUSIVE4_1) + goto set_attr; + else +#endif + break; /* fallthru */ case NFS3_CREATE_GUARDED: err = nfserr_exist; @@ -1448,7 +1456,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_check_ignore_resizing(iap); - if (createmode == NFS3_CREATE_EXCLUSIVE) { + if (createmode & NFS3_CREATE_EXCLUSIVE) { /* Cram the verifier into atime/mtime */ iap->ia_valid = ATTR_MTIME|ATTR_ATIME | ATTR_MTIME_SET|ATTR_ATIME_SET; diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 9a370a5..10dbe9f 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -54,7 +54,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, int type, dev_t rdev, struct svc_fh *res); #ifdef CONFIG_NFSD_V3 __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); -__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, +__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, struct svc_fh *res, int createmode, u32 *verifier, int *truncp, int *created); -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html