Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSv4: Enable delegated opens even when reboot recovery is pending

Unlike the previous attempt, this takes into account the fact that
we may be calling it from the recovery thread itself. Detect this
by looking at what kind of open we're doing, and checking the state
of the NFS_DELEGATION_NEED_RECLAIM if it turns out we're doing a
reboot reclaim-type open.

Cc: Olga Kornievskaia <aglo@umich.edu>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

+20 -9
+19 -8
fs/nfs/nfs4proc.c
··· 1150 1150 return ret; 1151 1151 } 1152 1152 1153 - static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) 1153 + static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode, 1154 + enum open_claim_type4 claim) 1154 1155 { 1155 1156 if (delegation == NULL) 1156 1157 return 0; 1157 1158 if ((delegation->type & fmode) != fmode) 1158 1159 return 0; 1159 - if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) 1160 - return 0; 1161 1160 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) 1162 1161 return 0; 1162 + switch (claim) { 1163 + case NFS4_OPEN_CLAIM_NULL: 1164 + case NFS4_OPEN_CLAIM_FH: 1165 + break; 1166 + case NFS4_OPEN_CLAIM_PREVIOUS: 1167 + if (!test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) 1168 + break; 1169 + default: 1170 + return 0; 1171 + } 1163 1172 nfs_mark_delegation_referenced(delegation); 1164 1173 return 1; 1165 1174 } ··· 1387 1378 struct nfs_delegation *delegation; 1388 1379 int open_mode = opendata->o_arg.open_flags; 1389 1380 fmode_t fmode = opendata->o_arg.fmode; 1381 + enum open_claim_type4 claim = opendata->o_arg.claim; 1390 1382 nfs4_stateid stateid; 1391 1383 int ret = -EAGAIN; 1392 1384 ··· 1401 1391 spin_unlock(&state->owner->so_lock); 1402 1392 rcu_read_lock(); 1403 1393 delegation = rcu_dereference(nfsi->delegation); 1404 - if (!can_open_delegated(delegation, fmode)) { 1394 + if (!can_open_delegated(delegation, fmode, claim)) { 1405 1395 rcu_read_unlock(); 1406 1396 break; 1407 1397 } ··· 1864 1854 struct nfs4_opendata *data = calldata; 1865 1855 struct nfs4_state_owner *sp = data->owner; 1866 1856 struct nfs_client *clp = sp->so_server->nfs_client; 1857 + enum open_claim_type4 claim = data->o_arg.claim; 1867 1858 1868 1859 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) 1869 1860 goto out_wait; ··· 1879 1868 goto out_no_action; 1880 1869 rcu_read_lock(); 1881 1870 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); 1882 - if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && 1883 - data->o_arg.claim != NFS4_OPEN_CLAIM_DELEG_CUR_FH && 1884 - can_open_delegated(delegation, data->o_arg.fmode)) 1871 + if (can_open_delegated(delegation, data->o_arg.fmode, claim)) 1885 1872 goto unlock_no_action; 1886 1873 rcu_read_unlock(); 1887 1874 } 1888 1875 /* Update client id. */ 1889 1876 data->o_arg.clientid = clp->cl_clientid; 1890 - switch (data->o_arg.claim) { 1877 + switch (claim) { 1878 + default: 1879 + break; 1891 1880 case NFS4_OPEN_CLAIM_PREVIOUS: 1892 1881 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 1893 1882 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
+1 -1
include/linux/nfs_xdr.h
··· 389 389 const struct nfs_server *server; /* Needed for ID mapping */ 390 390 const u32 * bitmask; 391 391 const u32 * open_bitmap; 392 - __u32 claim; 392 + enum open_claim_type4 claim; 393 393 enum createmode4 createmode; 394 394 const struct nfs4_label *label; 395 395 };