Skip to content

Commit 4b35035

Browse files
committed
Merge tag 'nfs-for-5.19-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: - Add FMODE_CAN_ODIRECT support to NFSv4 so opens don't fail - Fix trunking detection & cl_max_connect setting - Avoid pnfs_update_layout() livelocks - Don't keep retrying pNFS if the server replies with NFS4ERR_UNAVAILABLE * tag 'nfs-for-5.19-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFSv4: Add FMODE_CAN_ODIRECT after successful open of a NFS4.x file sunrpc: set cl_max_connect when cloning an rpc_clnt pNFS: Avoid a live lock condition in pnfs_update_layout() pNFS: Don't keep retrying if the server replied NFS4ERR_LAYOUTUNAVAILABLE
2 parents 32efdbf + 5ee3d10 commit 4b35035

File tree

6 files changed

+20
-6
lines changed

6 files changed

+20
-6
lines changed

fs/nfs/callback_proc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
288288
rv = NFS4_OK;
289289
break;
290290
case -ENOENT:
291+
set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags);
291292
/* Embrace your forgetfulness! */
292293
rv = NFS4ERR_NOMATCHING_LAYOUT;
293294

fs/nfs/dir.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
21242124
}
21252125
goto out;
21262126
}
2127+
file->f_mode |= FMODE_CAN_ODIRECT;
21272128

21282129
err = nfs_finish_open(ctx, ctx->dentry, file, open_flags);
21292130
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);

fs/nfs/nfs4file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ nfs4_file_open(struct inode *inode, struct file *filp)
9393
nfs_file_set_open_context(filp, ctx);
9494
nfs_fscache_open_file(inode, filp);
9595
err = 0;
96+
filp->f_mode |= FMODE_CAN_ODIRECT;
9697

9798
out_put_ctx:
9899
put_nfs_open_context(ctx);

fs/nfs/pnfs.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
469469
pnfs_clear_lseg_state(lseg, lseg_list);
470470
pnfs_clear_layoutreturn_info(lo);
471471
pnfs_free_returned_lsegs(lo, lseg_list, &range, 0);
472+
set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags);
472473
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) &&
473474
!test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
474475
pnfs_clear_layoutreturn_waitbit(lo);
@@ -1917,8 +1918,9 @@ static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
19171918

19181919
static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
19191920
{
1920-
if (atomic_dec_and_test(&lo->plh_outstanding))
1921-
wake_up_var(&lo->plh_outstanding);
1921+
if (atomic_dec_and_test(&lo->plh_outstanding) &&
1922+
test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags))
1923+
wake_up_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN);
19221924
}
19231925

19241926
static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo)
@@ -2025,11 +2027,11 @@ pnfs_update_layout(struct inode *ino,
20252027
* If the layout segment list is empty, but there are outstanding
20262028
* layoutget calls, then they might be subject to a layoutrecall.
20272029
*/
2028-
if ((list_empty(&lo->plh_segs) || !pnfs_layout_is_valid(lo)) &&
2030+
if (test_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags) &&
20292031
atomic_read(&lo->plh_outstanding) != 0) {
20302032
spin_unlock(&ino->i_lock);
2031-
lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
2032-
!atomic_read(&lo->plh_outstanding)));
2033+
lseg = ERR_PTR(wait_on_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN,
2034+
TASK_KILLABLE));
20332035
if (IS_ERR(lseg))
20342036
goto out_put_layout_hdr;
20352037
pnfs_put_layout_hdr(lo);
@@ -2152,6 +2154,12 @@ pnfs_update_layout(struct inode *ino,
21522154
case -ERECALLCONFLICT:
21532155
case -EAGAIN:
21542156
break;
2157+
case -ENODATA:
2158+
/* The server returned NFS4ERR_LAYOUTUNAVAILABLE */
2159+
pnfs_layout_set_fail_bit(
2160+
lo, pnfs_iomode_to_fail_bit(iomode));
2161+
lseg = NULL;
2162+
goto out_put_layout_hdr;
21552163
default:
21562164
if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
21572165
pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
@@ -2407,7 +2415,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
24072415
goto out_forget;
24082416
}
24092417

2410-
if (!pnfs_layout_is_valid(lo) && !pnfs_is_first_layoutget(lo))
2418+
if (test_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags) &&
2419+
!pnfs_is_first_layoutget(lo))
24112420
goto out_forget;
24122421

24132422
if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {

fs/nfs/pnfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ enum {
105105
NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
106106
NFS_LAYOUT_INODE_FREEING, /* The inode is being freed */
107107
NFS_LAYOUT_HASHED, /* The layout visible */
108+
NFS_LAYOUT_DRAIN,
108109
};
109110

110111
enum layoutdriver_policy_flags {

net/sunrpc/clnt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
651651
new->cl_discrtry = clnt->cl_discrtry;
652652
new->cl_chatty = clnt->cl_chatty;
653653
new->cl_principal = clnt->cl_principal;
654+
new->cl_max_connect = clnt->cl_max_connect;
654655
return new;
655656

656657
out_err:

0 commit comments

Comments
 (0)