Merge branch 'for-2.6.39' of git://linux-nfs.org/~bfields/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Mar 2011 15:20:39 +0000 (08:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Mar 2011 15:20:39 +0000 (08:20 -0700)
* 'for-2.6.39' of git://linux-nfs.org/~bfields/linux:
  SUNRPC: Remove resource leak in svc_rdma_send_error()
  nfsd: wrong index used in inner loop
  nfsd4: fix comment and remove unused nfsd4_file fields
  nfs41: make sure nfs server return right ca_maxresponsesize_cached
  nfsd: fix compile error
  svcrpc: fix bad argument in unix_domain_find
  nfsd4: fix struct file leak
  nfsd4: minor nfs4state.c reshuffling
  svcrpc: fix rare race on unix_domain creation
  nfsd41: modify the members value of nfsd4_op_flags
  nfsd: add proc file listing kernel's gss_krb5 enctypes
  gss:krb5 only include enctype numbers in gm_upcall_enctypes
  NFSD, VFS: Remove dead code in nfsd_rename()
  nfsd: kill unused macro definition
  locks: use assign_type()

fs/locks.c
fs/nfsd/export.c
fs/nfsd/nfs4idmap.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/state.h
fs/nfsd/vfs.c
net/sunrpc/svcauth_unix.c

index 822c3d1..0a4f50d 100644 (file)
@@ -414,17 +414,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
        fl->fl_ops = NULL;
        fl->fl_lmops = NULL;
 
-       switch (l->l_type) {
-       case F_RDLCK:
-       case F_WRLCK:
-       case F_UNLCK:
-               fl->fl_type = l->l_type;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return (0);
+       return assign_type(fl, l->l_type);
 }
 #endif
 
index 8b31e5f..ad000ae 100644 (file)
@@ -299,7 +299,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
 
 #define        EXPORT_HASHBITS         8
 #define        EXPORT_HASHMAX          (1<< EXPORT_HASHBITS)
-#define        EXPORT_HASHMASK         (EXPORT_HASHMAX -1)
 
 static struct cache_head *export_table[EXPORT_HASHMAX];
 
index 6d2c397..55780a2 100644 (file)
@@ -63,7 +63,6 @@ struct ent {
 
 #define ENT_HASHBITS          8
 #define ENT_HASHMAX           (1 << ENT_HASHBITS)
-#define ENT_HASHMASK          (ENT_HASHMAX - 1)
 
 static void
 ent_init(struct cache_head *cnew, struct cache_head *citm)
index db52546..5fcb139 100644 (file)
@@ -984,8 +984,8 @@ typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
                              void *);
 enum nfsd4_op_flags {
        ALLOWED_WITHOUT_FH = 1 << 0,    /* No current filehandle required */
-       ALLOWED_ON_ABSENT_FS = 2 << 0,  /* ops processed on absent fs */
-       ALLOWED_AS_FIRST_OP = 3 << 0,   /* ops reqired first in compound */
+       ALLOWED_ON_ABSENT_FS = 1 << 1,  /* ops processed on absent fs */
+       ALLOWED_AS_FIRST_OP = 1 << 2,   /* ops reqired first in compound */
 };
 
 struct nfsd4_operation {
index 7b566ec..fbde6f7 100644 (file)
@@ -148,7 +148,7 @@ static struct list_head     ownerstr_hashtbl[OWNER_HASH_SIZE];
 /* hash table for nfs4_file */
 #define FILE_HASH_BITS                   8
 #define FILE_HASH_SIZE                  (1 << FILE_HASH_BITS)
-#define FILE_HASH_MASK                  (FILE_HASH_SIZE - 1)
+
 /* hash table for (open)nfs4_stateid */
 #define STATEID_HASH_BITS              10
 #define STATEID_HASH_SIZE              (1 << STATEID_HASH_BITS)
@@ -316,64 +316,6 @@ static struct list_head    unconf_id_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head client_lru;
 static struct list_head close_lru;
 
-static void unhash_generic_stateid(struct nfs4_stateid *stp)
-{
-       list_del(&stp->st_hash);
-       list_del(&stp->st_perfile);
-       list_del(&stp->st_perstateowner);
-}
-
-static void free_generic_stateid(struct nfs4_stateid *stp)
-{
-       put_nfs4_file(stp->st_file);
-       kmem_cache_free(stateid_slab, stp);
-}
-
-static void release_lock_stateid(struct nfs4_stateid *stp)
-{
-       struct file *file;
-
-       unhash_generic_stateid(stp);
-       file = find_any_file(stp->st_file);
-       if (file)
-               locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
-       free_generic_stateid(stp);
-}
-
-static void unhash_lockowner(struct nfs4_stateowner *sop)
-{
-       struct nfs4_stateid *stp;
-
-       list_del(&sop->so_idhash);
-       list_del(&sop->so_strhash);
-       list_del(&sop->so_perstateid);
-       while (!list_empty(&sop->so_stateids)) {
-               stp = list_first_entry(&sop->so_stateids,
-                               struct nfs4_stateid, st_perstateowner);
-               release_lock_stateid(stp);
-       }
-}
-
-static void release_lockowner(struct nfs4_stateowner *sop)
-{
-       unhash_lockowner(sop);
-       nfs4_put_stateowner(sop);
-}
-
-static void
-release_stateid_lockowners(struct nfs4_stateid *open_stp)
-{
-       struct nfs4_stateowner *lock_sop;
-
-       while (!list_empty(&open_stp->st_lockowners)) {
-               lock_sop = list_entry(open_stp->st_lockowners.next,
-                               struct nfs4_stateowner, so_perstateid);
-               /* list_del(&open_stp->st_lockowners);  */
-               BUG_ON(lock_sop->so_is_open_owner);
-               release_lockowner(lock_sop);
-       }
-}
-
 /*
  * We store the NONE, READ, WRITE, and BOTH bits separately in the
  * st_{access,deny}_bmap field of the stateid, in order to track not
@@ -446,13 +388,71 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
        return nfs4_access_to_omode(access);
 }
 
-static void release_open_stateid(struct nfs4_stateid *stp)
+static void unhash_generic_stateid(struct nfs4_stateid *stp)
+{
+       list_del(&stp->st_hash);
+       list_del(&stp->st_perfile);
+       list_del(&stp->st_perstateowner);
+}
+
+static void free_generic_stateid(struct nfs4_stateid *stp)
 {
        int oflag = nfs4_access_bmap_to_omode(stp);
 
+       nfs4_file_put_access(stp->st_file, oflag);
+       put_nfs4_file(stp->st_file);
+       kmem_cache_free(stateid_slab, stp);
+}
+
+static void release_lock_stateid(struct nfs4_stateid *stp)
+{
+       struct file *file;
+
+       unhash_generic_stateid(stp);
+       file = find_any_file(stp->st_file);
+       if (file)
+               locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
+       free_generic_stateid(stp);
+}
+
+static void unhash_lockowner(struct nfs4_stateowner *sop)
+{
+       struct nfs4_stateid *stp;
+
+       list_del(&sop->so_idhash);
+       list_del(&sop->so_strhash);
+       list_del(&sop->so_perstateid);
+       while (!list_empty(&sop->so_stateids)) {
+               stp = list_first_entry(&sop->so_stateids,
+                               struct nfs4_stateid, st_perstateowner);
+               release_lock_stateid(stp);
+       }
+}
+
+static void release_lockowner(struct nfs4_stateowner *sop)
+{
+       unhash_lockowner(sop);
+       nfs4_put_stateowner(sop);
+}
+
+static void
+release_stateid_lockowners(struct nfs4_stateid *open_stp)
+{
+       struct nfs4_stateowner *lock_sop;
+
+       while (!list_empty(&open_stp->st_lockowners)) {
+               lock_sop = list_entry(open_stp->st_lockowners.next,
+                               struct nfs4_stateowner, so_perstateid);
+               /* list_del(&open_stp->st_lockowners);  */
+               BUG_ON(lock_sop->so_is_open_owner);
+               release_lockowner(lock_sop);
+       }
+}
+
+static void release_open_stateid(struct nfs4_stateid *stp)
+{
        unhash_generic_stateid(stp);
        release_stateid_lockowners(stp);
-       nfs4_file_put_access(stp->st_file, oflag);
        free_generic_stateid(stp);
 }
 
@@ -608,7 +608,8 @@ static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4
        u32 maxrpc = nfsd_serv->sv_max_mesg;
 
        new->maxreqs = numslots;
-       new->maxresp_cached = slotsize + NFSD_MIN_HDR_SEQ_SZ;
+       new->maxresp_cached = min_t(u32, req->maxresp_cached,
+                                       slotsize + NFSD_MIN_HDR_SEQ_SZ);
        new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc);
        new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc);
        new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND);
@@ -3735,6 +3736,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
        stp->st_stateid.si_stateownerid = sop->so_id;
        stp->st_stateid.si_fileid = fp->fi_id;
        stp->st_stateid.si_generation = 0;
+       stp->st_access_bmap = 0;
        stp->st_deny_bmap = open_stp->st_deny_bmap;
        stp->st_openstp = open_stp;
 
@@ -3749,6 +3751,17 @@ check_lock_length(u64 offset, u64 length)
             LOFF_OVERFLOW(offset, length)));
 }
 
+static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access)
+{
+       struct nfs4_file *fp = lock_stp->st_file;
+       int oflag = nfs4_access_to_omode(access);
+
+       if (test_bit(access, &lock_stp->st_access_bmap))
+               return;
+       nfs4_file_get_access(fp, oflag);
+       __set_bit(access, &lock_stp->st_access_bmap);
+}
+
 /*
  *  LOCK operation 
  */
@@ -3765,7 +3778,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        struct file_lock conflock;
        __be32 status = 0;
        unsigned int strhashval;
-       unsigned int cmd;
        int err;
 
        dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
@@ -3847,22 +3859,18 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        switch (lock->lk_type) {
                case NFS4_READ_LT:
                case NFS4_READW_LT:
-                       if (find_readable_file(lock_stp->st_file)) {
-                               nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ);
-                               filp = find_readable_file(lock_stp->st_file);
-                       }
+                       filp = find_readable_file(lock_stp->st_file);
+                       if (filp)
+                               get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
                        file_lock.fl_type = F_RDLCK;
-                       cmd = F_SETLK;
-               break;
+                       break;
                case NFS4_WRITE_LT:
                case NFS4_WRITEW_LT:
-                       if (find_writeable_file(lock_stp->st_file)) {
-                               nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE);
-                               filp = find_writeable_file(lock_stp->st_file);
-                       }
+                       filp = find_writeable_file(lock_stp->st_file);
+                       if (filp)
+                               get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
                        file_lock.fl_type = F_WRLCK;
-                       cmd = F_SETLK;
-               break;
+                       break;
                default:
                        status = nfserr_inval;
                goto out;
@@ -3886,7 +3894,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        * Note: locks.c uses the BKL to protect the inode's lock list.
        */
 
-       err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
+       err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
        switch (-err) {
        case 0: /* success! */
                update_stateid(&lock_stp->st_stateid);
index 615f0a9..c6766af 100644 (file)
@@ -1142,7 +1142,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 
        u32 dummy;
        char *machine_name;
-       int i, j;
+       int i;
        int nr_secflavs;
 
        READ_BUF(16);
@@ -1215,8 +1215,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
                        READ_BUF(4);
                        READ32(dummy);
                        READ_BUF(dummy * 4);
-                       for (j = 0; j < dummy; ++j)
-                               READ32(dummy);
                        break;
                case RPC_AUTH_GSS:
                        dprintk("RPC_AUTH_GSS callback secflavor "
@@ -1232,7 +1230,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
                        READ_BUF(4);
                        READ32(dummy);
                        READ_BUF(dummy);
-                       p += XDR_QUADLEN(dummy);
                        break;
                default:
                        dprintk("Illegal callback secflavor\n");
index 33b3e2b..1f5eae4 100644 (file)
 #include <linux/nfsd/syscall.h>
 #include <linux/lockd/lockd.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/gss_api.h>
 
 #include "idmap.h"
 #include "nfsd.h"
 #include "cache.h"
 
 /*
- *     We have a single directory with 9 nodes in it.
+ *     We have a single directory with several nodes in it.
  */
 enum {
        NFSD_Root = 1,
@@ -42,6 +43,7 @@ enum {
        NFSD_Versions,
        NFSD_Ports,
        NFSD_MaxBlkSize,
+       NFSD_SupportedEnctypes,
        /*
         * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
         * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -187,6 +189,34 @@ static struct file_operations export_features_operations = {
        .release        = single_release,
 };
 
+#ifdef CONFIG_SUNRPC_GSS
+static int supported_enctypes_show(struct seq_file *m, void *v)
+{
+       struct gss_api_mech *k5mech;
+
+       k5mech = gss_mech_get_by_name("krb5");
+       if (k5mech == NULL)
+               goto out;
+       if (k5mech->gm_upcall_enctypes != NULL)
+               seq_printf(m, k5mech->gm_upcall_enctypes);
+       gss_mech_put(k5mech);
+out:
+       return 0;
+}
+
+static int supported_enctypes_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, supported_enctypes_show, NULL);
+}
+
+static struct file_operations supported_enctypes_ops = {
+       .open           = supported_enctypes_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif /* CONFIG_SUNRPC_GSS */
+
 extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
 extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
 
@@ -1397,6 +1427,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
                [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
+#ifdef CONFIG_SUNRPC_GSS
+               [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
+#endif /* CONFIG_SUNRPC_GSS */
 #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
index 2d31224..6bd2f3c 100644 (file)
@@ -367,16 +367,12 @@ struct nfs4_file {
        struct list_head        fi_delegations;
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
        struct file *           fi_fds[3];
-       /* One each for O_RDONLY, O_WRONLY: */
-       atomic_t                fi_access[2];
        /*
-        * Each open stateid contributes 1 to either fi_readers or
-        * fi_writers, or both, depending on the open mode.  A
-        * delegation also takes an fi_readers reference.  Lock
-        * stateid's take none.
+        * Each open or lock stateid contributes 1 to either
+        * fi_access[O_RDONLY], fi_access[O_WRONLY], or both, depending
+        * on open or lock mode:
         */
-       atomic_t                fi_readers;
-       atomic_t                fi_writers;
+       atomic_t                fi_access[2];
        struct file             *fi_deleg_file;
        struct file_lock        *fi_lease;
        atomic_t                fi_delegees;
index ff93025..2e1cebd 100644 (file)
@@ -1749,8 +1749,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
                if (host_err)
                        goto out_drop_write;
        }
-       if (host_err)
-               goto out_drop_write;
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
        if (!host_err) {
                host_err = commit_metadata(tfhp);
index 30916b0..c8e1021 100644 (file)
@@ -38,6 +38,14 @@ struct unix_domain {
 
 extern struct auth_ops svcauth_unix;
 
+static void svcauth_unix_domain_release(struct auth_domain *dom)
+{
+       struct unix_domain *ud = container_of(dom, struct unix_domain, h);
+
+       kfree(dom->name);
+       kfree(ud);
+}
+
 struct auth_domain *unix_domain_find(char *name)
 {
        struct auth_domain *rv;
@@ -47,7 +55,7 @@ struct auth_domain *unix_domain_find(char *name)
        while(1) {
                if (rv) {
                        if (new && rv != &new->h)
-                               auth_domain_put(&new->h);
+                               svcauth_unix_domain_release(&new->h);
 
                        if (rv->flavour != &svcauth_unix) {
                                auth_domain_put(rv);
@@ -74,14 +82,6 @@ struct auth_domain *unix_domain_find(char *name)
 }
 EXPORT_SYMBOL_GPL(unix_domain_find);
 
-static void svcauth_unix_domain_release(struct auth_domain *dom)
-{
-       struct unix_domain *ud = container_of(dom, struct unix_domain, h);
-
-       kfree(dom->name);
-       kfree(ud);
-}
-
 
 /**************************************************
  * cache for IP address to unix_domain