Skip to content

Commit b85900e

Browse files
committed
Merge tag 'nfs-for-7.1-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Bugfixes: - Fix handling of ENOSPC so that if we have to resend writes, they are written synchronously - SUNRPC RDMA transport fixes from Chuck - Several fixes for delegated timestamps in NFSv4.2 - Failure to obtain a directory delegation should not cause stat() to fail with NFSv4 - Rename was failing to update timestamps when a directory delegation is held on NFSv4 - Ensure we check rsize/wsize after crossing a NFSv4 filesystem boundary - NFSv4/pnfs: - If the server is down, retry the layout returns on reboot - Fallback to MDS could result in a short write being incorrectly logged Cleanups: - Use memcpy_and_pad in decode_fh" * tag 'nfs-for-7.1-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (21 commits) NFS: Fix RCU dereference of cl_xprt in nfs_compare_super_address NFS: remove redundant __private attribute from nfs_page_class NFSv4.2: fix CLONE/COPY attrs in presence of delegated attributes NFS: fix writeback in presence of errors nfs: use memcpy_and_pad in decode_fh NFSv4.1: Apply session size limits on clone path NFSv4: retry GETATTR if GET_DIR_DELEGATION failed NFS: fix RENAME attr in presence of directory delegations pnfs/flexfiles: validate ds_versions_cnt is non-zero NFS/blocklayout: print each device used for SCSI layouts xprtrdma: Post receive buffers after RPC completion xprtrdma: Scale receive batch size with credit window xprtrdma: Replace rpcrdma_mr_seg with xdr_buf cursor xprtrdma: Decouple frwr_wp_create from frwr_map xprtrdma: Close lost-wakeup race in xprt_rdma_alloc_slot xprtrdma: Avoid 250 ms delay on backlog wakeup xprtrdma: Close sendctx get/put race that can block a transport nfs: update inode ctime after removexattr operation nfs: fix utimensat() for atime with delegated timestamps NFS: improve "Server wrote zero bytes" error ...
2 parents ac2dc6d + e6614b8 commit b85900e

25 files changed

Lines changed: 443 additions & 215 deletions

File tree

fs/nfs/blocklayout/dev.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,14 @@ bl_open_path(struct pnfs_block_volume *v, const char *prefix)
370370
if (!devname)
371371
return ERR_PTR(-ENOMEM);
372372

373-
bdev_file = bdev_file_open_by_path(devname, BLK_OPEN_READ | BLK_OPEN_WRITE,
374-
NULL, NULL);
373+
bdev_file = bdev_file_open_by_path(devname,
374+
BLK_OPEN_READ | BLK_OPEN_WRITE, NULL, NULL);
375375
if (IS_ERR(bdev_file)) {
376376
dprintk("failed to open device %s (%ld)\n",
377377
devname, PTR_ERR(bdev_file));
378+
} else {
379+
pr_info("pNFS: using block device %s\n",
380+
file_bdev(bdev_file)->bd_disk->disk_name);
378381
}
379382

380383
kfree(devname);

fs/nfs/callback_xdr.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
9696
p = xdr_inline_decode(xdr, fh->size);
9797
if (unlikely(p == NULL))
9898
return htonl(NFS4ERR_RESOURCE);
99-
memcpy(&fh->data[0], p, fh->size);
100-
memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size);
99+
memcpy_and_pad(fh->data, sizeof(fh->data), p, fh->size, 0);
101100
return 0;
102101
}
103102

fs/nfs/flexfilelayout/flexfilelayoutdev.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
9797
if (unlikely(!p))
9898
goto out_err_drain_dsaddrs;
9999
version_count = be32_to_cpup(p);
100+
101+
if (version_count == 0) {
102+
ret = -EINVAL;
103+
goto out_err_drain_dsaddrs;
104+
}
100105
dprintk("%s: version count %d\n", __func__, version_count);
101106

102107
ds_versions = kzalloc_objs(struct nfs4_ff_ds_version, version_count,

fs/nfs/inode.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,8 @@ void nfs_update_delegated_atime(struct inode *inode)
692692

693693
void nfs_update_delegated_mtime_locked(struct inode *inode)
694694
{
695-
if (nfs_have_delegated_mtime(inode))
695+
if (nfs_have_delegated_mtime(inode) ||
696+
nfs_have_directory_delegation(inode))
696697
nfs_update_mtime(inode);
697698
}
698699

@@ -757,14 +758,7 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
757758
} else if (nfs_have_delegated_atime(inode) &&
758759
attr->ia_valid & ATTR_ATIME &&
759760
!(attr->ia_valid & ATTR_MTIME)) {
760-
if (attr->ia_valid & ATTR_ATIME_SET) {
761-
if (uid_eq(task_uid, owner_uid)) {
762-
spin_lock(&inode->i_lock);
763-
nfs_set_timestamps_to_ts(inode, attr);
764-
spin_unlock(&inode->i_lock);
765-
attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
766-
}
767-
} else {
761+
if (!(attr->ia_valid & ATTR_ATIME_SET)) {
768762
nfs_update_delegated_atime(inode);
769763
attr->ia_valid &= ~ATTR_ATIME;
770764
}

fs/nfs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
253253
u32 minor_version);
254254
extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
255255
struct inode *);
256+
extern void nfs4_session_limit_rwsize(struct nfs_server *server);
257+
extern void nfs4_session_limit_xasize(struct nfs_server *server);
256258
extern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
257259
const struct sockaddr_storage *ds_addr, int ds_addrlen,
258260
int ds_proto, unsigned int ds_timeo,

fs/nfs/localio.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,8 @@ static void nfs_local_call_write(struct work_struct *work)
865865
file_start_write(filp);
866866
n_iters = atomic_read(&iocb->n_iters);
867867
for (int i = 0; i < n_iters ; i++) {
868+
size_t icount;
869+
868870
if (iocb->iter_is_dio_aligned[i]) {
869871
iocb->kiocb.ki_flags |= IOCB_DIRECT;
870872
/* Only use AIO completion if DIO-aligned segment is last */
@@ -881,8 +883,16 @@ static void nfs_local_call_write(struct work_struct *work)
881883
if (status == -EIOCBQUEUED)
882884
continue;
883885
/* Break on completion, errors, or short writes */
886+
icount = iov_iter_count(&iocb->iters[i]);
884887
if (nfs_local_pgio_done(iocb, status) || status < 0 ||
885-
(size_t)status < iov_iter_count(&iocb->iters[i])) {
888+
(size_t)status < icount) {
889+
if ((size_t)status < icount) {
890+
struct nfs_lock_context *ctx =
891+
iocb->hdr->req->wb_lock_context;
892+
893+
set_bit(NFS_CONTEXT_WRITE_SYNC,
894+
&ctx->open_context->flags);
895+
}
886896
nfs_local_write_iocb_done(iocb);
887897
break;
888898
}
@@ -901,6 +911,9 @@ static void nfs_local_do_write(struct nfs_local_kiocb *iocb,
901911
__func__, hdr->args.count, hdr->args.offset,
902912
(hdr->args.stable == NFS_UNSTABLE) ? "unstable" : "stable");
903913

914+
if (test_bit(NFS_CONTEXT_WRITE_SYNC,
915+
&hdr->req->wb_lock_context->open_context->flags))
916+
hdr->args.stable = NFS_FILE_SYNC;
904917
switch (hdr->args.stable) {
905918
default:
906919
break;

fs/nfs/nfs42proc.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ static void nfs42_copy_dest_done(struct file *file, loff_t pos, loff_t len,
401401
NFS_INO_INVALID_MTIME |
402402
NFS_INO_INVALID_BLOCKS);
403403
spin_unlock(&inode->i_lock);
404+
nfs_update_delegated_mtime(inode);
404405
}
405406

406407
static ssize_t _nfs42_proc_copy(struct file *src,
@@ -1372,11 +1373,15 @@ int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
13721373
static int _nfs42_proc_removexattr(struct inode *inode, const char *name)
13731374
{
13741375
struct nfs_server *server = NFS_SERVER(inode);
1376+
__u32 bitmask[NFS_BITMASK_SZ];
13751377
struct nfs42_removexattrargs args = {
13761378
.fh = NFS_FH(inode),
1379+
.bitmask = bitmask,
13771380
.xattr_name = name,
13781381
};
1379-
struct nfs42_removexattrres res;
1382+
struct nfs42_removexattrres res = {
1383+
.server = server,
1384+
};
13801385
struct rpc_message msg = {
13811386
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVEXATTR],
13821387
.rpc_argp = &args,
@@ -1385,12 +1390,22 @@ static int _nfs42_proc_removexattr(struct inode *inode, const char *name)
13851390
int ret;
13861391
unsigned long timestamp = jiffies;
13871392

1393+
res.fattr = nfs_alloc_fattr();
1394+
if (!res.fattr)
1395+
return -ENOMEM;
1396+
1397+
nfs4_bitmask_set(bitmask, server->cache_consistency_bitmask,
1398+
inode, NFS_INO_INVALID_CHANGE);
1399+
13881400
ret = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
13891401
&res.seq_res, 1);
13901402
trace_nfs4_removexattr(inode, name, ret);
1391-
if (!ret)
1403+
if (!ret) {
13921404
nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);
1405+
ret = nfs_post_op_update_inode(inode, res.fattr);
1406+
}
13931407

1408+
kfree(res.fattr);
13941409
return ret;
13951410
}
13961411

fs/nfs/nfs42xdr.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,13 @@
263263
#define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \
264264
encode_sequence_maxsz + \
265265
encode_putfh_maxsz + \
266-
encode_removexattr_maxsz)
266+
encode_removexattr_maxsz + \
267+
encode_getattr_maxsz)
267268
#define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \
268269
decode_sequence_maxsz + \
269270
decode_putfh_maxsz + \
270-
decode_removexattr_maxsz)
271+
decode_removexattr_maxsz + \
272+
decode_getattr_maxsz)
271273

272274
/*
273275
* These values specify the maximum amount of data that is not
@@ -869,6 +871,7 @@ static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
869871
encode_sequence(xdr, &args->seq_args, &hdr);
870872
encode_putfh(xdr, args->fh, &hdr);
871873
encode_removexattr(xdr, args->xattr_name, &hdr);
874+
encode_getfattr(xdr, args->bitmask, &hdr);
872875
encode_nops(&hdr);
873876
}
874877

@@ -1818,6 +1821,9 @@ static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
18181821
goto out;
18191822

18201823
status = decode_removexattr(xdr, &res->cinfo);
1824+
if (status)
1825+
goto out;
1826+
status = decode_getfattr(xdr, res->fattr, res->server);
18211827
out:
18221828
return status;
18231829
}

fs/nfs/nfs4client.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ EXPORT_SYMBOL_GPL(nfs4_set_ds_client);
855855
* Limit the mount rsize, wsize and dtsize using negotiated fore
856856
* channel attributes.
857857
*/
858-
static void nfs4_session_limit_rwsize(struct nfs_server *server)
858+
void nfs4_session_limit_rwsize(struct nfs_server *server)
859859
{
860860
struct nfs4_session *sess;
861861
u32 server_resp_sz;
@@ -878,7 +878,7 @@ static void nfs4_session_limit_rwsize(struct nfs_server *server)
878878
/*
879879
* Limit xattr sizes using the channel attributes.
880880
*/
881-
static void nfs4_session_limit_xasize(struct nfs_server *server)
881+
void nfs4_session_limit_xasize(struct nfs_server *server)
882882
{
883883
#ifdef CONFIG_NFS_V4_2
884884
struct nfs4_session *sess;

fs/nfs/nfs4proc.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4469,6 +4469,13 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
44694469
case -ENOTSUPP:
44704470
case -EOPNOTSUPP:
44714471
server->caps &= ~NFS_CAP_DIR_DELEG;
4472+
break;
4473+
case -NFS4ERR_INVAL:
4474+
case -NFS4ERR_IO:
4475+
case -NFS4ERR_DIRDELEG_UNAVAIL:
4476+
case -NFS4ERR_NOTDIR:
4477+
clear_bit(NFS_INO_REQ_DIR_DELEG, &(NFS_I(inode)->flags));
4478+
status = -EAGAIN;
44724479
}
44734480
}
44744481

@@ -4490,6 +4497,7 @@ int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
44904497
default:
44914498
err = nfs4_handle_exception(server, err, &exception);
44924499
break;
4500+
case -EAGAIN:
44934501
case -ENOTSUPP:
44944502
case -EOPNOTSUPP:
44954503
exception.retry = true;
@@ -5052,6 +5060,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
50525060
res->new_fattr->time_start,
50535061
NFS_INO_INVALID_NLINK |
50545062
NFS_INO_INVALID_DATA);
5063+
nfs_update_delegated_mtime(new_dir);
50555064
} else
50565065
nfs4_update_changeattr(old_dir, &res->old_cinfo,
50575066
res->old_fattr->time_start,
@@ -9769,16 +9778,26 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
97699778
if (!nfs41_sequence_process(task, &lrp->res.seq_res))
97709779
return;
97719780

9772-
if (task->tk_rpc_status == -ETIMEDOUT) {
9773-
lrp->rpc_status = -EAGAIN;
9774-
lrp->res.lrs_present = 0;
9775-
return;
9776-
}
9777-
/*
9778-
* Was there an RPC level error? Assume the call succeeded,
9779-
* and that we need to release the layout
9780-
*/
9781-
if (task->tk_rpc_status != 0 && RPC_WAS_SENT(task)) {
9781+
if (task->tk_rpc_status < 0) {
9782+
switch (task->tk_rpc_status) {
9783+
case -EACCES:
9784+
case -EIO:
9785+
case -EKEYEXPIRED:
9786+
case -ERESTARTSYS:
9787+
case -EINTR:
9788+
lrp->rpc_status = 0;
9789+
break;
9790+
case -ENETDOWN:
9791+
case -ENETUNREACH:
9792+
if (task->tk_flags & RPC_TASK_NETUNREACH_FATAL)
9793+
lrp->rpc_status = 0;
9794+
else
9795+
lrp->rpc_status = -EAGAIN;
9796+
break;
9797+
default:
9798+
lrp->rpc_status = -EAGAIN;
9799+
break;
9800+
}
97829801
lrp->res.lrs_present = 0;
97839802
return;
97849803
}
@@ -10618,6 +10637,9 @@ static struct nfs_server *nfs4_clone_server(struct nfs_server *source,
1061810637
if (IS_ERR(server))
1061910638
return server;
1062010639

10640+
nfs4_session_limit_rwsize(server);
10641+
nfs4_session_limit_xasize(server);
10642+
1062110643
error = nfs4_delegation_hash_alloc(server);
1062210644
if (error) {
1062310645
nfs_free_server(server);

0 commit comments

Comments
 (0)