Merge branch 'for-4.0' of git://linux-nfs.org/~bfields/linux
Pull nfsd fixes from Bruce Fields: "Two main issues: - We found that turning on pNFS by default (when it's configured at build time) was too aggressive, so we want to switch the default before the 4.0 release. - Recent client changes to increase open parallelism uncovered a serious bug lurking in the server's open code. Also fix a krb5/selinux regression. The rest is mainly smaller pNFS fixes" * 'for-4.0' of git://linux-nfs.org/~bfields/linux: sunrpc: make debugfs file creation failure non-fatal nfsd: require an explicit option to enable pNFS NFSD: Fix bad update of layout in nfsd4_return_file_layout NFSD: Take care the return value from nfsd4_encode_stateid NFSD: Printk blocklayout length and offset as format 0x%llx nfsd: return correct lockowner when there is a race on hash insert nfsd: return correct openowner when there is a race to put one in the hash NFSD: Put exports after nfsd4_layout_verify fail NFSD: Error out when register_shrinker() fail NFSD: Take care the return value from nfsd4_decode_stateid NFSD: Check layout type when returning client layouts NFSD: restore trace event lost in mismerge
This commit is contained in:
commit
1e848913f0
|
@ -137,7 +137,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp,
|
|||
seg->offset = iomap.offset;
|
||||
seg->length = iomap.length;
|
||||
|
||||
dprintk("GET: %lld:%lld %d\n", bex->foff, bex->len, bex->es);
|
||||
dprintk("GET: 0x%llx:0x%llx %d\n", bex->foff, bex->len, bex->es);
|
||||
return 0;
|
||||
|
||||
out_error:
|
||||
|
|
|
@ -122,19 +122,19 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp,
|
|||
|
||||
p = xdr_decode_hyper(p, &bex.foff);
|
||||
if (bex.foff & (block_size - 1)) {
|
||||
dprintk("%s: unaligned offset %lld\n",
|
||||
dprintk("%s: unaligned offset 0x%llx\n",
|
||||
__func__, bex.foff);
|
||||
goto fail;
|
||||
}
|
||||
p = xdr_decode_hyper(p, &bex.len);
|
||||
if (bex.len & (block_size - 1)) {
|
||||
dprintk("%s: unaligned length %lld\n",
|
||||
dprintk("%s: unaligned length 0x%llx\n",
|
||||
__func__, bex.foff);
|
||||
goto fail;
|
||||
}
|
||||
p = xdr_decode_hyper(p, &bex.soff);
|
||||
if (bex.soff & (block_size - 1)) {
|
||||
dprintk("%s: unaligned disk offset %lld\n",
|
||||
dprintk("%s: unaligned disk offset 0x%llx\n",
|
||||
__func__, bex.soff);
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
|
|||
{
|
||||
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
|
||||
|
||||
if (exp->ex_flags & NFSEXP_NOPNFS)
|
||||
if (!(exp->ex_flags & NFSEXP_PNFS))
|
||||
return;
|
||||
|
||||
if (sb->s_export_op->get_uuid &&
|
||||
|
@ -440,15 +440,14 @@ nfsd4_return_file_layout(struct nfs4_layout *lp, struct nfsd4_layout_seg *seg,
|
|||
list_move_tail(&lp->lo_perstate, reaplist);
|
||||
return;
|
||||
}
|
||||
end = seg->offset;
|
||||
lo->offset = layout_end(seg);
|
||||
} else {
|
||||
/* retain the whole layout segment on a split. */
|
||||
if (layout_end(seg) < end) {
|
||||
dprintk("%s: split not supported\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
lo->offset = layout_end(seg);
|
||||
end = seg->offset;
|
||||
}
|
||||
|
||||
layout_update_len(lo, end);
|
||||
|
@ -513,6 +512,9 @@ nfsd4_return_client_layouts(struct svc_rqst *rqstp,
|
|||
|
||||
spin_lock(&clp->cl_lock);
|
||||
list_for_each_entry_safe(ls, n, &clp->cl_lo_states, ls_perclnt) {
|
||||
if (ls->ls_layout_type != lrp->lr_layout_type)
|
||||
continue;
|
||||
|
||||
if (lrp->lr_return_type == RETURN_FSID &&
|
||||
!fh_fsid_match(&ls->ls_stid.sc_file->fi_fhandle,
|
||||
&cstate->current_fh.fh_handle))
|
||||
|
@ -587,6 +589,8 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls)
|
|||
|
||||
rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str));
|
||||
|
||||
trace_layout_recall_fail(&ls->ls_stid.sc_stateid);
|
||||
|
||||
printk(KERN_WARNING
|
||||
"nfsd: client %s failed to respond to layout recall. "
|
||||
" Fencing..\n", addr_str);
|
||||
|
|
|
@ -1237,8 +1237,8 @@ nfsd4_getdeviceinfo(struct svc_rqst *rqstp,
|
|||
nfserr = ops->proc_getdeviceinfo(exp->ex_path.mnt->mnt_sb, gdp);
|
||||
|
||||
gdp->gd_notify_types &= ops->notify_types;
|
||||
exp_put(exp);
|
||||
out:
|
||||
exp_put(exp);
|
||||
return nfserr;
|
||||
}
|
||||
|
||||
|
|
|
@ -3221,7 +3221,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
|
|||
} else
|
||||
nfs4_free_openowner(&oo->oo_owner);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
return oo;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
|
||||
|
@ -5062,7 +5062,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp,
|
|||
} else
|
||||
nfs4_free_lockowner(&lo->lo_owner);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
return lo;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1562,7 +1562,11 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
|
|||
p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
|
||||
p = xdr_decode_hyper(p, &lgp->lg_seg.length);
|
||||
p = xdr_decode_hyper(p, &lgp->lg_minlength);
|
||||
nfsd4_decode_stateid(argp, &lgp->lg_sid);
|
||||
|
||||
status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
READ_BUF(4);
|
||||
lgp->lg_maxcount = be32_to_cpup(p++);
|
||||
|
||||
|
@ -1580,7 +1584,11 @@ nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
|
|||
p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
|
||||
p = xdr_decode_hyper(p, &lcp->lc_seg.length);
|
||||
lcp->lc_reclaim = be32_to_cpup(p++);
|
||||
nfsd4_decode_stateid(argp, &lcp->lc_sid);
|
||||
|
||||
status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
READ_BUF(4);
|
||||
lcp->lc_newoffset = be32_to_cpup(p++);
|
||||
if (lcp->lc_newoffset) {
|
||||
|
@ -1628,7 +1636,11 @@ nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
|
|||
READ_BUF(16);
|
||||
p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
|
||||
p = xdr_decode_hyper(p, &lrp->lr_seg.length);
|
||||
nfsd4_decode_stateid(argp, &lrp->lr_sid);
|
||||
|
||||
status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
READ_BUF(4);
|
||||
lrp->lrf_body_len = be32_to_cpup(p++);
|
||||
if (lrp->lrf_body_len > 0) {
|
||||
|
@ -4123,7 +4135,7 @@ nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(lrp->lrs_present);
|
||||
if (lrp->lrs_present)
|
||||
nfsd4_encode_stateid(xdr, &lrp->lr_sid);
|
||||
return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
|
||||
return nfs_ok;
|
||||
}
|
||||
#endif /* CONFIG_NFSD_PNFS */
|
||||
|
|
|
@ -165,13 +165,17 @@ int nfsd_reply_cache_init(void)
|
|||
{
|
||||
unsigned int hashsize;
|
||||
unsigned int i;
|
||||
int status = 0;
|
||||
|
||||
max_drc_entries = nfsd_cache_size_limit();
|
||||
atomic_set(&num_drc_entries, 0);
|
||||
hashsize = nfsd_hashsize(max_drc_entries);
|
||||
maskbits = ilog2(hashsize);
|
||||
|
||||
register_shrinker(&nfsd_reply_cache_shrinker);
|
||||
status = register_shrinker(&nfsd_reply_cache_shrinker);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
|
||||
0, 0, NULL);
|
||||
if (!drc_slab)
|
||||
|
|
|
@ -60,17 +60,17 @@ struct rpc_xprt;
|
|||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
void rpc_register_sysctl(void);
|
||||
void rpc_unregister_sysctl(void);
|
||||
int sunrpc_debugfs_init(void);
|
||||
void sunrpc_debugfs_init(void);
|
||||
void sunrpc_debugfs_exit(void);
|
||||
int rpc_clnt_debugfs_register(struct rpc_clnt *);
|
||||
void rpc_clnt_debugfs_register(struct rpc_clnt *);
|
||||
void rpc_clnt_debugfs_unregister(struct rpc_clnt *);
|
||||
int rpc_xprt_debugfs_register(struct rpc_xprt *);
|
||||
void rpc_xprt_debugfs_register(struct rpc_xprt *);
|
||||
void rpc_xprt_debugfs_unregister(struct rpc_xprt *);
|
||||
#else
|
||||
static inline int
|
||||
static inline void
|
||||
sunrpc_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -79,10 +79,10 @@ sunrpc_debugfs_exit(void)
|
|||
return;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline void
|
||||
rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -91,10 +91,10 @@ rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
|
|||
return;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline void
|
||||
rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
* exported filesystem.
|
||||
*/
|
||||
#define NFSEXP_V4ROOT 0x10000
|
||||
#define NFSEXP_NOPNFS 0x20000
|
||||
#define NFSEXP_PNFS 0x20000
|
||||
|
||||
/* All flags that we claim to support. (Note we don't support NOACL.) */
|
||||
#define NFSEXP_ALLFLAGS 0x3FE7F
|
||||
|
|
|
@ -303,9 +303,7 @@ static int rpc_client_register(struct rpc_clnt *clnt,
|
|||
struct super_block *pipefs_sb;
|
||||
int err;
|
||||
|
||||
err = rpc_clnt_debugfs_register(clnt);
|
||||
if (err)
|
||||
return err;
|
||||
rpc_clnt_debugfs_register(clnt);
|
||||
|
||||
pipefs_sb = rpc_get_sb_net(net);
|
||||
if (pipefs_sb) {
|
||||
|
|
|
@ -129,48 +129,52 @@ static const struct file_operations tasks_fops = {
|
|||
.release = tasks_release,
|
||||
};
|
||||
|
||||
int
|
||||
void
|
||||
rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
|
||||
{
|
||||
int len, err;
|
||||
int len;
|
||||
char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */
|
||||
struct rpc_xprt *xprt;
|
||||
|
||||
/* Already registered? */
|
||||
if (clnt->cl_debugfs)
|
||||
return 0;
|
||||
if (clnt->cl_debugfs || !rpc_clnt_dir)
|
||||
return;
|
||||
|
||||
len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
|
||||
if (len >= sizeof(name))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
/* make the per-client dir */
|
||||
clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
|
||||
if (!clnt->cl_debugfs)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
|
||||
/* make tasks file */
|
||||
err = -ENOMEM;
|
||||
if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
|
||||
clnt, &tasks_fops))
|
||||
goto out_err;
|
||||
|
||||
err = -EINVAL;
|
||||
rcu_read_lock();
|
||||
xprt = rcu_dereference(clnt->cl_xprt);
|
||||
/* no "debugfs" dentry? Don't bother with the symlink. */
|
||||
if (!xprt->debugfs) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
len = snprintf(name, sizeof(name), "../../rpc_xprt/%s",
|
||||
rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name);
|
||||
xprt->debugfs->d_name.name);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (len >= sizeof(name))
|
||||
goto out_err;
|
||||
|
||||
err = -ENOMEM;
|
||||
if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name))
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
return;
|
||||
out_err:
|
||||
debugfs_remove_recursive(clnt->cl_debugfs);
|
||||
clnt->cl_debugfs = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -226,33 +230,33 @@ static const struct file_operations xprt_info_fops = {
|
|||
.release = xprt_info_release,
|
||||
};
|
||||
|
||||
int
|
||||
void
|
||||
rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
|
||||
{
|
||||
int len, id;
|
||||
static atomic_t cur_id;
|
||||
char name[9]; /* 8 hex digits + NULL term */
|
||||
|
||||
if (!rpc_xprt_dir)
|
||||
return;
|
||||
|
||||
id = (unsigned int)atomic_inc_return(&cur_id);
|
||||
|
||||
len = snprintf(name, sizeof(name), "%x", id);
|
||||
if (len >= sizeof(name))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
/* make the per-client dir */
|
||||
xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir);
|
||||
if (!xprt->debugfs)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
|
||||
/* make tasks file */
|
||||
if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs,
|
||||
xprt, &xprt_info_fops)) {
|
||||
debugfs_remove_recursive(xprt->debugfs);
|
||||
xprt->debugfs = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -266,14 +270,17 @@ void __exit
|
|||
sunrpc_debugfs_exit(void)
|
||||
{
|
||||
debugfs_remove_recursive(topdir);
|
||||
topdir = NULL;
|
||||
rpc_clnt_dir = NULL;
|
||||
rpc_xprt_dir = NULL;
|
||||
}
|
||||
|
||||
int __init
|
||||
void __init
|
||||
sunrpc_debugfs_init(void)
|
||||
{
|
||||
topdir = debugfs_create_dir("sunrpc", NULL);
|
||||
if (!topdir)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
|
||||
if (!rpc_clnt_dir)
|
||||
|
@ -283,10 +290,9 @@ sunrpc_debugfs_init(void)
|
|||
if (!rpc_xprt_dir)
|
||||
goto out_remove;
|
||||
|
||||
return 0;
|
||||
return;
|
||||
out_remove:
|
||||
debugfs_remove_recursive(topdir);
|
||||
topdir = NULL;
|
||||
out:
|
||||
return -ENOMEM;
|
||||
rpc_clnt_dir = NULL;
|
||||
}
|
||||
|
|
|
@ -98,10 +98,7 @@ init_sunrpc(void)
|
|||
if (err)
|
||||
goto out4;
|
||||
|
||||
err = sunrpc_debugfs_init();
|
||||
if (err)
|
||||
goto out5;
|
||||
|
||||
sunrpc_debugfs_init();
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
rpc_register_sysctl();
|
||||
#endif
|
||||
|
@ -109,8 +106,6 @@ init_sunrpc(void)
|
|||
init_socket_xprt(); /* clnt sock transport */
|
||||
return 0;
|
||||
|
||||
out5:
|
||||
unregister_rpc_pipefs();
|
||||
out4:
|
||||
unregister_pernet_subsys(&sunrpc_net_ops);
|
||||
out3:
|
||||
|
|
|
@ -1331,7 +1331,6 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
|
|||
*/
|
||||
struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
|
||||
{
|
||||
int err;
|
||||
struct rpc_xprt *xprt;
|
||||
struct xprt_class *t;
|
||||
|
||||
|
@ -1372,11 +1371,7 @@ found:
|
|||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
err = rpc_xprt_debugfs_register(xprt);
|
||||
if (err) {
|
||||
xprt_destroy(xprt);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
rpc_xprt_debugfs_register(xprt);
|
||||
|
||||
dprintk("RPC: created transport %p with %u slots\n", xprt,
|
||||
xprt->max_reqs);
|
||||
|
|
Loading…
Reference in New Issue