Skip to content

Commit

Permalink
Merge branch 'for-3.16' of git://linux-nfs.org/~bfields/linux
Browse files Browse the repository at this point in the history
Pull nfsd updates from Bruce Fields:
 "The largest piece is a long-overdue rewrite of the xdr code to remove
  some annoying limitations: for example, there was no way to return
  ACLs larger than 4K, and readdir results were returned only in 4k
  chunks, limiting performance on large directories.

  Also:
        - part of Neil Brown's work to make NFS work reliably over the
          loopback interface (so client and server can run on the same
          machine without deadlocks).  The rest of it is coming through
          other trees.
        - cleanup and bugfixes for some of the server RDMA code, from
          Steve Wise.
        - Various cleanup of NFSv4 state code in preparation for an
          overhaul of the locking, from Jeff, Trond, and Benny.
        - smaller bugfixes and cleanup from Christoph Hellwig and
          Kinglong Mee.

  Thanks to everyone!

  This summer looks likely to be busier than usual for knfsd.  Hopefully
  we won't break it too badly; testing definitely welcomed"

* 'for-3.16' of git://linux-nfs.org/~bfields/linux: (100 commits)
  nfsd4: fix FREE_STATEID lockowner leak
  svcrdma: Fence LOCAL_INV work requests
  svcrdma: refactor marshalling logic
  nfsd: don't halt scanning the DRC LRU list when there's an RC_INPROG entry
  nfs4: remove unused CHANGE_SECURITY_LABEL
  nfsd4: kill READ64
  nfsd4: kill READ32
  nfsd4: simplify server xdr->next_page use
  nfsd4: hash deleg stateid only on successful nfs4_set_delegation
  nfsd4: rename recall_lock to state_lock
  nfsd: remove unneeded zeroing of fields in nfsd4_proc_compound
  nfsd: fix setting of NFS4_OO_CONFIRMED in nfsd4_open
  nfsd4: use recall_lock for delegation hashing
  nfsd: fix laundromat next-run-time calculation
  nfsd: make nfsd4_encode_fattr static
  SUNRPC/NFSD: Remove using of dprintk with KERN_WARNING
  nfsd: remove unused function nfsd_read_file
  nfsd: getattr for FATTR4_WORD0_FILES_AVAIL needs the statfs buffer
  NFSD: Error out when getting more than one fsloc/secinfo/uuid
  NFSD: Using type of uint32_t for ex_nflavors instead of int
  ...
  • Loading branch information
torvalds committed Jun 10, 2014
2 parents 1d21b1b + 4838540 commit 5b174fd
Show file tree
Hide file tree
Showing 53 changed files with 2,265 additions and 1,999 deletions.
2 changes: 0 additions & 2 deletions Documentation/filesystems/nfs/nfs41-server.txt
Expand Up @@ -176,7 +176,5 @@ Nonstandard compound limitations:
ca_maxrequestsize request and a ca_maxresponsesize reply, so we may
fail to live up to the promise we made in CREATE_SESSION fore channel
negotiation.
* No more than one read-like operation allowed per compound; encoding
replies that cross page boundaries (except for read data) not handled.

See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues.
2 changes: 2 additions & 0 deletions fs/lockd/clnt4xdr.c
Expand Up @@ -14,6 +14,8 @@
#include <linux/sunrpc/stats.h>
#include <linux/lockd/lockd.h>

#include <uapi/linux/nfs3.h>

#define NLMDBG_FACILITY NLMDBG_XDR

#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
Expand Down
2 changes: 2 additions & 0 deletions fs/lockd/clntxdr.c
Expand Up @@ -15,6 +15,8 @@
#include <linux/sunrpc/stats.h>
#include <linux/lockd/lockd.h>

#include <uapi/linux/nfs2.h>

#define NLMDBG_FACILITY NLMDBG_XDR

#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
Expand Down
2 changes: 1 addition & 1 deletion fs/lockd/svc.c
Expand Up @@ -622,8 +622,8 @@ static int __init init_nlm(void)
err_pernet:
#ifdef CONFIG_SYSCTL
unregister_sysctl_table(nlm_sysctl_table);
#endif
err_sysctl:
#endif
return err;
}

Expand Down
3 changes: 1 addition & 2 deletions fs/lockd/svcsubs.c
Expand Up @@ -14,12 +14,11 @@
#include <linux/mutex.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/addr.h>
#include <linux/nfsd/nfsfh.h>
#include <linux/nfsd/export.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/share.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <uapi/linux/nfs2.h>

#define NLMDBG_FACILITY NLMDBG_SVCSUBS

Expand Down
2 changes: 2 additions & 0 deletions fs/lockd/xdr.c
Expand Up @@ -16,6 +16,8 @@
#include <linux/sunrpc/stats.h>
#include <linux/lockd/lockd.h>

#include <uapi/linux/nfs2.h>

#define NLMDBG_FACILITY NLMDBG_XDR


Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs4proc.c
Expand Up @@ -2750,7 +2750,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)

#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL)
#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL)

static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
{
Expand Down
2 changes: 1 addition & 1 deletion fs/nfsd/acl.h
Expand Up @@ -49,7 +49,7 @@ struct svc_rqst;

struct nfs4_acl *nfs4_acl_new(int);
int nfs4_acl_get_whotype(char *, u32);
__be32 nfs4_acl_write_who(int who, __be32 **p, int *len);
__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who);

int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
struct nfs4_acl **acl);
Expand Down
5 changes: 1 addition & 4 deletions fs/nfsd/auth.c
@@ -1,7 +1,6 @@
/* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */

#include <linux/sched.h>
#include <linux/user_namespace.h>
#include "nfsd.h"
#include "auth.h"

Expand All @@ -25,7 +24,6 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
struct cred *new;
int i;
int flags = nfsexp_flags(rqstp, exp);
int ret;

validate_process_creds();

Expand Down Expand Up @@ -86,8 +84,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
return 0;

oom:
ret = -ENOMEM;
abort_creds(new);
return ret;
return -ENOMEM;
}

88 changes: 55 additions & 33 deletions fs/nfsd/export.c
Expand Up @@ -17,17 +17,12 @@
#include <linux/exportfs.h>
#include <linux/sunrpc/svc_xprt.h>

#include <net/ipv6.h>

#include "nfsd.h"
#include "nfsfh.h"
#include "netns.h"

#define NFSDDBG_FACILITY NFSDDBG_EXPORT

typedef struct auth_domain svc_client;
typedef struct svc_export svc_export;

/*
* We have two caches.
* One maps client+vfsmnt+dentry to export options - the export map
Expand Down Expand Up @@ -73,7 +68,7 @@ static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_

static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
{
/* client fsidtype fsid [path] */
/* client fsidtype fsid expiry [path] */
char *buf;
int len;
struct auth_domain *dom = NULL;
Expand Down Expand Up @@ -295,13 +290,19 @@ svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,

static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
{
struct nfsd4_fs_location *locations = fsloc->locations;
int i;

if (!locations)
return;

for (i = 0; i < fsloc->locations_count; i++) {
kfree(fsloc->locations[i].path);
kfree(fsloc->locations[i].hosts);
kfree(locations[i].path);
kfree(locations[i].hosts);
}
kfree(fsloc->locations);

kfree(locations);
fsloc->locations = NULL;
}

static void svc_export_put(struct kref *ref)
Expand Down Expand Up @@ -388,6 +389,10 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
int len;
int migrated, i, err;

/* more than one fsloc */
if (fsloc->locations)
return -EINVAL;

/* listsize */
err = get_uint(mesg, &fsloc->locations_count);
if (err)
Expand Down Expand Up @@ -437,13 +442,18 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)

static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
{
int listsize, err;
struct exp_flavor_info *f;
u32 listsize;
int err;

/* more than one secinfo */
if (exp->ex_nflavors)
return -EINVAL;

err = get_int(mesg, &listsize);
err = get_uint(mesg, &listsize);
if (err)
return err;
if (listsize < 0 || listsize > MAX_SECINFO_LIST)
if (listsize > MAX_SECINFO_LIST)
return -EINVAL;

for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
Expand Down Expand Up @@ -474,6 +484,27 @@ static inline int
secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
#endif

static inline int
uuid_parse(char **mesg, char *buf, unsigned char **puuid)
{
int len;

/* more than one uuid */
if (*puuid)
return -EINVAL;

/* expect a 16 byte uuid encoded as \xXXXX... */
len = qword_get(mesg, buf, PAGE_SIZE);
if (len != EX_UUID_LEN)
return -EINVAL;

*puuid = kmemdup(buf, EX_UUID_LEN, GFP_KERNEL);
if (*puuid == NULL)
return -ENOMEM;

return 0;
}

static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
{
/* client path expiry [flags anonuid anongid fsid] */
Expand Down Expand Up @@ -552,18 +583,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
if (strcmp(buf, "fsloc") == 0)
err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
else if (strcmp(buf, "uuid") == 0) {
/* expect a 16 byte uuid encoded as \xXXXX... */
len = qword_get(&mesg, buf, PAGE_SIZE);
if (len != 16)
err = -EINVAL;
else {
exp.ex_uuid =
kmemdup(buf, 16, GFP_KERNEL);
if (exp.ex_uuid == NULL)
err = -ENOMEM;
}
} else if (strcmp(buf, "secinfo") == 0)
else if (strcmp(buf, "uuid") == 0)
err = uuid_parse(&mesg, buf, &exp.ex_uuid);
else if (strcmp(buf, "secinfo") == 0)
err = secinfo_parse(&mesg, buf, &exp);
else
/* quietly ignore unknown words and anything
Expand Down Expand Up @@ -649,7 +671,7 @@ static int svc_export_show(struct seq_file *m,
if (exp->ex_uuid) {
int i;
seq_puts(m, ",uuid=");
for (i=0; i<16; i++) {
for (i = 0; i < EX_UUID_LEN; i++) {
if ((i&3) == 0 && i)
seq_putc(m, ':');
seq_printf(m, "%02x", exp->ex_uuid[i]);
Expand Down Expand Up @@ -771,7 +793,7 @@ svc_export_update(struct svc_export *new, struct svc_export *old)


static struct svc_expkey *
exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
u32 *fsidv, struct cache_req *reqp)
{
struct svc_expkey key, *ek;
Expand All @@ -793,9 +815,9 @@ exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
return ek;
}


static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
const struct path *path, struct cache_req *reqp)
static struct svc_export *
exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
const struct path *path, struct cache_req *reqp)
{
struct svc_export *exp, key;
int err;
Expand All @@ -819,11 +841,11 @@ static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
/*
* Find the export entry for a given dentry.
*/
static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
struct path *path)
static struct svc_export *
exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
{
struct dentry *saved = dget(path->dentry);
svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
struct svc_export *exp = exp_get_by_name(cd, clp, path, NULL);

while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
struct dentry *parent = dget_parent(path->dentry);
Expand All @@ -844,7 +866,7 @@ static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
* since its harder to fool a kernel module than a user space program.
*/
int
exp_rootfh(struct net *net, svc_client *clp, char *name,
exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
struct knfsd_fh *f, int maxsize)
{
struct svc_export *exp;
Expand Down
14 changes: 7 additions & 7 deletions include/linux/nfsd/export.h → fs/nfsd/export.h
@@ -1,17 +1,16 @@
/*
* include/linux/nfsd/export.h
*
* Public declarations for NFS exports. The definitions for the
* syscall interface are in nfsctl.h
*
* Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
*/
#ifndef NFSD_EXPORT_H
#define NFSD_EXPORT_H

# include <linux/nfsd/nfsfh.h>
#include <linux/sunrpc/cache.h>
#include <uapi/linux/nfsd/export.h>

struct knfsd_fh;
struct svc_fh;
struct svc_rqst;

/*
* FS Locations
*/
Expand All @@ -38,6 +37,7 @@ struct nfsd4_fs_locations {
* spkm3i, and spkm3p (and using all 8 at once should be rare).
*/
#define MAX_SECINFO_LIST 8
#define EX_UUID_LEN 16

struct exp_flavor_info {
u32 pseudoflavor;
Expand All @@ -54,7 +54,7 @@ struct svc_export {
int ex_fsid;
unsigned char * ex_uuid; /* 16 byte fsid */
struct nfsd4_fs_locations ex_fslocs;
int ex_nflavors;
uint32_t ex_nflavors;
struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST];
struct cache_detail *cd;
};
Expand Down
15 changes: 2 additions & 13 deletions fs/nfsd/fault_inject.c
Expand Up @@ -97,25 +97,14 @@ static ssize_t fault_inject_read(struct file *file, char __user *buf,
{
static u64 val;
char read_buf[25];
size_t size, ret;
size_t size;
loff_t pos = *ppos;

if (!pos)
nfsd_inject_get(file_inode(file)->i_private, &val);
size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);

if (pos < 0)
return -EINVAL;
if (pos >= size || !len)
return 0;
if (len > size - pos)
len = size - pos;
ret = copy_to_user(buf, read_buf + pos, len);
if (ret == len)
return -EFAULT;
len -= ret;
*ppos = pos + len;
return len;
return simple_read_from_buffer(buf, len, ppos, read_buf, size);
}

static ssize_t fault_inject_write(struct file *file, const char __user *buf,
Expand Down
4 changes: 2 additions & 2 deletions fs/nfsd/idmap.h
Expand Up @@ -56,7 +56,7 @@ static inline void nfsd_idmap_shutdown(struct net *net)

__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *);
__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *);
__be32 nfsd4_encode_user(struct svc_rqst *, kuid_t, __be32 **, int *);
__be32 nfsd4_encode_group(struct svc_rqst *, kgid_t, __be32 **, int *);
__be32 nfsd4_encode_user(struct xdr_stream *, struct svc_rqst *, kuid_t);
__be32 nfsd4_encode_group(struct xdr_stream *, struct svc_rqst *, kgid_t);

#endif /* LINUX_NFSD_IDMAP_H */

0 comments on commit 5b174fd

Please sign in to comment.