Skip to content

Commit 5394eea

Browse files
committed
Merge tag 'nfs-for-6.14-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: "Stable Fixes: - O_DIRECT writes should adjust file length Other Bugfixes: - Adjust delegated timestamps for O_DIRECT reads and writes - Prevent looping due to rpc_signal_task() races - Fix a deadlock when recovering state on a sillyrenamed file - Properly handle -ETIMEDOUT errors from tlshd - Suppress build warnings for unused procfs functions - Fix memory leak of lsm_contexts" * tag 'nfs-for-6.14-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: lsm,nfs: fix memory leak of lsm_context sunrpc: suppress warnings for unused procfs functions SUNRPC: Handle -ETIMEDOUT return from tlshd NFSv4: Fix a deadlock when recovering state on a sillyrenamed file SUNRPC: Prevent looping due to rpc_signal_task() races NFS: Adjust delegated timestamps for O_DIRECT reads and writes NFS: O_DIRECT writes must check and adjust the file length
2 parents c0d3508 + 9084ed7 commit 5394eea

File tree

10 files changed

+83
-17
lines changed

10 files changed

+83
-17
lines changed

fs/nfs/delegation.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,43 @@ int nfs4_inode_return_delegation(struct inode *inode)
780780
return 0;
781781
}
782782

783+
/**
784+
* nfs4_inode_set_return_delegation_on_close - asynchronously return a delegation
785+
* @inode: inode to process
786+
*
787+
* This routine is called to request that the delegation be returned as soon
788+
* as the file is closed. If the file is already closed, the delegation is
789+
* immediately returned.
790+
*/
791+
void nfs4_inode_set_return_delegation_on_close(struct inode *inode)
792+
{
793+
struct nfs_delegation *delegation;
794+
struct nfs_delegation *ret = NULL;
795+
796+
if (!inode)
797+
return;
798+
rcu_read_lock();
799+
delegation = nfs4_get_valid_delegation(inode);
800+
if (!delegation)
801+
goto out;
802+
spin_lock(&delegation->lock);
803+
if (!delegation->inode)
804+
goto out_unlock;
805+
if (list_empty(&NFS_I(inode)->open_files) &&
806+
!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
807+
/* Refcount matched in nfs_end_delegation_return() */
808+
ret = nfs_get_delegation(delegation);
809+
} else
810+
set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
811+
out_unlock:
812+
spin_unlock(&delegation->lock);
813+
if (ret)
814+
nfs_clear_verifier_delegated(inode);
815+
out:
816+
rcu_read_unlock();
817+
nfs_end_delegation_return(inode, ret, 0);
818+
}
819+
783820
/**
784821
* nfs4_inode_return_delegation_on_close - asynchronously return a delegation
785822
* @inode: inode to process

fs/nfs/delegation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
4949
unsigned long pagemod_limit, u32 deleg_type);
5050
int nfs4_inode_return_delegation(struct inode *inode);
5151
void nfs4_inode_return_delegation_on_close(struct inode *inode);
52+
void nfs4_inode_set_return_delegation_on_close(struct inode *inode);
5253
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
5354
void nfs_inode_evict_delegation(struct inode *inode);
5455

fs/nfs/direct.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include <linux/uaccess.h>
5757
#include <linux/atomic.h>
5858

59+
#include "delegation.h"
5960
#include "internal.h"
6061
#include "iostat.h"
6162
#include "pnfs.h"
@@ -130,6 +131,20 @@ static void nfs_direct_truncate_request(struct nfs_direct_req *dreq,
130131
dreq->count = req_start;
131132
}
132133

134+
static void nfs_direct_file_adjust_size_locked(struct inode *inode,
135+
loff_t offset, size_t count)
136+
{
137+
loff_t newsize = offset + (loff_t)count;
138+
loff_t oldsize = i_size_read(inode);
139+
140+
if (newsize > oldsize) {
141+
i_size_write(inode, newsize);
142+
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
143+
trace_nfs_size_grow(inode, newsize);
144+
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
145+
}
146+
}
147+
133148
/**
134149
* nfs_swap_rw - NFS address space operation for swap I/O
135150
* @iocb: target I/O control block
@@ -272,6 +287,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
272287
nfs_direct_count_bytes(dreq, hdr);
273288
spin_unlock(&dreq->lock);
274289

290+
nfs_update_delegated_atime(dreq->inode);
291+
275292
while (!list_empty(&hdr->pages)) {
276293
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
277294
struct page *page = req->wb_page;
@@ -741,6 +758,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
741758
struct nfs_direct_req *dreq = hdr->dreq;
742759
struct nfs_commit_info cinfo;
743760
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
761+
struct inode *inode = dreq->inode;
744762
int flags = NFS_ODIRECT_DONE;
745763

746764
trace_nfs_direct_write_completion(dreq);
@@ -762,6 +780,11 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
762780
}
763781
spin_unlock(&dreq->lock);
764782

783+
spin_lock(&inode->i_lock);
784+
nfs_direct_file_adjust_size_locked(inode, dreq->io_start, dreq->count);
785+
nfs_update_delegated_mtime_locked(dreq->inode);
786+
spin_unlock(&inode->i_lock);
787+
765788
while (!list_empty(&hdr->pages)) {
766789

767790
req = nfs_list_entry(hdr->pages.next);

fs/nfs/nfs4proc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
133133
if (err)
134134
return NULL;
135135

136+
label->lsmid = shim.id;
136137
label->label = shim.context;
137138
label->len = shim.len;
138139
return label;
@@ -145,7 +146,7 @@ nfs4_label_release_security(struct nfs4_label *label)
145146
if (label) {
146147
shim.context = label->label;
147148
shim.len = label->len;
148-
shim.id = LSM_ID_UNDEF;
149+
shim.id = label->lsmid;
149150
security_release_secctx(&shim);
150151
}
151152
}
@@ -3906,8 +3907,11 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
39063907

39073908
static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
39083909
{
3910+
struct dentry *dentry = ctx->dentry;
39093911
if (ctx->state == NULL)
39103912
return;
3913+
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
3914+
nfs4_inode_set_return_delegation_on_close(d_inode(dentry));
39113915
if (is_sync)
39123916
nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
39133917
else
@@ -6269,7 +6273,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
62696273
size_t buflen)
62706274
{
62716275
struct nfs_server *server = NFS_SERVER(inode);
6272-
struct nfs4_label label = {0, 0, buflen, buf};
6276+
struct nfs4_label label = {0, 0, 0, buflen, buf};
62736277

62746278
u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
62756279
struct nfs_fattr fattr = {
@@ -6374,7 +6378,7 @@ static int nfs4_do_set_security_label(struct inode *inode,
63746378
static int
63756379
nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
63766380
{
6377-
struct nfs4_label ilabel = {0, 0, buflen, (char *)buf };
6381+
struct nfs4_label ilabel = {0, 0, 0, buflen, (char *)buf };
63786382
struct nfs_fattr *fattr;
63796383
int status;
63806384

include/linux/nfs4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct nfs4_acl {
4747
struct nfs4_label {
4848
uint32_t lfs;
4949
uint32_t pi;
50+
u32 lsmid;
5051
u32 len;
5152
char *label;
5253
};

include/linux/sunrpc/sched.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ enum {
158158
RPC_TASK_NEED_XMIT,
159159
RPC_TASK_NEED_RECV,
160160
RPC_TASK_MSG_PIN_WAIT,
161-
RPC_TASK_SIGNALLED,
162161
};
163162

164163
#define rpc_test_and_set_running(t) \
@@ -171,7 +170,7 @@ enum {
171170

172171
#define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
173172

174-
#define RPC_SIGNALLED(t) test_bit(RPC_TASK_SIGNALLED, &(t)->tk_runstate)
173+
#define RPC_SIGNALLED(t) (READ_ONCE(task->tk_rpc_status) == -ERESTARTSYS)
175174

176175
/*
177176
* Task priorities.

include/trace/events/sunrpc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ TRACE_EVENT(rpc_request,
360360
{ (1UL << RPC_TASK_ACTIVE), "ACTIVE" }, \
361361
{ (1UL << RPC_TASK_NEED_XMIT), "NEED_XMIT" }, \
362362
{ (1UL << RPC_TASK_NEED_RECV), "NEED_RECV" }, \
363-
{ (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }, \
364-
{ (1UL << RPC_TASK_SIGNALLED), "SIGNALLED" })
363+
{ (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" })
365364

366365
DECLARE_EVENT_CLASS(rpc_task_running,
367366

net/sunrpc/cache.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,12 +1674,14 @@ static void remove_cache_proc_entries(struct cache_detail *cd)
16741674
}
16751675
}
16761676

1677-
#ifdef CONFIG_PROC_FS
16781677
static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
16791678
{
16801679
struct proc_dir_entry *p;
16811680
struct sunrpc_net *sn;
16821681

1682+
if (!IS_ENABLED(CONFIG_PROC_FS))
1683+
return 0;
1684+
16831685
sn = net_generic(net, sunrpc_net_id);
16841686
cd->procfs = proc_mkdir(cd->name, sn->proc_net_rpc);
16851687
if (cd->procfs == NULL)
@@ -1707,12 +1709,6 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
17071709
remove_cache_proc_entries(cd);
17081710
return -ENOMEM;
17091711
}
1710-
#else /* CONFIG_PROC_FS */
1711-
static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1712-
{
1713-
return 0;
1714-
}
1715-
#endif
17161712

17171713
void __init cache_initialize(void)
17181714
{

net/sunrpc/sched.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -864,8 +864,6 @@ void rpc_signal_task(struct rpc_task *task)
864864
if (!rpc_task_set_rpc_status(task, -ERESTARTSYS))
865865
return;
866866
trace_rpc_task_signalled(task, task->tk_action);
867-
set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
868-
smp_mb__after_atomic();
869867
queue = READ_ONCE(task->tk_waitqueue);
870868
if (queue)
871869
rpc_wake_up_queued_task(queue, task);

net/sunrpc/xprtsock.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2581,7 +2581,15 @@ static void xs_tls_handshake_done(void *data, int status, key_serial_t peerid)
25812581
struct sock_xprt *lower_transport =
25822582
container_of(lower_xprt, struct sock_xprt, xprt);
25832583

2584-
lower_transport->xprt_err = status ? -EACCES : 0;
2584+
switch (status) {
2585+
case 0:
2586+
case -EACCES:
2587+
case -ETIMEDOUT:
2588+
lower_transport->xprt_err = status;
2589+
break;
2590+
default:
2591+
lower_transport->xprt_err = -EACCES;
2592+
}
25852593
complete(&lower_transport->handshake_done);
25862594
xprt_put(lower_xprt);
25872595
}

0 commit comments

Comments
 (0)