commit: 9dc4e6c4d1182d34604ea40fef641775f5b15456
From: J. Bruce Fields <[email protected]>
Date: Mon, 9 Apr 2012 18:06:49 -0400
Subject: nfsd: don't fail unchecked creates of non-special files

Allow a v3 unchecked open of a non-regular file succeed as if it were a
lookup; typically a client in such a case will want to fall back on a
local open, so succeeding and giving it the filehandle is more useful
than failing with nfserr_exist, which makes it appear that nothing at
all exists by that name.

Similarly for v4, on an open-create, return the same errors we would on
an attempt to open a non-regular file, instead of returning
nfserr_exist.

This fixes a problem found doing a v4 open of a symlink with
O_RDONLY|O_CREAT, which resulted in the current client returning EEXIST.

Thanks also to Trond for analysis.

Cc: [email protected]
Reported-by: Orion Poplawski <[email protected]>
Tested-by: Orion Poplawski <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
---
 fs/nfsd/nfs4proc.c |    8 ++++----
 fs/nfsd/vfs.c      |    2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 2ed14df..8256efd 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -235,17 +235,17 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh 
*current_fh, struct nfsd4_o
                 */
                if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
                        open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
-                                               FATTR4_WORD1_TIME_MODIFY);
+                                                       
FATTR4_WORD1_TIME_MODIFY);
        } else {
                status = nfsd_lookup(rqstp, current_fh,
                                     open->op_fname.data, open->op_fname.len, 
resfh);
                fh_unlock(current_fh);
-               if (status)
-                       goto out;
-               status = nfsd_check_obj_isreg(resfh);
        }
        if (status)
                goto out;
+       status = nfsd_check_obj_isreg(resfh);
+       if (status)
+               goto out;
 
        if (is_create_with_attrs(open) && open->op_acl != NULL)
                do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 296d671..5686661 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                switch (createmode) {
                case NFS3_CREATE_UNCHECKED:
                        if (! S_ISREG(dchild->d_inode->i_mode))
-                               err = nfserr_exist;
+                               goto out;
                        else if (truncp) {
                                /* in nfsv4, we need to treat this case a little
                                 * differently.  we don't want to truncate the
-- 
1.7.3.4
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to