OSDN Git Service

Merge branch 'for-4.1' of git://linux-nfs.org/~bfields/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Apr 2015 14:46:05 +0000 (07:46 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Apr 2015 14:46:05 +0000 (07:46 -0700)
Pull nfsd updates from Bruce Fields:
 "A quiet cycle this time; this is basically entirely bugfixes.

  The few that aren't cc'd to stable are cleanup or seemed unlikely to
  affect anyone much"

* 'for-4.1' of git://linux-nfs.org/~bfields/linux:
  uapi: Remove kernel internal declaration
  nfsd: fix nsfd startup race triggering BUG_ON
  nfsd: eliminate NFSD_DEBUG
  nfsd4: fix READ permission checking
  nfsd4: disallow SEEK with special stateids
  nfsd4: disallow ALLOCATE with special stateids
  nfsd: add NFSEXP_PNFS to the exflags array
  nfsd: Remove duplicate macro define for max sec label length
  nfsd: allow setting acls with unenforceable DENYs
  nfsd: NFSD_FAULT_INJECTION depends on DEBUG_FS
  nfsd: remove unused status arg to nfsd4_cleanup_open_state
  nfsd: remove bogus setting of status in nfsd4_process_open2
  NFSD: Use correct reply size calculating function
  NFSD: Using path_equal() for checking two paths

14 files changed:
fs/lockd/svcsubs.c
fs/nfsd/Kconfig
fs/nfsd/export.c
fs/nfsd/nfs4acl.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/xdr4.h
include/linux/nfs4.h
include/uapi/linux/nfs4.h
include/uapi/linux/nfsd/debug.h
include/uapi/linux/nfsd/export.h

index 665ef5a..a563ddb 100644 (file)
@@ -31,7 +31,7 @@
 static struct hlist_head       nlm_files[FILE_NRHASH];
 static DEFINE_MUTEX(nlm_file_mutex);
 
-#ifdef NFSD_DEBUG
+#ifdef CONFIG_SUNRPC_DEBUG
 static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
 {
        u32 *fhp = (u32*)f->data;
index fc2d108..a0b77fc 100644 (file)
@@ -108,7 +108,7 @@ config NFSD_V4_SECURITY_LABEL
 
 config NFSD_FAULT_INJECTION
        bool "NFS server manual fault injection"
-       depends on NFSD_V4 && DEBUG_KERNEL
+       depends on NFSD_V4 && DEBUG_KERNEL && DEBUG_FS
        help
          This option enables support for manually injecting faults
          into the NFS server.  This is intended to be used for
index c3e3b6e..900c3ae 100644 (file)
@@ -691,8 +691,7 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b)
        struct svc_export *orig = container_of(a, struct svc_export, h);
        struct svc_export *new = container_of(b, struct svc_export, h);
        return orig->ex_client == new->ex_client &&
-               orig->ex_path.dentry == new->ex_path.dentry &&
-               orig->ex_path.mnt == new->ex_path.mnt;
+               path_equal(&orig->ex_path, &new->ex_path);
 }
 
 static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
@@ -1159,6 +1158,7 @@ static struct flags {
        { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
        { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
        { NFSEXP_V4ROOT, {"v4root", ""}},
+       { NFSEXP_PNFS, {"pnfs", ""}},
        { 0, {"", ""}}
 };
 
index 59fd766..eaf4605 100644 (file)
@@ -499,43 +499,13 @@ static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_s
        state->mask.allow |= astate->allow;
 }
 
-/*
- * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
- * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
- * to traditional read/write/execute permissions.
- *
- * It's problematic to reject acls that use certain mode bits, because it
- * places the burden on users to learn the rules about which bits one
- * particular server sets, without giving the user a lot of help--we return an
- * error that could mean any number of different things.  To make matters
- * worse, the problematic bits might be introduced by some application that's
- * automatically mapping from some other acl model.
- *
- * So wherever possible we accept anything, possibly erring on the side of
- * denying more permissions than necessary.
- *
- * However we do reject *explicit* DENY's of a few bits representing
- * permissions we could never deny:
- */
-
-static inline int check_deny(u32 mask, int isowner)
-{
-       if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
-               return -EINVAL;
-       if (!isowner)
-               return 0;
-       if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
-               return -EINVAL;
-       return 0;
-}
-
 static struct posix_acl *
 posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 {
        struct posix_acl_entry *pace;
        struct posix_acl *pacl;
        int nace;
-       int i, error = 0;
+       int i;
 
        /*
         * ACLs with no ACEs are treated differently in the inheritable
@@ -560,17 +530,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 
        pace = pacl->a_entries;
        pace->e_tag = ACL_USER_OBJ;
-       error = check_deny(state->owner.deny, 1);
-       if (error)
-               goto out_err;
        low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
 
        for (i=0; i < state->users->n; i++) {
                pace++;
                pace->e_tag = ACL_USER;
-               error = check_deny(state->users->aces[i].perms.deny, 0);
-               if (error)
-                       goto out_err;
                low_mode_from_nfs4(state->users->aces[i].perms.allow,
                                        &pace->e_perm, flags);
                pace->e_uid = state->users->aces[i].uid;
@@ -579,18 +543,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 
        pace++;
        pace->e_tag = ACL_GROUP_OBJ;
-       error = check_deny(state->group.deny, 0);
-       if (error)
-               goto out_err;
        low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
        add_to_mask(state, &state->group);
 
        for (i=0; i < state->groups->n; i++) {
                pace++;
                pace->e_tag = ACL_GROUP;
-               error = check_deny(state->groups->aces[i].perms.deny, 0);
-               if (error)
-                       goto out_err;
                low_mode_from_nfs4(state->groups->aces[i].perms.allow,
                                        &pace->e_perm, flags);
                pace->e_gid = state->groups->aces[i].gid;
@@ -605,15 +563,9 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 
        pace++;
        pace->e_tag = ACL_OTHER;
-       error = check_deny(state->other.deny, 0);
-       if (error)
-               goto out_err;
        low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
 
        return pacl;
-out_err:
-       posix_acl_release(pacl);
-       return ERR_PTR(error);
 }
 
 static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
index 92b9d97..4a8314f 100644 (file)
@@ -470,7 +470,7 @@ out:
                fh_put(resfh);
                kfree(resfh);
        }
-       nfsd4_cleanup_open_state(cstate, open, status);
+       nfsd4_cleanup_open_state(cstate, open);
        nfsd4_bump_seqid(cstate, status);
        return status;
 }
@@ -1030,6 +1030,8 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
                return status;
        }
+       if (!file)
+               return nfserr_bad_stateid;
 
        status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
                                     fallocate->falloc_offset,
@@ -1069,6 +1071,8 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
                return status;
        }
+       if (!file)
+               return nfserr_bad_stateid;
 
        switch (seek->seek_whence) {
        case NFS4_CONTENT_DATA:
@@ -1815,7 +1819,7 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
                bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
        }
        if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
-               ret += NFSD4_MAX_SEC_LABEL_LEN + 12;
+               ret += NFS4_MAXLABELLEN + 12;
                bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
        }
        /*
@@ -2282,13 +2286,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_func = (nfsd4op_func)nfsd4_allocate,
                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
                .op_name = "OP_ALLOCATE",
-               .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
+               .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
        },
        [OP_DEALLOCATE] = {
                .op_func = (nfsd4op_func)nfsd4_deallocate,
                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
                .op_name = "OP_DEALLOCATE",
-               .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
+               .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
        },
        [OP_SEEK] = {
                .op_func = (nfsd4op_func)nfsd4_seek,
index 326a545..d42786e 100644 (file)
@@ -1139,7 +1139,7 @@ hash_sessionid(struct nfs4_sessionid *sessionid)
        return sid->sequence % SESSION_HASH_SIZE;
 }
 
-#ifdef NFSD_DEBUG
+#ifdef CONFIG_SUNRPC_DEBUG
 static inline void
 dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
 {
@@ -4049,7 +4049,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                status = nfserr_bad_stateid;
                if (nfsd4_is_deleg_cur(open))
                        goto out;
-               status = nfserr_jukebox;
        }
 
        /*
@@ -4118,7 +4117,7 @@ out:
 }
 
 void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
-                             struct nfsd4_open *open, __be32 status)
+                             struct nfsd4_open *open)
 {
        if (open->op_openowner) {
                struct nfs4_stateowner *so = &open->op_openowner->oo_owner;
index 5fb7e78..a45032c 100644 (file)
@@ -424,7 +424,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                len += 4;
                dummy32 = be32_to_cpup(p++);
                READ_BUF(dummy32);
-               if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN)
+               if (dummy32 > NFS4_MAXLABELLEN)
                        return nfserr_badlabel;
                len += (XDR_QUADLEN(dummy32) << 2);
                READMEM(buf, dummy32);
@@ -2020,7 +2020,7 @@ static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
         * dentries/path components in an array.
         */
        for (;;) {
-               if (cur.dentry == root->dentry && cur.mnt == root->mnt)
+               if (path_equal(&cur, root))
                        break;
                if (cur.dentry == cur.mnt->mnt_root) {
                        if (follow_up(&cur))
@@ -3422,6 +3422,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
        unsigned long maxcount;
        struct xdr_stream *xdr = &resp->xdr;
        struct file *file = read->rd_filp;
+       struct svc_fh *fhp = read->rd_fhp;
        int starting_len = xdr->buf->len;
        struct raparms *ra;
        __be32 *p;
@@ -3445,12 +3446,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
        maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
        maxcount = min_t(unsigned long, maxcount, read->rd_length);
 
-       if (!read->rd_filp) {
+       if (read->rd_filp)
+               err = nfsd_permission(resp->rqstp, fhp->fh_export,
+                               fhp->fh_dentry,
+                               NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
+       else
                err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
                                                &file, &ra);
-               if (err)
-                       goto err_truncate;
-       }
+       if (err)
+               goto err_truncate;
 
        if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
                err = nfsd4_encode_splice_read(resp, read, file, maxcount);
index aa47d75..9690cb4 100644 (file)
@@ -1250,15 +1250,15 @@ static int __init init_nfsd(void)
        int retval;
        printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
 
-       retval = register_cld_notifier();
-       if (retval)
-               return retval;
        retval = register_pernet_subsys(&nfsd_net_ops);
        if (retval < 0)
-               goto out_unregister_notifier;
-       retval = nfsd4_init_slabs();
+               return retval;
+       retval = register_cld_notifier();
        if (retval)
                goto out_unregister_pernet;
+       retval = nfsd4_init_slabs();
+       if (retval)
+               goto out_unregister_notifier;
        retval = nfsd4_init_pnfs();
        if (retval)
                goto out_free_slabs;
@@ -1290,10 +1290,10 @@ out_exit_pnfs:
        nfsd4_exit_pnfs();
 out_free_slabs:
        nfsd4_free_slabs();
-out_unregister_pernet:
-       unregister_pernet_subsys(&nfsd_net_ops);
 out_unregister_notifier:
        unregister_cld_notifier();
+out_unregister_pernet:
+       unregister_pernet_subsys(&nfsd_net_ops);
        return retval;
 }
 
@@ -1308,8 +1308,8 @@ static void __exit exit_nfsd(void)
        nfsd4_exit_pnfs();
        nfsd_fault_inject_cleanup();
        unregister_filesystem(&nfsd_fs_type);
-       unregister_pernet_subsys(&nfsd_net_ops);
        unregister_cld_notifier();
+       unregister_pernet_subsys(&nfsd_net_ops);
 }
 
 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
index 565c4da..cf98052 100644 (file)
@@ -24,7 +24,7 @@
 #include "export.h"
 
 #undef ifdebug
-#ifdef NFSD_DEBUG
+#ifdef CONFIG_SUNRPC_DEBUG
 # define ifdebug(flag)         if (nfsd_debug & NFSDDBG_##flag)
 #else
 # define ifdebug(flag)         if (0)
index 0bda93e..556ce2e 100644 (file)
@@ -40,7 +40,6 @@
 #include "state.h"
 #include "nfsd.h"
 
-#define NFSD4_MAX_SEC_LABEL_LEN        2048
 #define NFSD4_MAX_TAGLEN       128
 #define XDR_LEN(n)                     (((n) + 3) & ~3)
 
@@ -683,7 +682,7 @@ extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open *open);
 extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
 extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
-               struct nfsd4_open *open, __be32 status);
+               struct nfsd4_open *open);
 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
 extern __be32 nfsd4_close(struct svc_rqst *rqstp,
index ed43cb7..32201c2 100644 (file)
 #include <linux/uidgid.h>
 #include <uapi/linux/nfs4.h>
 
+enum nfs4_acl_whotype {
+       NFS4_ACL_WHO_NAMED = 0,
+       NFS4_ACL_WHO_OWNER,
+       NFS4_ACL_WHO_GROUP,
+       NFS4_ACL_WHO_EVERYONE,
+};
+
 struct nfs4_ace {
        uint32_t        type;
        uint32_t        flag;
index 35f5f4c..adc0aff 100644 (file)
  */
 #define NFS4_MAX_BACK_CHANNEL_OPS 2
 
-enum nfs4_acl_whotype {
-       NFS4_ACL_WHO_NAMED = 0,
-       NFS4_ACL_WHO_OWNER,
-       NFS4_ACL_WHO_GROUP,
-       NFS4_ACL_WHO_EVERYONE,
-};
-
 #endif /* _UAPI_LINUX_NFS4_H */
 
 /*
index 0bf130a..28ec6c9 100644 (file)
 #include <linux/sunrpc/debug.h>
 
 /*
- * Enable debugging for nfsd.
- * Requires RPC_DEBUG.
- */
-#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
-# define NFSD_DEBUG            1
-#endif
-
-/*
  * knfsd debug flags
  */
 #define NFSDDBG_SOCK           0x0001
index d3bd6ff..0df7bd5 100644 (file)
@@ -21,6 +21,9 @@
 
 /*
  * Export flags.
+ *
+ * Please update the expflags[] array in fs/nfsd/export.c when adding
+ * a new flag.
  */
 #define NFSEXP_READONLY                0x0001
 #define NFSEXP_INSECURE_PORT   0x0002