Skip to content

Commit 589109d

Browse files
committed
Merge tag 'nfs-for-4.19-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client bugfixes from Anna Schumaker: "These are a handful of fixes for problems that Trond found. Patch #1 and #3 have the same name, a second issue was found after applying the first patch. Stable bugfixes: - v4.17+: Fix tracepoint Oops in initiate_file_draining() - v4.11+: Fix an infinite loop on I/O Other fixes: - Return errors if a waiting layoutget is killed - Don't open code clearing of delegation state" * tag 'nfs-for-4.19-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFS: Don't open code clearing of delegation state NFSv4.1 fix infinite loop on I/O. NFSv4: Fix a tracepoint Oops in initiate_file_draining() pNFS: Ensure we return the error if someone kills a waiting layoutget NFSv4: Fix a tracepoint Oops in initiate_file_draining()
2 parents 5b945fd + 9f0c512 commit 589109d

File tree

4 files changed

+39
-24
lines changed

4 files changed

+39
-24
lines changed

fs/nfs/nfs4proc.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,14 @@ static void nfs_state_set_delegation(struct nfs4_state *state,
16371637
write_sequnlock(&state->seqlock);
16381638
}
16391639

1640+
static void nfs_state_clear_delegation(struct nfs4_state *state)
1641+
{
1642+
write_seqlock(&state->seqlock);
1643+
nfs4_stateid_copy(&state->stateid, &state->open_stateid);
1644+
clear_bit(NFS_DELEGATED_STATE, &state->flags);
1645+
write_sequnlock(&state->seqlock);
1646+
}
1647+
16401648
static int update_open_stateid(struct nfs4_state *state,
16411649
const nfs4_stateid *open_stateid,
16421650
const nfs4_stateid *delegation,
@@ -2145,10 +2153,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
21452153
if (IS_ERR(opendata))
21462154
return PTR_ERR(opendata);
21472155
nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
2148-
write_seqlock(&state->seqlock);
2149-
nfs4_stateid_copy(&state->stateid, &state->open_stateid);
2150-
write_sequnlock(&state->seqlock);
2151-
clear_bit(NFS_DELEGATED_STATE, &state->flags);
2156+
nfs_state_clear_delegation(state);
21522157
switch (type & (FMODE_READ|FMODE_WRITE)) {
21532158
case FMODE_READ|FMODE_WRITE:
21542159
case FMODE_WRITE:
@@ -2601,10 +2606,7 @@ static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state,
26012606
const nfs4_stateid *stateid)
26022607
{
26032608
nfs_remove_bad_delegation(state->inode, stateid);
2604-
write_seqlock(&state->seqlock);
2605-
nfs4_stateid_copy(&state->stateid, &state->open_stateid);
2606-
write_sequnlock(&state->seqlock);
2607-
clear_bit(NFS_DELEGATED_STATE, &state->flags);
2609+
nfs_state_clear_delegation(state);
26082610
}
26092611

26102612
static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
@@ -2672,15 +2674,20 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
26722674
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
26732675
if (delegation == NULL) {
26742676
rcu_read_unlock();
2677+
nfs_state_clear_delegation(state);
26752678
return;
26762679
}
26772680

26782681
nfs4_stateid_copy(&stateid, &delegation->stateid);
2679-
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) ||
2680-
!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
2681-
&delegation->flags)) {
2682+
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
2683+
rcu_read_unlock();
2684+
nfs_state_clear_delegation(state);
2685+
return;
2686+
}
2687+
2688+
if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
2689+
&delegation->flags)) {
26822690
rcu_read_unlock();
2683-
nfs_finish_clear_delegation_stateid(state, &stateid);
26842691
return;
26852692
}
26862693

fs/nfs/nfs4state.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,8 @@ int nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_
13901390

13911391
if (!nfs4_state_mark_reclaim_nograce(clp, state))
13921392
return -EBADF;
1393+
nfs_inode_find_delegation_state_and_recover(state->inode,
1394+
&state->stateid);
13931395
dprintk("%s: scheduling stateid recovery for server %s\n", __func__,
13941396
clp->cl_hostname);
13951397
nfs4_schedule_state_manager(clp);

fs/nfs/nfs4trace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,
11371137
TP_fast_assign(
11381138
__entry->error = error;
11391139
__entry->fhandle = nfs_fhandle_hash(fhandle);
1140-
if (inode != NULL) {
1140+
if (!IS_ERR_OR_NULL(inode)) {
11411141
__entry->fileid = NFS_FILEID(inode);
11421142
__entry->dev = inode->i_sb->s_dev;
11431143
} else {
@@ -1194,7 +1194,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,
11941194
TP_fast_assign(
11951195
__entry->error = error;
11961196
__entry->fhandle = nfs_fhandle_hash(fhandle);
1197-
if (inode != NULL) {
1197+
if (!IS_ERR_OR_NULL(inode)) {
11981198
__entry->fileid = NFS_FILEID(inode);
11991199
__entry->dev = inode->i_sb->s_dev;
12001200
} else {

fs/nfs/pnfs.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,16 +1740,16 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
17401740
return ret;
17411741
}
17421742

1743-
static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
1743+
static int pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
17441744
{
17451745
/*
17461746
* send layoutcommit as it can hold up layoutreturn due to lseg
17471747
* reference
17481748
*/
17491749
pnfs_layoutcommit_inode(lo->plh_inode, false);
1750-
return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
1750+
return wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
17511751
nfs_wait_bit_killable,
1752-
TASK_UNINTERRUPTIBLE);
1752+
TASK_KILLABLE);
17531753
}
17541754

17551755
static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
@@ -1830,7 +1830,9 @@ pnfs_update_layout(struct inode *ino,
18301830
}
18311831

18321832
lookup_again:
1833-
nfs4_client_recover_expired_lease(clp);
1833+
lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp));
1834+
if (IS_ERR(lseg))
1835+
goto out;
18341836
first = false;
18351837
spin_lock(&ino->i_lock);
18361838
lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
@@ -1863,9 +1865,9 @@ pnfs_update_layout(struct inode *ino,
18631865
if (list_empty(&lo->plh_segs) &&
18641866
atomic_read(&lo->plh_outstanding) != 0) {
18651867
spin_unlock(&ino->i_lock);
1866-
if (wait_var_event_killable(&lo->plh_outstanding,
1867-
atomic_read(&lo->plh_outstanding) == 0
1868-
|| !list_empty(&lo->plh_segs)))
1868+
lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
1869+
atomic_read(&lo->plh_outstanding)));
1870+
if (IS_ERR(lseg) || !list_empty(&lo->plh_segs))
18691871
goto out_put_layout_hdr;
18701872
pnfs_put_layout_hdr(lo);
18711873
goto lookup_again;
@@ -1898,8 +1900,11 @@ pnfs_update_layout(struct inode *ino,
18981900
if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET,
18991901
&lo->plh_flags)) {
19001902
spin_unlock(&ino->i_lock);
1901-
wait_on_bit(&lo->plh_flags, NFS_LAYOUT_FIRST_LAYOUTGET,
1902-
TASK_UNINTERRUPTIBLE);
1903+
lseg = ERR_PTR(wait_on_bit(&lo->plh_flags,
1904+
NFS_LAYOUT_FIRST_LAYOUTGET,
1905+
TASK_KILLABLE));
1906+
if (IS_ERR(lseg))
1907+
goto out_put_layout_hdr;
19031908
pnfs_put_layout_hdr(lo);
19041909
dprintk("%s retrying\n", __func__);
19051910
goto lookup_again;
@@ -1925,7 +1930,8 @@ pnfs_update_layout(struct inode *ino,
19251930
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
19261931
spin_unlock(&ino->i_lock);
19271932
dprintk("%s wait for layoutreturn\n", __func__);
1928-
if (pnfs_prepare_to_retry_layoutget(lo)) {
1933+
lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
1934+
if (!IS_ERR(lseg)) {
19291935
if (first)
19301936
pnfs_clear_first_layoutget(lo);
19311937
pnfs_put_layout_hdr(lo);

0 commit comments

Comments
 (0)