hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nfs/nfs4proc.c
....@@ -130,6 +130,11 @@
130130 if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
131131 return NULL;
132132
133
+ label->lfs = 0;
134
+ label->pi = 0;
135
+ label->len = 0;
136
+ label->label = NULL;
137
+
133138 err = security_dentry_init_security(dentry, sattr->ia_mode,
134139 &dentry->d_name, (void **)&label->label, &label->len);
135140 if (err == 0)
....@@ -921,6 +926,7 @@
921926 out_noaction:
922927 return ret;
923928 session_recover:
929
+ set_bit(NFS4_SLOT_TBL_DRAINING, &session->fc_slot_table.slot_tbl_state);
924930 nfs4_schedule_session_recovery(session, status);
925931 dprintk("%s ERROR: %d Reset session\n", __func__, status);
926932 nfs41_sequence_free_slot(res);
....@@ -1970,8 +1976,7 @@
19701976 if (!data->rpc_done) {
19711977 if (data->rpc_status)
19721978 return ERR_PTR(data->rpc_status);
1973
- /* cached opens have already been processed */
1974
- goto update;
1979
+ return nfs4_try_open_cached(data);
19751980 }
19761981
19771982 ret = nfs_refresh_inode(inode, &data->f_attr);
....@@ -1980,7 +1985,7 @@
19801985
19811986 if (data->o_res.delegation_type != 0)
19821987 nfs4_opendata_check_deleg(data, state);
1983
-update:
1988
+
19841989 if (!update_open_stateid(state, &data->o_res.stateid,
19851990 NULL, data->o_arg.fmode))
19861991 return ERR_PTR(-EAGAIN);
....@@ -2121,18 +2126,18 @@
21212126 }
21222127
21232128 static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
2124
- fmode_t fmode)
2129
+ fmode_t fmode)
21252130 {
21262131 struct nfs4_state *newstate;
2132
+ struct nfs_server *server = NFS_SB(opendata->dentry->d_sb);
2133
+ int openflags = opendata->o_arg.open_flags;
21272134 int ret;
21282135
21292136 if (!nfs4_mode_match_open_stateid(opendata->state, fmode))
21302137 return 0;
2131
- opendata->o_arg.open_flags = 0;
21322138 opendata->o_arg.fmode = fmode;
2133
- opendata->o_arg.share_access = nfs4_map_atomic_open_share(
2134
- NFS_SB(opendata->dentry->d_sb),
2135
- fmode, 0);
2139
+ opendata->o_arg.share_access =
2140
+ nfs4_map_atomic_open_share(server, fmode, openflags);
21362141 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
21372142 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
21382143 nfs4_init_opendata_res(opendata);
....@@ -2708,10 +2713,15 @@
27082713 struct nfs4_opendata *opendata;
27092714 int ret;
27102715
2711
- opendata = nfs4_open_recoverdata_alloc(ctx, state,
2712
- NFS4_OPEN_CLAIM_FH);
2716
+ opendata = nfs4_open_recoverdata_alloc(ctx, state, NFS4_OPEN_CLAIM_FH);
27132717 if (IS_ERR(opendata))
27142718 return PTR_ERR(opendata);
2719
+ /*
2720
+ * We're not recovering a delegation, so ask for no delegation.
2721
+ * Otherwise the recovery thread could deadlock with an outstanding
2722
+ * delegation return.
2723
+ */
2724
+ opendata->o_arg.open_flags = O_DIRECT;
27152725 ret = nfs4_open_recover(opendata, state);
27162726 if (ret == -ESTALE)
27172727 d_drop(ctx->dentry);
....@@ -3793,7 +3803,7 @@
37933803 int open_flags, struct iattr *attr, int *opened)
37943804 {
37953805 struct nfs4_state *state;
3796
- struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
3806
+ struct nfs4_label l, *label;
37973807
37983808 label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
37993809
....@@ -4557,7 +4567,7 @@
45574567 int flags)
45584568 {
45594569 struct nfs_server *server = NFS_SERVER(dir);
4560
- struct nfs4_label l, *ilabel = NULL;
4570
+ struct nfs4_label l, *ilabel;
45614571 struct nfs_open_context *ctx;
45624572 struct nfs4_state *state;
45634573 int status = 0;
....@@ -4916,7 +4926,7 @@
49164926 struct nfs4_exception exception = {
49174927 .interruptible = true,
49184928 };
4919
- struct nfs4_label l, *label = NULL;
4929
+ struct nfs4_label l, *label;
49204930 int err;
49214931
49224932 label = nfs4_label_init_security(dir, dentry, sattr, &l);
....@@ -4957,7 +4967,7 @@
49574967 struct nfs4_exception exception = {
49584968 .interruptible = true,
49594969 };
4960
- struct nfs4_label l, *label = NULL;
4970
+ struct nfs4_label l, *label;
49614971 int err;
49624972
49634973 label = nfs4_label_init_security(dir, dentry, sattr, &l);
....@@ -5078,7 +5088,7 @@
50785088 struct nfs4_exception exception = {
50795089 .interruptible = true,
50805090 };
5081
- struct nfs4_label l, *label = NULL;
5091
+ struct nfs4_label l, *label;
50825092 int err;
50835093
50845094 label = nfs4_label_init_security(dir, dentry, sattr, &l);
....@@ -5854,9 +5864,8 @@
58545864 out_ok:
58555865 ret = res.acl_len;
58565866 out_free:
5857
- for (i = 0; i < npages; i++)
5858
- if (pages[i])
5859
- __free_page(pages[i]);
5867
+ while (--i >= 0)
5868
+ __free_page(pages[i]);
58605869 if (res.acl_scratch)
58615870 __free_page(res.acl_scratch);
58625871 kfree(pages);
....@@ -7037,8 +7046,15 @@
70377046 } else if (!nfs4_update_lock_stateid(lsp, &data->res.stateid))
70387047 goto out_restart;
70397048 break;
7040
- case -NFS4ERR_BAD_STATEID:
70417049 case -NFS4ERR_OLD_STATEID:
7050
+ if (data->arg.new_lock_owner != 0 &&
7051
+ nfs4_refresh_open_old_stateid(&data->arg.open_stateid,
7052
+ lsp->ls_state))
7053
+ goto out_restart;
7054
+ if (nfs4_refresh_lock_old_stateid(&data->arg.lock_stateid, lsp))
7055
+ goto out_restart;
7056
+ fallthrough;
7057
+ case -NFS4ERR_BAD_STATEID:
70427058 case -NFS4ERR_STALE_STATEID:
70437059 case -NFS4ERR_EXPIRED:
70447060 if (data->arg.new_lock_owner != 0) {
....@@ -10378,6 +10394,28 @@
1037810394 return error + error2 + error3;
1037910395 }
1038010396
10397
+static void nfs4_enable_swap(struct inode *inode)
10398
+{
10399
+ /* The state manager thread must always be running.
10400
+ * It will notice the client is a swapper, and stay put.
10401
+ */
10402
+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
10403
+
10404
+ nfs4_schedule_state_manager(clp);
10405
+}
10406
+
10407
+static void nfs4_disable_swap(struct inode *inode)
10408
+{
10409
+ /* The state manager thread will now exit once it is
10410
+ * woken.
10411
+ */
10412
+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
10413
+
10414
+ set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
10415
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
10416
+ wake_up_var(&clp->cl_state);
10417
+}
10418
+
1038110419 static const struct inode_operations nfs4_dir_inode_operations = {
1038210420 .create = nfs_create,
1038310421 .lookup = nfs_lookup,
....@@ -10454,6 +10492,8 @@
1045410492 .free_client = nfs4_free_client,
1045510493 .create_server = nfs4_create_server,
1045610494 .clone_server = nfs_clone_server,
10495
+ .enable_swap = nfs4_enable_swap,
10496
+ .disable_swap = nfs4_disable_swap,
1045710497 };
1045810498
1045910499 static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {