Skip to content

Commit

Permalink
Merge tag 'nfs-for-6.1-1' of git://git.linux-nfs.org/projects/anna/li…
Browse files Browse the repository at this point in the history
…nux-nfs

Pull NFS client updates from Anna Schumaker:
 "New Features:
   - Add NFSv4.2 xattr tracepoints
   - Replace xprtiod WQ in rpcrdma
   - Flexfiles cancels I/O on layout recall or revoke

  Bugfixes and Cleanups:
   - Directly use ida_alloc() / ida_free()
   - Don't open-code max_t()
   - Prefer using strscpy over strlcpy
   - Remove unused forward declarations
   - Always return layout states on flexfiles layout return
   - Have LISTXATTR treat NFS4ERR_NOXATTR as an empty reply instead of
     error
   - Allow more xprtrdma memory allocations to fail without triggering a
     reclaim
   - Various other xprtrdma clean ups
   - Fix rpc_killall_tasks() races"

* tag 'nfs-for-6.1-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (27 commits)
  NFSv4/flexfiles: Cancel I/O if the layout is recalled or revoked
  SUNRPC: Add API to force the client to disconnect
  SUNRPC: Add a helper to allow pNFS drivers to selectively cancel RPC calls
  SUNRPC: Fix races with rpc_killall_tasks()
  xprtrdma: Fix uninitialized variable
  xprtrdma: Prevent memory allocations from driving a reclaim
  xprtrdma: Memory allocation should be allowed to fail during connect
  xprtrdma: MR-related memory allocation should be allowed to fail
  xprtrdma: Clean up synopsis of rpcrdma_regbuf_alloc()
  xprtrdma: Clean up synopsis of rpcrdma_req_create()
  svcrdma: Clean up RPCRDMA_DEF_GFP
  SUNRPC: Replace the use of the xprtiod WQ in rpcrdma
  NFSv4.2: Add a tracepoint for listxattr
  NFSv4.2: Add tracepoints for getxattr, setxattr, and removexattr
  NFSv4.2: Move TRACE_DEFINE_ENUM(NFS4_CONTENT_*) under CONFIG_NFS_V4_2
  NFSv4.2: Add special handling for LISTXATTR receiving NFS4ERR_NOXATTR
  nfs: remove nfs_wait_atomic_killable() and nfs_write_prepare() declaration
  NFSv4: remove nfs4_renewd_prepare_shutdown() declaration
  fs/nfs/pnfs_nfs.c: fix spelling typo and syntax error in comment
  NFSv4/pNFS: Always return layout stats on layout return for flexfiles
  ...
  • Loading branch information
torvalds committed Oct 13, 2022
2 parents 531d3b5 + b739a5b commit 66b8345
Show file tree
Hide file tree
Showing 30 changed files with 342 additions and 116 deletions.
6 changes: 3 additions & 3 deletions fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,9 +656,9 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
goto out;
}
if (mntflags & NFS_MOUNT_WRITE_WAIT) {
result = filemap_fdatawait_range(file->f_mapping,
iocb->ki_pos - written,
iocb->ki_pos - 1);
filemap_fdatawait_range(file->f_mapping,
iocb->ki_pos - written,
iocb->ki_pos - 1);
}
result = generic_write_sync(iocb, written);
if (result < 0)
Expand Down
109 changes: 99 additions & 10 deletions fs/nfs/flexfilelayout/flexfilelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@
#define FF_LAYOUT_POLL_RETRY_MAX (15*HZ)
#define FF_LAYOUTRETURN_MAXERR 20

enum nfs4_ff_op_type {
NFS4_FF_OP_LAYOUTSTATS,
NFS4_FF_OP_LAYOUTRETURN,
};

static unsigned short io_maxretrans;

static const struct pnfs_commit_ops ff_layout_commit_ops;
static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
struct nfs_pgio_header *hdr);
static int ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
struct nfs42_layoutstat_devinfo *devinfo,
int dev_limit);
int dev_limit, enum nfs4_ff_op_type type);
static void ff_layout_encode_ff_layoutupdate(struct xdr_stream *xdr,
const struct nfs42_layoutstat_devinfo *devinfo,
struct nfs4_ff_layout_mirror *mirror);
Expand Down Expand Up @@ -1373,6 +1379,11 @@ static int ff_layout_read_prepare_common(struct rpc_task *task,
return -EIO;
}

if (!pnfs_is_valid_lseg(hdr->lseg)) {
rpc_exit(task, -EAGAIN);
return -EAGAIN;
}

ff_layout_read_record_layoutstats_start(task, hdr);
return 0;
}
Expand Down Expand Up @@ -1553,6 +1564,11 @@ static int ff_layout_write_prepare_common(struct rpc_task *task,
return -EIO;
}

if (!pnfs_is_valid_lseg(hdr->lseg)) {
rpc_exit(task, -EAGAIN);
return -EAGAIN;
}

ff_layout_write_record_layoutstats_start(task, hdr);
return 0;
}
Expand Down Expand Up @@ -1645,15 +1661,23 @@ static void ff_layout_commit_record_layoutstats_done(struct rpc_task *task,
set_bit(NFS_LSEG_LAYOUTRETURN, &cdata->lseg->pls_flags);
}

static void ff_layout_commit_prepare_common(struct rpc_task *task,
struct nfs_commit_data *cdata)
static int ff_layout_commit_prepare_common(struct rpc_task *task,
struct nfs_commit_data *cdata)
{
if (!pnfs_is_valid_lseg(cdata->lseg)) {
rpc_exit(task, -EAGAIN);
return -EAGAIN;
}

ff_layout_commit_record_layoutstats_start(task, cdata);
return 0;
}

static void ff_layout_commit_prepare_v3(struct rpc_task *task, void *data)
{
ff_layout_commit_prepare_common(task, data);
if (ff_layout_commit_prepare_common(task, data))
return;

rpc_call_start(task);
}

Expand Down Expand Up @@ -1949,6 +1973,65 @@ ff_layout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
ff_layout_initiate_commit);
}

static bool ff_layout_match_rw(const struct rpc_task *task,
const struct nfs_pgio_header *hdr,
const struct pnfs_layout_segment *lseg)
{
return hdr->lseg == lseg;
}

static bool ff_layout_match_commit(const struct rpc_task *task,
const struct nfs_commit_data *cdata,
const struct pnfs_layout_segment *lseg)
{
return cdata->lseg == lseg;
}

static bool ff_layout_match_io(const struct rpc_task *task, const void *data)
{
const struct rpc_call_ops *ops = task->tk_ops;

if (ops == &ff_layout_read_call_ops_v3 ||
ops == &ff_layout_read_call_ops_v4 ||
ops == &ff_layout_write_call_ops_v3 ||
ops == &ff_layout_write_call_ops_v4)
return ff_layout_match_rw(task, task->tk_calldata, data);
if (ops == &ff_layout_commit_call_ops_v3 ||
ops == &ff_layout_commit_call_ops_v4)
return ff_layout_match_commit(task, task->tk_calldata, data);
return false;
}

static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
{
struct nfs4_ff_layout_segment *flseg = FF_LAYOUT_LSEG(lseg);
struct nfs4_ff_layout_mirror *mirror;
struct nfs4_ff_layout_ds *mirror_ds;
struct nfs4_pnfs_ds *ds;
struct nfs_client *ds_clp;
struct rpc_clnt *clnt;
u32 idx;

for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
mirror = flseg->mirror_array[idx];
mirror_ds = mirror->mirror_ds;
if (!mirror_ds)
continue;
ds = mirror->mirror_ds->ds;
if (!ds)
continue;
ds_clp = ds->ds_clp;
if (!ds_clp)
continue;
clnt = ds_clp->cl_rpcclient;
if (!clnt)
continue;
if (!rpc_cancel_tasks(clnt, -EAGAIN, ff_layout_match_io, lseg))
continue;
rpc_clnt_disconnect(clnt);
}
}

static struct pnfs_ds_commit_info *
ff_layout_get_ds_info(struct inode *inode)
{
Expand Down Expand Up @@ -2161,8 +2244,9 @@ ff_layout_prepare_layoutreturn(struct nfs4_layoutreturn_args *args)
FF_LAYOUTRETURN_MAXERR);

spin_lock(&args->inode->i_lock);
ff_args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr,
&ff_args->devinfo[0], ARRAY_SIZE(ff_args->devinfo));
ff_args->num_dev = ff_layout_mirror_prepare_stats(
&ff_layout->generic_hdr, &ff_args->devinfo[0],
ARRAY_SIZE(ff_args->devinfo), NFS4_FF_OP_LAYOUTRETURN);
spin_unlock(&args->inode->i_lock);

args->ld_private->ops = &layoutreturn_ops;
Expand Down Expand Up @@ -2396,7 +2480,7 @@ static const struct nfs4_xdr_opaque_ops layoutstat_ops = {
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
struct nfs42_layoutstat_devinfo *devinfo,
int dev_limit)
int dev_limit, enum nfs4_ff_op_type type)
{
struct nfs4_flexfile_layout *ff_layout = FF_LAYOUT_FROM_HDR(lo);
struct nfs4_ff_layout_mirror *mirror;
Expand All @@ -2408,7 +2492,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
break;
if (IS_ERR_OR_NULL(mirror->mirror_ds))
continue;
if (!test_and_clear_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags))
if (!test_and_clear_bit(NFS4_FF_MIRROR_STAT_AVAIL,
&mirror->flags) &&
type != NFS4_FF_OP_LAYOUTRETURN)
continue;
/* mirror refcount put in cleanup_layoutstats */
if (!refcount_inc_not_zero(&mirror->ref))
Expand Down Expand Up @@ -2448,7 +2534,9 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
spin_lock(&args->inode->i_lock);
ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout);
args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr,
&args->devinfo[0], dev_count);
&args->devinfo[0],
dev_count,
NFS4_FF_OP_LAYOUTSTATS);
spin_unlock(&args->inode->i_lock);
if (!args->num_dev) {
kfree(args->devinfo);
Expand Down Expand Up @@ -2501,6 +2589,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
.prepare_layoutreturn = ff_layout_prepare_layoutreturn,
.sync = pnfs_nfs_generic_sync,
.prepare_layoutstats = ff_layout_prepare_layoutstats,
.cancel_io = ff_layout_cancel_io,
};

static int __init nfs4flexfilelayout_init(void)
Expand Down
6 changes: 3 additions & 3 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ struct nfs_find_desc {
static int
nfs_find_actor(struct inode *inode, void *opaque)
{
struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque;
struct nfs_find_desc *desc = opaque;
struct nfs_fh *fh = desc->fh;
struct nfs_fattr *fattr = desc->fattr;

Expand All @@ -331,7 +331,7 @@ nfs_find_actor(struct inode *inode, void *opaque)
static int
nfs_init_locked(struct inode *inode, void *opaque)
{
struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque;
struct nfs_find_desc *desc = opaque;
struct nfs_fattr *fattr = desc->fattr;

set_nfs_fileid(inode, fattr->fileid);
Expand Down Expand Up @@ -2267,7 +2267,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)

static void init_once(void *foo)
{
struct nfs_inode *nfsi = (struct nfs_inode *) foo;
struct nfs_inode *nfsi = foo;

inode_init_once(&nfsi->vfs_inode);
INIT_LIST_HEAD(&nfsi->open_files);
Expand Down
2 changes: 0 additions & 2 deletions fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,6 @@ extern void nfs_zap_acl_cache(struct inode *inode);
extern void nfs_set_cache_invalid(struct inode *inode, unsigned long flags);
extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);

/* super.c */
extern const struct super_operations nfs_sops;
Expand Down Expand Up @@ -503,7 +502,6 @@ extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
const struct nfs_pgio_completion_ops *compl_ops);
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
extern void nfs_commit_free(struct nfs_commit_data *p);
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
extern int nfs_initiate_commit(struct rpc_clnt *clnt,
struct nfs_commit_data *data,
Expand Down
4 changes: 4 additions & 0 deletions fs/nfs/nfs42proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ static int _nfs42_proc_removexattr(struct inode *inode, const char *name)

ret = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
&res.seq_res, 1);
trace_nfs4_removexattr(inode, name, ret);
if (!ret)
nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);

Expand Down Expand Up @@ -1214,6 +1215,7 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,

ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
&res.seq_res, 1);
trace_nfs4_setxattr(inode, name, ret);

for (; np > 0; np--)
put_page(pages[np - 1]);
Expand Down Expand Up @@ -1246,6 +1248,7 @@ static ssize_t _nfs42_proc_getxattr(struct inode *inode, const char *name,

ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
&res.seq_res, 0);
trace_nfs4_getxattr(inode, name, ret);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -1317,6 +1320,7 @@ static ssize_t _nfs42_proc_listxattrs(struct inode *inode, void *buf,

ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
&res.seq_res, 0);
trace_nfs4_listxattr(inode, ret);

if (ret >= 0) {
ret = res.copied;
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs42xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ nfs4_xattr_entry_count(struct shrinker *shrink, struct shrink_control *sc)

static void nfs4_xattr_cache_init_once(void *p)
{
struct nfs4_xattr_cache *cache = (struct nfs4_xattr_cache *)p;
struct nfs4_xattr_cache *cache = p;

spin_lock_init(&cache->listxattr_lock);
atomic_long_set(&cache->nent, 0);
Expand Down
8 changes: 8 additions & 0 deletions fs/nfs/nfs42xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,14 @@ static int decode_listxattrs(struct xdr_stream *xdr,
*/
if (status == -ETOOSMALL)
status = -ERANGE;
/*
* Special case: for LISTXATTRS, NFS4ERR_NOXATTR
* should be translated to success with zero-length reply.
*/
if (status == -ENODATA) {
res->eof = true;
status = 0;
}
goto out;
}

Expand Down
1 change: 0 additions & 1 deletion fs/nfs/nfs4_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);

/* nfs4renewd.c */
extern void nfs4_schedule_state_renewal(struct nfs_client *);
extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
extern void nfs4_kill_renewd(struct nfs_client *);
extern void nfs4_renew_state(struct work_struct *);
extern void nfs4_set_lease_period(struct nfs_client *clp, unsigned long lease);
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs4client.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
goto error;
ip_addr = (const char *)buf;
}
strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
strscpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));

err = nfs_idmap_new(clp);
if (err < 0) {
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs4idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux)
struct request_key_auth *rka = get_request_key_auth(authkey);
struct rpc_pipe_msg *msg;
struct idmap_msg *im;
struct idmap *idmap = (struct idmap *)aux;
struct idmap *idmap = aux;
struct key *key = rka->target_key;
int ret = -ENOKEY;

Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6608,7 +6608,7 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
struct nfs4_delegreturndata *d_data;
struct pnfs_layout_hdr *lo;

d_data = (struct nfs4_delegreturndata *)data;
d_data = data;

if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) {
nfs4_sequence_done(task, &d_data->res.seq_res);
Expand Down Expand Up @@ -8900,7 +8900,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred)
void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
void *data)
{
struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
struct nfs4_add_xprt_data *adata = data;
struct rpc_task *task;
int status;

Expand Down
10 changes: 4 additions & 6 deletions fs/nfs/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,7 @@ nfs4_alloc_state_owner(struct nfs_server *server,
sp = kzalloc(sizeof(*sp), gfp_flags);
if (!sp)
return NULL;
sp->so_seqid.owner_id = ida_simple_get(&server->openowner_id, 0, 0,
gfp_flags);
sp->so_seqid.owner_id = ida_alloc(&server->openowner_id, gfp_flags);
if (sp->so_seqid.owner_id < 0) {
kfree(sp);
return NULL;
Expand Down Expand Up @@ -534,7 +533,7 @@ static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
{
nfs4_destroy_seqid_counter(&sp->so_seqid);
put_cred(sp->so_cred);
ida_simple_remove(&sp->so_server->openowner_id, sp->so_seqid.owner_id);
ida_free(&sp->so_server->openowner_id, sp->so_seqid.owner_id);
kfree(sp);
}

Expand Down Expand Up @@ -877,8 +876,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
refcount_set(&lsp->ls_count, 1);
lsp->ls_state = state;
lsp->ls_owner = fl_owner;
lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id,
0, 0, GFP_KERNEL_ACCOUNT);
lsp->ls_seqid.owner_id = ida_alloc(&server->lockowner_id, GFP_KERNEL_ACCOUNT);
if (lsp->ls_seqid.owner_id < 0)
goto out_free;
INIT_LIST_HEAD(&lsp->ls_locks);
Expand All @@ -890,7 +888,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f

void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
{
ida_simple_remove(&server->lockowner_id, lsp->ls_seqid.owner_id);
ida_free(&server->lockowner_id, lsp->ls_seqid.owner_id);
nfs4_destroy_seqid_counter(&lsp->ls_seqid);
kfree(lsp);
}
Expand Down
Loading

0 comments on commit 66b8345

Please sign in to comment.