Skip to content

Commit 5ff2756

Browse files
committed
Merge tag 'nfs-for-5.13-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: "Stable fixes: - Fix v4.0/v4.1 SEEK_DATA return -ENOTSUPP when set NFS_V4_2 config - Fix Oops in xs_tcp_send_request() when transport is disconnected - Fix a NULL pointer dereference in pnfs_mark_matching_lsegs_return() Bugfixes: - Fix instances where signal_pending() should be fatal_signal_pending() - fix an incorrect limit in filelayout_decode_layout() - Fixes for the SUNRPC backlogged RPC queue - Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() - Revert commit 586a078 ("Clean up rpcrdma_prepare_readch()")" * tag 'nfs-for-5.13-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: Remove trailing semicolon in macros xprtrdma: Revert 586a078 NFSv4: Fix v4.0/v4.1 SEEK_DATA return -ENOTSUPP when set NFS_V4_2 config NFS: Clean up reset of the mirror accounting variables NFS: Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() NFS: Fix an Oopsable condition in __nfs_pageio_add_request() SUNRPC: More fixes for backlog congestion SUNRPC: Fix Oops in xs_tcp_send_request() when transport is disconnected NFSv4: Fix a NULL pointer dereference in pnfs_mark_matching_lsegs_return() SUNRPC in case of backlog, hand free slots directly to waiting task pNFS/NFSv4: Remove redundant initialization of 'rd_size' NFS: fix an incorrect limit in filelayout_decode_layout() fs/nfs: Use fatal_signal_pending instead of signal_pending
2 parents fc683f9 + a799b68 commit 5ff2756

File tree

15 files changed

+96
-62
lines changed

15 files changed

+96
-62
lines changed

fs/nfs/filelayout/filelayout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
718718
if (unlikely(!p))
719719
goto out_err;
720720
fl->fh_array[i]->size = be32_to_cpup(p++);
721-
if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
721+
if (fl->fh_array[i]->size > NFS_MAXFHSIZE) {
722722
printk(KERN_ERR "NFS: Too big fh %d received %d\n",
723723
i, fl->fh_array[i]->size);
724724
goto out_err;

fs/nfs/namespace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ static const struct kernel_param_ops param_ops_nfs_timeout = {
362362
.set = param_set_nfs_timeout,
363363
.get = param_get_nfs_timeout,
364364
};
365-
#define param_check_nfs_timeout(name, p) __param_check(name, p, int);
365+
#define param_check_nfs_timeout(name, p) __param_check(name, p, int)
366366

367367
module_param(nfs_mountpoint_expiry_timeout, nfs_timeout, 0644);
368368
MODULE_PARM_DESC(nfs_mountpoint_expiry_timeout,

fs/nfs/nfs4file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
211211
case SEEK_HOLE:
212212
case SEEK_DATA:
213213
ret = nfs42_proc_llseek(filep, offset, whence);
214-
if (ret != -ENOTSUPP)
214+
if (ret != -EOPNOTSUPP)
215215
return ret;
216216
fallthrough;
217217
default:

fs/nfs/nfs4proc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,7 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state,
17061706
rcu_read_unlock();
17071707
trace_nfs4_open_stateid_update_wait(state->inode, stateid, 0);
17081708

1709-
if (!signal_pending(current)) {
1709+
if (!fatal_signal_pending(current)) {
17101710
if (schedule_timeout(5*HZ) == 0)
17111711
status = -EAGAIN;
17121712
else
@@ -3487,7 +3487,7 @@ static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst,
34873487
write_sequnlock(&state->seqlock);
34883488
trace_nfs4_close_stateid_update_wait(state->inode, dst, 0);
34893489

3490-
if (signal_pending(current))
3490+
if (fatal_signal_pending(current))
34913491
status = -EINTR;
34923492
else
34933493
if (schedule_timeout(5*HZ) != 0)

fs/nfs/pagelist.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,15 +1094,16 @@ nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
10941094
struct nfs_page *prev = NULL;
10951095
unsigned int size;
10961096

1097-
if (mirror->pg_count != 0) {
1098-
prev = nfs_list_entry(mirror->pg_list.prev);
1099-
} else {
1097+
if (list_empty(&mirror->pg_list)) {
11001098
if (desc->pg_ops->pg_init)
11011099
desc->pg_ops->pg_init(desc, req);
11021100
if (desc->pg_error < 0)
11031101
return 0;
11041102
mirror->pg_base = req->wb_pgbase;
1105-
}
1103+
mirror->pg_count = 0;
1104+
mirror->pg_recoalesce = 0;
1105+
} else
1106+
prev = nfs_list_entry(mirror->pg_list.prev);
11061107

11071108
if (desc->pg_maxretrans && req->wb_nio > desc->pg_maxretrans) {
11081109
if (NFS_SERVER(desc->pg_inode)->flags & NFS_MOUNT_SOFTERR)
@@ -1127,18 +1128,13 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
11271128
{
11281129
struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
11291130

1130-
11311131
if (!list_empty(&mirror->pg_list)) {
11321132
int error = desc->pg_ops->pg_doio(desc);
11331133
if (error < 0)
11341134
desc->pg_error = error;
1135-
else
1135+
if (list_empty(&mirror->pg_list))
11361136
mirror->pg_bytes_written += mirror->pg_count;
11371137
}
1138-
if (list_empty(&mirror->pg_list)) {
1139-
mirror->pg_count = 0;
1140-
mirror->pg_base = 0;
1141-
}
11421138
}
11431139

11441140
static void
@@ -1227,10 +1223,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
12271223

12281224
do {
12291225
list_splice_init(&mirror->pg_list, &head);
1230-
mirror->pg_bytes_written -= mirror->pg_count;
1231-
mirror->pg_count = 0;
1232-
mirror->pg_base = 0;
1233-
mirror->pg_recoalesce = 0;
12341226

12351227
while (!list_empty(&head)) {
12361228
struct nfs_page *req;

fs/nfs/pnfs.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,11 @@ _pnfs_return_layout(struct inode *ino)
13171317
{
13181318
struct pnfs_layout_hdr *lo = NULL;
13191319
struct nfs_inode *nfsi = NFS_I(ino);
1320+
struct pnfs_layout_range range = {
1321+
.iomode = IOMODE_ANY,
1322+
.offset = 0,
1323+
.length = NFS4_MAX_UINT64,
1324+
};
13201325
LIST_HEAD(tmp_list);
13211326
const struct cred *cred;
13221327
nfs4_stateid stateid;
@@ -1344,16 +1349,10 @@ _pnfs_return_layout(struct inode *ino)
13441349
}
13451350
valid_layout = pnfs_layout_is_valid(lo);
13461351
pnfs_clear_layoutcommit(ino, &tmp_list);
1347-
pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0);
1352+
pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0);
13481353

1349-
if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
1350-
struct pnfs_layout_range range = {
1351-
.iomode = IOMODE_ANY,
1352-
.offset = 0,
1353-
.length = NFS4_MAX_UINT64,
1354-
};
1354+
if (NFS_SERVER(ino)->pnfs_curr_ld->return_range)
13551355
NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &range);
1356-
}
13571356

13581357
/* Don't send a LAYOUTRETURN if list was initially empty */
13591358
if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) ||
@@ -2678,7 +2677,7 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_range);
26782677
void
26792678
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
26802679
{
2681-
u64 rd_size = req->wb_bytes;
2680+
u64 rd_size;
26822681

26832682
pnfs_generic_pg_check_layout(pgio);
26842683
pnfs_generic_pg_check_range(pgio, req);

fs/nfs/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ static const struct kernel_param_ops param_ops_portnr = {
13791379
.set = param_set_portnr,
13801380
.get = param_get_uint,
13811381
};
1382-
#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
1382+
#define param_check_portnr(name, p) __param_check(name, p, unsigned int)
13831383

13841384
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
13851385
module_param_named(callback_nr_threads, nfs_callback_nr_threads, ushort, 0644);

include/linux/sunrpc/xprt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ struct rpc_xprt * xprt_alloc(struct net *net, size_t size,
368368
unsigned int num_prealloc,
369369
unsigned int max_req);
370370
void xprt_free(struct rpc_xprt *);
371+
void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task);
372+
bool xprt_wake_up_backlog(struct rpc_xprt *xprt, struct rpc_rqst *req);
371373

372374
static inline int
373375
xprt_enable_swap(struct rpc_xprt *xprt)

net/sunrpc/clnt.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,13 +1677,6 @@ call_reserveresult(struct rpc_task *task)
16771677
return;
16781678
}
16791679

1680-
/*
1681-
* Even though there was an error, we may have acquired
1682-
* a request slot somehow. Make sure not to leak it.
1683-
*/
1684-
if (task->tk_rqstp)
1685-
xprt_release(task);
1686-
16871680
switch (status) {
16881681
case -ENOMEM:
16891682
rpc_delay(task, HZ >> 2);

net/sunrpc/xprt.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
static void xprt_init(struct rpc_xprt *xprt, struct net *net);
7171
static __be32 xprt_alloc_xid(struct rpc_xprt *xprt);
7272
static void xprt_destroy(struct rpc_xprt *xprt);
73+
static void xprt_request_init(struct rpc_task *task);
7374

7475
static DEFINE_SPINLOCK(xprt_list_lock);
7576
static LIST_HEAD(xprt_list);
@@ -1606,17 +1607,40 @@ xprt_transmit(struct rpc_task *task)
16061607
spin_unlock(&xprt->queue_lock);
16071608
}
16081609

1609-
static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task)
1610+
static void xprt_complete_request_init(struct rpc_task *task)
1611+
{
1612+
if (task->tk_rqstp)
1613+
xprt_request_init(task);
1614+
}
1615+
1616+
void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task)
16101617
{
16111618
set_bit(XPRT_CONGESTED, &xprt->state);
1612-
rpc_sleep_on(&xprt->backlog, task, NULL);
1619+
rpc_sleep_on(&xprt->backlog, task, xprt_complete_request_init);
1620+
}
1621+
EXPORT_SYMBOL_GPL(xprt_add_backlog);
1622+
1623+
static bool __xprt_set_rq(struct rpc_task *task, void *data)
1624+
{
1625+
struct rpc_rqst *req = data;
1626+
1627+
if (task->tk_rqstp == NULL) {
1628+
memset(req, 0, sizeof(*req)); /* mark unused */
1629+
task->tk_rqstp = req;
1630+
return true;
1631+
}
1632+
return false;
16131633
}
16141634

1615-
static void xprt_wake_up_backlog(struct rpc_xprt *xprt)
1635+
bool xprt_wake_up_backlog(struct rpc_xprt *xprt, struct rpc_rqst *req)
16161636
{
1617-
if (rpc_wake_up_next(&xprt->backlog) == NULL)
1637+
if (rpc_wake_up_first(&xprt->backlog, __xprt_set_rq, req) == NULL) {
16181638
clear_bit(XPRT_CONGESTED, &xprt->state);
1639+
return false;
1640+
}
1641+
return true;
16191642
}
1643+
EXPORT_SYMBOL_GPL(xprt_wake_up_backlog);
16201644

16211645
static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task)
16221646
{
@@ -1626,7 +1650,7 @@ static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task
16261650
goto out;
16271651
spin_lock(&xprt->reserve_lock);
16281652
if (test_bit(XPRT_CONGESTED, &xprt->state)) {
1629-
rpc_sleep_on(&xprt->backlog, task, NULL);
1653+
xprt_add_backlog(xprt, task);
16301654
ret = true;
16311655
}
16321656
spin_unlock(&xprt->reserve_lock);
@@ -1703,11 +1727,11 @@ EXPORT_SYMBOL_GPL(xprt_alloc_slot);
17031727
void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
17041728
{
17051729
spin_lock(&xprt->reserve_lock);
1706-
if (!xprt_dynamic_free_slot(xprt, req)) {
1730+
if (!xprt_wake_up_backlog(xprt, req) &&
1731+
!xprt_dynamic_free_slot(xprt, req)) {
17071732
memset(req, 0, sizeof(*req)); /* mark unused */
17081733
list_add(&req->rq_list, &xprt->free);
17091734
}
1710-
xprt_wake_up_backlog(xprt);
17111735
spin_unlock(&xprt->reserve_lock);
17121736
}
17131737
EXPORT_SYMBOL_GPL(xprt_free_slot);
@@ -1894,10 +1918,10 @@ void xprt_release(struct rpc_task *task)
18941918
xdr_free_bvec(&req->rq_snd_buf);
18951919
if (req->rq_cred != NULL)
18961920
put_rpccred(req->rq_cred);
1897-
task->tk_rqstp = NULL;
18981921
if (req->rq_release_snd_buf)
18991922
req->rq_release_snd_buf(req);
19001923

1924+
task->tk_rqstp = NULL;
19011925
if (likely(!bc_prealloc(req)))
19021926
xprt->ops->free_slot(xprt, req);
19031927
else

0 commit comments

Comments
 (0)