1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/nfs4.h> 3 #include <linux/nfs.h> 4 #include <linux/sunrpc/sched.h> 5 #include <linux/nfs_fs.h> 6 #include "internal.h" 7 #include "nfs4_fs.h" 8 #include "nfs40.h" 9 #include "nfs4session.h" 10 #include "nfs4trace.h" 11 12 static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata) 13 { 14 struct nfs4_call_sync_data *data = calldata; 15 nfs4_setup_sequence(data->seq_server->nfs_client, 16 data->seq_args, data->seq_res, task); 17 } 18 19 static void nfs40_call_sync_done(struct rpc_task *task, void *calldata) 20 { 21 struct nfs4_call_sync_data *data = calldata; 22 nfs4_sequence_done(task, data->seq_res); 23 } 24 25 static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res) 26 { 27 struct nfs4_slot *slot = res->sr_slot; 28 struct nfs4_slot_table *tbl; 29 30 tbl = slot->table; 31 spin_lock(&tbl->slot_tbl_lock); 32 if (!nfs41_wake_and_assign_slot(tbl, slot)) 33 nfs4_free_slot(tbl, slot); 34 spin_unlock(&tbl->slot_tbl_lock); 35 36 res->sr_slot = NULL; 37 } 38 39 static int nfs40_sequence_done(struct rpc_task *task, 40 struct nfs4_sequence_res *res) 41 { 42 if (res->sr_slot != NULL) 43 nfs40_sequence_free_slot(res); 44 return 1; 45 } 46 47 static void nfs40_clear_delegation_stateid(struct nfs4_state *state) 48 { 49 if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL) 50 nfs_finish_clear_delegation_stateid(state, NULL); 51 } 52 53 static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) 54 { 55 /* NFSv4.0 doesn't allow for delegation recovery on open expire */ 56 nfs40_clear_delegation_stateid(state); 57 nfs_state_clear_open_state_flags(state); 58 return nfs4_open_expired(sp, state); 59 } 60 61 struct nfs4_renewdata { 62 struct nfs_client *client; 63 unsigned long timestamp; 64 }; 65 66 /* 67 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special 68 * standalone procedure for queueing an asynchronous RENEW. 69 */ 70 static void nfs4_renew_release(void *calldata) 71 { 72 struct nfs4_renewdata *data = calldata; 73 struct nfs_client *clp = data->client; 74 75 if (refcount_read(&clp->cl_count) > 1) 76 nfs4_schedule_state_renewal(clp); 77 nfs_put_client(clp); 78 kfree(data); 79 } 80 81 static void nfs4_renew_done(struct rpc_task *task, void *calldata) 82 { 83 struct nfs4_renewdata *data = calldata; 84 struct nfs_client *clp = data->client; 85 unsigned long timestamp = data->timestamp; 86 87 trace_nfs4_renew_async(clp, task->tk_status); 88 switch (task->tk_status) { 89 case 0: 90 break; 91 case -NFS4ERR_LEASE_MOVED: 92 nfs4_schedule_lease_moved_recovery(clp); 93 break; 94 default: 95 /* Unless we're shutting down, schedule state recovery! */ 96 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0) 97 return; 98 if (task->tk_status != NFS4ERR_CB_PATH_DOWN) { 99 nfs4_schedule_lease_recovery(clp); 100 return; 101 } 102 nfs4_schedule_path_down_recovery(clp); 103 } 104 do_renew_lease(clp, timestamp); 105 } 106 107 static const struct rpc_call_ops nfs4_renew_ops = { 108 .rpc_call_done = nfs4_renew_done, 109 .rpc_release = nfs4_renew_release, 110 }; 111 112 static int nfs4_proc_async_renew(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags) 113 { 114 struct rpc_message msg = { 115 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 116 .rpc_argp = clp, 117 .rpc_cred = cred, 118 }; 119 struct nfs4_renewdata *data; 120 121 if (renew_flags == 0) 122 return 0; 123 if (!refcount_inc_not_zero(&clp->cl_count)) 124 return -EIO; 125 data = kmalloc_obj(*data, GFP_NOFS); 126 if (data == NULL) { 127 nfs_put_client(clp); 128 return -ENOMEM; 129 } 130 data->client = clp; 131 data->timestamp = jiffies; 132 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT, 133 &nfs4_renew_ops, data); 134 } 135 136 static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred) 137 { 138 struct rpc_message msg = { 139 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 140 .rpc_argp = clp, 141 .rpc_cred = cred, 142 }; 143 unsigned long now = jiffies; 144 int status; 145 146 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 147 if (status < 0) 148 return status; 149 do_renew_lease(clp, now); 150 return 0; 151 } 152 153 static int nfs40_test_and_free_expired_stateid(struct nfs_server *server, 154 nfs4_stateid *stateid, 155 const struct cred *cred) 156 { 157 return -NFS4ERR_BAD_STATEID; 158 } 159 160 /* 161 * This operation also signals the server that this client is 162 * performing migration recovery. The server can stop returning 163 * NFS4ERR_LEASE_MOVED to this client. A RENEW operation is 164 * appended to this compound to identify the client ID which is 165 * performing recovery. 166 */ 167 static int _nfs40_proc_get_locations(struct nfs_server *server, 168 struct nfs_fh *fhandle, 169 struct nfs4_fs_locations *locations, 170 struct page *page, const struct cred *cred) 171 { 172 struct rpc_clnt *clnt = server->client; 173 struct nfs_client *clp = server->nfs_client; 174 u32 bitmask[2] = { 175 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 176 }; 177 struct nfs4_fs_locations_arg args = { 178 .clientid = clp->cl_clientid, 179 .fh = fhandle, 180 .page = page, 181 .bitmask = bitmask, 182 .migration = 1, /* skip LOOKUP */ 183 .renew = 1, /* append RENEW */ 184 }; 185 struct nfs4_fs_locations_res res = { 186 .fs_locations = locations, 187 .migration = 1, 188 .renew = 1, 189 }; 190 struct rpc_message msg = { 191 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], 192 .rpc_argp = &args, 193 .rpc_resp = &res, 194 .rpc_cred = cred, 195 }; 196 unsigned long now = jiffies; 197 int status; 198 199 nfs_fattr_init(locations->fattr); 200 locations->server = server; 201 locations->nlocations = 0; 202 203 nfs4_init_sequence(clp, &args.seq_args, &res.seq_res, 0, 1); 204 status = nfs4_call_sync_sequence(clnt, server, &msg, 205 &args.seq_args, &res.seq_res); 206 if (status) 207 return status; 208 209 renew_lease(server, now); 210 return 0; 211 } 212 213 /* 214 * This operation also signals the server that this client is 215 * performing "lease moved" recovery. The server can stop 216 * returning NFS4ERR_LEASE_MOVED to this client. A RENEW operation 217 * is appended to this compound to identify the client ID which is 218 * performing recovery. 219 */ 220 static int _nfs40_proc_fsid_present(struct inode *inode, const struct cred *cred) 221 { 222 struct nfs_server *server = NFS_SERVER(inode); 223 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 224 struct rpc_clnt *clnt = server->client; 225 struct nfs4_fsid_present_arg args = { 226 .fh = NFS_FH(inode), 227 .clientid = clp->cl_clientid, 228 .renew = 1, /* append RENEW */ 229 }; 230 struct nfs4_fsid_present_res res = { 231 .renew = 1, 232 }; 233 struct rpc_message msg = { 234 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT], 235 .rpc_argp = &args, 236 .rpc_resp = &res, 237 .rpc_cred = cred, 238 }; 239 unsigned long now = jiffies; 240 int status; 241 242 res.fh = nfs_alloc_fhandle(); 243 if (res.fh == NULL) 244 return -ENOMEM; 245 246 nfs4_init_sequence(clp, &args.seq_args, &res.seq_res, 0, 1); 247 status = nfs4_call_sync_sequence(clnt, server, &msg, 248 &args.seq_args, &res.seq_res); 249 nfs_free_fhandle(res.fh); 250 if (status) 251 return status; 252 253 do_renew_lease(clp, now); 254 return 0; 255 } 256 257 struct nfs_release_lockowner_data { 258 struct nfs4_lock_state *lsp; 259 struct nfs_server *server; 260 struct nfs_release_lockowner_args args; 261 struct nfs_release_lockowner_res res; 262 unsigned long timestamp; 263 }; 264 265 static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata) 266 { 267 struct nfs_release_lockowner_data *data = calldata; 268 struct nfs_server *server = data->server; 269 nfs4_setup_sequence(server->nfs_client, &data->args.seq_args, 270 &data->res.seq_res, task); 271 data->args.lock_owner.clientid = server->nfs_client->cl_clientid; 272 data->timestamp = jiffies; 273 } 274 275 static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) 276 { 277 struct nfs_release_lockowner_data *data = calldata; 278 struct nfs_server *server = data->server; 279 280 nfs40_sequence_done(task, &data->res.seq_res); 281 282 switch (task->tk_status) { 283 case 0: 284 renew_lease(server, data->timestamp); 285 break; 286 case -NFS4ERR_STALE_CLIENTID: 287 case -NFS4ERR_EXPIRED: 288 nfs4_schedule_lease_recovery(server->nfs_client); 289 break; 290 case -NFS4ERR_LEASE_MOVED: 291 case -NFS4ERR_DELAY: 292 if (nfs4_async_handle_error(task, server, 293 NULL, NULL) == -EAGAIN) 294 rpc_restart_call_prepare(task); 295 } 296 } 297 298 static void nfs4_release_lockowner_release(void *calldata) 299 { 300 struct nfs_release_lockowner_data *data = calldata; 301 nfs4_free_lock_state(data->server, data->lsp); 302 kfree(calldata); 303 } 304 305 static const struct rpc_call_ops nfs4_release_lockowner_ops = { 306 .rpc_call_prepare = nfs4_release_lockowner_prepare, 307 .rpc_call_done = nfs4_release_lockowner_done, 308 .rpc_release = nfs4_release_lockowner_release, 309 }; 310 311 static void 312 nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) 313 { 314 struct nfs_release_lockowner_data *data; 315 struct nfs_client *clp = server->nfs_client; 316 struct rpc_message msg = { 317 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER], 318 }; 319 320 if (clp->cl_mvops->minor_version != 0) 321 return; 322 323 data = kmalloc_obj(*data); 324 if (!data) 325 return; 326 data->lsp = lsp; 327 data->server = server; 328 data->args.lock_owner.clientid = clp->cl_clientid; 329 data->args.lock_owner.id = lsp->ls_seqid.owner_id; 330 data->args.lock_owner.s_dev = server->s_dev; 331 332 msg.rpc_argp = &data->args; 333 msg.rpc_resp = &data->res; 334 nfs4_init_sequence(clp, &data->args.seq_args, &data->res.seq_res, 0, 0); 335 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); 336 } 337 338 static const struct rpc_call_ops nfs40_call_sync_ops = { 339 .rpc_call_prepare = nfs40_call_sync_prepare, 340 .rpc_call_done = nfs40_call_sync_done, 341 }; 342 343 static const struct nfs4_sequence_slot_ops nfs40_sequence_slot_ops = { 344 .process = nfs40_sequence_done, 345 .done = nfs40_sequence_done, 346 .free_slot = nfs40_sequence_free_slot, 347 }; 348 349 static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 350 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, 351 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 352 .recover_open = nfs4_open_reclaim, 353 .recover_lock = nfs4_lock_reclaim, 354 .establish_clid = nfs4_init_clientid, 355 .detect_trunking = nfs40_discover_server_trunking, 356 }; 357 358 static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { 359 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, 360 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 361 .recover_open = nfs40_open_expired, 362 .recover_lock = nfs4_lock_expired, 363 .establish_clid = nfs4_init_clientid, 364 }; 365 366 static const struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = { 367 .sched_state_renewal = nfs4_proc_async_renew, 368 .get_state_renewal_cred = nfs4_get_renew_cred, 369 .renew_lease = nfs4_proc_renew, 370 }; 371 372 static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = { 373 .get_locations = _nfs40_proc_get_locations, 374 .fsid_present = _nfs40_proc_fsid_present, 375 }; 376 377 const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { 378 .minor_version = 0, 379 .init_caps = NFS_CAP_READDIRPLUS 380 | NFS_CAP_ATOMIC_OPEN 381 | NFS_CAP_POSIX_LOCK, 382 .init_client = nfs40_init_client, 383 .shutdown_client = nfs40_shutdown_client, 384 .match_stateid = nfs4_match_stateid, 385 .find_root_sec = nfs4_find_root_sec, 386 .free_lock_state = nfs4_release_lockowner, 387 .test_and_free_expired = nfs40_test_and_free_expired_stateid, 388 .alloc_seqid = nfs_alloc_seqid, 389 .call_sync_ops = &nfs40_call_sync_ops, 390 .sequence_slot_ops = &nfs40_sequence_slot_ops, 391 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 392 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 393 .state_renewal_ops = &nfs40_state_renewal_ops, 394 .mig_recovery_ops = &nfs40_mig_recovery_ops, 395 }; 396