Skip to content

Commit

Permalink
Merge tag 'nfs-for-5.2-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:
 "Highlights include:

  Stable bugfixes:
   - Fall back to MDS if no deviceid is found rather than aborting   # v4.11+
   - NFS4: Fix v4.0 client state corruption when mount

  Features:
   - Much improved handling of soft mounts with NFS v4.0:
       - Reduce risk of false positive timeouts
       - Faster failover of reads and writes after a timeout
       - Added a "softerr" mount option to return ETIMEDOUT instead of
         EIO to the application after a timeout
   - Increase number of xprtrdma backchannel requests
   - Add additional xprtrdma tracepoints
   - Improved send completion batching for xprtrdma

  Other bugfixes and cleanups:
   - Return -EINVAL when NFS v4.2 is passed an invalid dedup mode
   - Reduce usage of GFP_ATOMIC pages in SUNRPC
   - Various minor NFS over RDMA cleanups and bugfixes
   - Use the correct container namespace for upcalls
   - Don't share superblocks between user namespaces
   - Various other container fixes
   - Make nfs_match_client() killable to prevent soft lockups
   - Don't mark all open state for recovery when handling recallable
     state revoked flag"

* tag 'nfs-for-5.2-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (69 commits)
  SUNRPC: Rebalance a kref in auth_gss.c
  NFS: Fix a double unlock from nfs_match,get_client
  nfs: pass the correct prototype to read_cache_page
  NFSv4: don't mark all open state for recovery when handling recallable state revoked flag
  SUNRPC: Fix an error code in gss_alloc_msg()
  SUNRPC: task should be exit if encode return EKEYEXPIRED more times
  NFS4: Fix v4.0 client state corruption when mount
  PNFS fallback to MDS if no deviceid found
  NFS: make nfs_match_client killable
  lockd: Store the lockd client credential in struct nlm_host
  NFS: When mounting, don't share filesystems between different user namespaces
  NFS: Convert NFSv2 to use the container user namespace
  NFSv4: Convert the NFS client idmapper to use the container user namespace
  NFS: Convert NFSv3 to use the container user namespace
  SUNRPC: Use namespace of listening daemon in the client AUTH_GSS upcall
  SUNRPC: Use the client user namespace when encoding creds
  NFS: Store the credential of the mount process in the nfs_server
  SUNRPC: Cache cred of process creating the rpc_client
  xprtrdma: Remove stale comment
  xprtrdma: Update comments that reference ib_drain_qp
  ...
  • Loading branch information
Linus Torvalds committed May 9, 2019
2 parents abde77e + 5940d1c commit 06cbd26
Show file tree
Hide file tree
Showing 59 changed files with 1,366 additions and 946 deletions.
2 changes: 1 addition & 1 deletion fs/lockd/clntlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init)
host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen,
nlm_init->protocol, nlm_version,
nlm_init->hostname, nlm_init->noresvport,
nlm_init->net);
nlm_init->net, nlm_init->cred);
if (host == NULL)
goto out_nohost;
if (host->h_rpcclnt == NULL && nlm_bind_host(host) == NULL)
Expand Down
4 changes: 2 additions & 2 deletions fs/lockd/clntproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
struct nlm_rqst *req = data;
u32 status = ntohl(req->a_res.status);

if (RPC_ASSASSINATED(task))
if (RPC_SIGNALLED(task))
goto die;

if (task->tk_status < 0) {
Expand Down Expand Up @@ -783,7 +783,7 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
struct nlm_rqst *req = data;
u32 status = ntohl(req->a_res.status);

if (RPC_ASSASSINATED(task))
if (RPC_SIGNALLED(task))
goto die;

if (task->tk_status < 0) {
Expand Down
10 changes: 9 additions & 1 deletion fs/lockd/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct nlm_lookup_host_info {
const size_t hostname_len; /* it's length */
const int noresvport; /* use non-priv port */
struct net *net; /* network namespace to bind */
const struct cred *cred;
};

/*
Expand Down Expand Up @@ -162,6 +163,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
host->h_nsmhandle = nsm;
host->h_addrbuf = nsm->sm_addrbuf;
host->net = ni->net;
host->h_cred = get_cred(ni->cred),
strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));

out:
Expand All @@ -188,6 +190,7 @@ static void nlm_destroy_host_locked(struct nlm_host *host)
clnt = host->h_rpcclnt;
if (clnt != NULL)
rpc_shutdown_client(clnt);
put_cred(host->h_cred);
kfree(host);

ln->nrhosts--;
Expand All @@ -202,6 +205,8 @@ static void nlm_destroy_host_locked(struct nlm_host *host)
* @version: NLM protocol version
* @hostname: '\0'-terminated hostname of server
* @noresvport: 1 if non-privileged port should be used
* @net: pointer to net namespace
* @cred: pointer to cred
*
* Returns an nlm_host structure that matches the passed-in
* [server address, transport protocol, NLM version, server hostname].
Expand All @@ -214,7 +219,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
const u32 version,
const char *hostname,
int noresvport,
struct net *net)
struct net *net,
const struct cred *cred)
{
struct nlm_lookup_host_info ni = {
.server = 0,
Expand All @@ -226,6 +232,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
.hostname_len = strlen(hostname),
.noresvport = noresvport,
.net = net,
.cred = cred,
};
struct hlist_head *chain;
struct nlm_host *host;
Expand Down Expand Up @@ -458,6 +465,7 @@ nlm_bind_host(struct nlm_host *host)
.authflavor = RPC_AUTH_UNIX,
.flags = (RPC_CLNT_CREATE_NOPING |
RPC_CLNT_CREATE_AUTOBIND),
.cred = host->h_cred,
};

/*
Expand Down
1 change: 1 addition & 0 deletions fs/lockd/mon.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
.version = NSM_VERSION,
.authflavor = RPC_AUTH_NULL,
.flags = RPC_CLNT_CREATE_NOPING,
.cred = current_cred(),
};

return rpc_create(&args);
Expand Down
16 changes: 15 additions & 1 deletion fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
struct nfs_client *clp;
const struct sockaddr *sap = data->addr;
struct nfs_net *nn = net_generic(data->net, nfs_net_id);
int error;

again:
list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
Expand All @@ -296,9 +297,11 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
if (clp->cl_cons_state > NFS_CS_READY) {
refcount_inc(&clp->cl_count);
spin_unlock(&nn->nfs_client_lock);
nfs_wait_client_init_complete(clp);
error = nfs_wait_client_init_complete(clp);
nfs_put_client(clp);
spin_lock(&nn->nfs_client_lock);
if (error < 0)
return ERR_PTR(error);
goto again;
}

Expand Down Expand Up @@ -407,6 +410,8 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
clp = nfs_match_client(cl_init);
if (clp) {
spin_unlock(&nn->nfs_client_lock);
if (IS_ERR(clp))
return clp;
if (new)
new->rpc_ops->free_client(new);
return nfs_found_client(cl_init, clp);
Expand Down Expand Up @@ -500,6 +505,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
.program = &nfs_program,
.version = clp->rpc_ops->version,
.authflavor = flavor,
.cred = cl_init->cred,
};

if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
Expand Down Expand Up @@ -598,6 +604,8 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
sizeof(server->client->cl_timeout_default));
server->client->cl_timeout = &server->client->cl_timeout_default;
server->client->cl_softrtry = 0;
if (server->flags & NFS_MOUNT_SOFTERR)
server->client->cl_softerr = 1;
if (server->flags & NFS_MOUNT_SOFT)
server->client->cl_softrtry = 1;

Expand Down Expand Up @@ -652,6 +660,7 @@ static int nfs_init_server(struct nfs_server *server,
.proto = data->nfs_server.protocol,
.net = data->net,
.timeparms = &timeparms,
.cred = server->cred,
};
struct nfs_client *clp;
int error;
Expand Down Expand Up @@ -920,6 +929,7 @@ void nfs_free_server(struct nfs_server *server)
ida_destroy(&server->lockowner_id);
ida_destroy(&server->openowner_id);
nfs_free_iostats(server->io_stats);
put_cred(server->cred);
kfree(server);
nfs_release_automount_timer();
}
Expand All @@ -940,6 +950,8 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
if (!server)
return ERR_PTR(-ENOMEM);

server->cred = get_cred(current_cred());

error = -ENOMEM;
fattr = nfs_alloc_fattr();
if (fattr == NULL)
Expand Down Expand Up @@ -1006,6 +1018,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
if (!server)
return ERR_PTR(-ENOMEM);

server->cred = get_cred(source->cred);

error = -ENOMEM;
fattr_fsinfo = nfs_alloc_fattr();
if (fattr_fsinfo == NULL)
Expand Down
12 changes: 12 additions & 0 deletions fs/nfs/delegation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,18 @@ void nfs_mark_test_expired_all_delegations(struct nfs_client *clp)
rcu_read_unlock();
}

/**
* nfs_test_expired_all_delegations - test all delegations for a client
* @clp: nfs_client to process
*
* Helper for handling "recallable state revoked" status from server.
*/
void nfs_test_expired_all_delegations(struct nfs_client *clp)
{
nfs_mark_test_expired_all_delegations(clp);
nfs4_schedule_state_manager(clp);
}

/**
* nfs_reap_expired_delegations - reap expired delegations
* @clp: nfs_client to process
Expand Down
1 change: 1 addition & 0 deletions fs/nfs/delegation.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp);
void nfs_delegation_reap_unclaimed(struct nfs_client *clp);

void nfs_mark_test_expired_all_delegations(struct nfs_client *clp);
void nfs_test_expired_all_delegations(struct nfs_client *clp);
void nfs_reap_expired_delegations(struct nfs_client *clp);

/* NFSv4 delegation-related procedures */
Expand Down
7 changes: 4 additions & 3 deletions fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,9 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
* We only need to convert from xdr once so future lookups are much simpler
*/
static
int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
int nfs_readdir_filler(void *data, struct page* page)
{
nfs_readdir_descriptor_t *desc = data;
struct inode *inode = file_inode(desc->file);
int ret;

Expand Down Expand Up @@ -762,8 +763,8 @@ void cache_page_release(nfs_readdir_descriptor_t *desc)
static
struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
{
return read_cache_page(desc->file->f_mapping,
desc->page_index, (filler_t *)nfs_readdir_filler, desc);
return read_cache_page(desc->file->f_mapping, desc->page_index,
nfs_readdir_filler, desc);
}

/*
Expand Down
11 changes: 9 additions & 2 deletions fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
struct nfs_page *req;
unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
/* XXX do we need to do the eof zeroing found in async_filler? */
req = nfs_create_request(dreq->ctx, pagevec[i], NULL,
req = nfs_create_request(dreq->ctx, pagevec[i],
pgbase, req_len);
if (IS_ERR(req)) {
result = PTR_ERR(req);
Expand Down Expand Up @@ -663,6 +663,8 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
}

list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
/* Bump the transmission count */
req->wb_nio++;
if (!nfs_pageio_add_request(&desc, req)) {
nfs_list_move_request(req, &failed);
spin_lock(&cinfo.inode->i_lock);
Expand Down Expand Up @@ -703,6 +705,11 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
req = nfs_list_entry(data->pages.next);
nfs_list_remove_request(req);
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
/*
* Despite the reboot, the write was successful,
* so reset wb_nio.
*/
req->wb_nio = 0;
/* Note the rewrite will go through mds */
nfs_mark_request_commit(req, NULL, &cinfo, 0);
} else
Expand Down Expand Up @@ -899,7 +906,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
struct nfs_page *req;
unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);

req = nfs_create_request(dreq->ctx, pagevec[i], NULL,
req = nfs_create_request(dreq->ctx, pagevec[i],
pgbase, req_len);
if (IS_ERR(req)) {
result = PTR_ERR(req);
Expand Down
31 changes: 7 additions & 24 deletions fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
return 0;

/* Flush writes to the server and return any errors */
return vfs_fsync(file, 0);
return nfs_wb_all(inode);
}

ssize_t
Expand Down Expand Up @@ -199,13 +199,6 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
* Flush any dirty pages for this process, and check for write errors.
* The return status from this call provides a reliable indication of
* whether any write errors occurred for this process.
*
* Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
* disk, but it retrieves and clears ctx->error after synching, despite
* the two being set at the same time in nfs_context_set_write_error().
* This is because the former is used to notify the _next_ call to
* nfs_file_write() that a write error occurred, and hence cause it to
* fall back to doing a synchronous write.
*/
static int
nfs_file_fsync_commit(struct file *file, int datasync)
Expand All @@ -220,11 +213,8 @@ nfs_file_fsync_commit(struct file *file, int datasync)
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
status = nfs_commit_inode(inode, FLUSH_SYNC);
if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
ret = xchg(&ctx->error, 0);
if (ret)
goto out;
}
if (status == 0)
status = file_check_and_advance_wb_err(file);
if (status < 0) {
ret = status;
goto out;
Expand All @@ -245,13 +235,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
trace_nfs_fsync_enter(inode);

do {
struct nfs_open_context *ctx = nfs_file_open_context(file);
ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
int ret2 = xchg(&ctx->error, 0);
if (ret2)
ret = ret2;
}
ret = file_write_and_wait_range(file, start, end);
if (ret != 0)
break;
ret = nfs_file_fsync_commit(file, datasync);
Expand Down Expand Up @@ -600,8 +584,7 @@ static int nfs_need_check_write(struct file *filp, struct inode *inode)
struct nfs_open_context *ctx;

ctx = nfs_file_open_context(filp);
if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
nfs_ctx_key_to_expire(ctx, inode))
if (nfs_ctx_key_to_expire(ctx, inode))
return 1;
return 0;
}
Expand Down Expand Up @@ -655,7 +638,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)

/* Return error values */
if (nfs_need_check_write(file, inode)) {
int err = vfs_fsync(file, 0);
int err = nfs_wb_all(inode);
if (err < 0)
result = err;
}
Expand Down Expand Up @@ -709,7 +692,7 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
* Flush all pending writes before doing anything
* with locks..
*/
vfs_fsync(filp, 0);
nfs_wb_all(inode);

l_ctx = nfs_get_lock_context(nfs_file_open_context(filp));
if (!IS_ERR(l_ctx)) {
Expand Down
6 changes: 3 additions & 3 deletions fs/nfs/filelayout/filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ fl_pnfs_update_layout(struct inode *ino,
status = filelayout_check_deviceid(lo, fl, gfp_flags);
if (status) {
pnfs_put_lseg(lseg);
lseg = ERR_PTR(status);
lseg = NULL;
}
out:
return lseg;
Expand All @@ -917,7 +917,7 @@ filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
pnfs_generic_pg_check_layout(pgio);
if (!pgio->pg_lseg) {
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
req->wb_context,
nfs_req_openctx(req),
0,
NFS4_MAX_UINT64,
IOMODE_READ,
Expand All @@ -944,7 +944,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
pnfs_generic_pg_check_layout(pgio);
if (!pgio->pg_lseg) {
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
req->wb_context,
nfs_req_openctx(req),
0,
NFS4_MAX_UINT64,
IOMODE_RW,
Expand Down
Loading

0 comments on commit 06cbd26

Please sign in to comment.