1 /* 2 * linux/fs/nfs/delegation.c 3 * 4 * Copyright (C) 2004 Trond Myklebust 5 * 6 * NFS file delegation management 7 * 8 */ 9 #include <linux/completion.h> 10 #include <linux/kthread.h> 11 #include <linux/module.h> 12 #include <linux/sched.h> 13 #include <linux/spinlock.h> 14 15 #include <linux/nfs4.h> 16 #include <linux/nfs_fs.h> 17 #include <linux/nfs_xdr.h> 18 19 #include "nfs4_fs.h" 20 #include "delegation.h" 21 #include "internal.h" 22 23 static void nfs_do_free_delegation(struct nfs_delegation *delegation) 24 { 25 kfree(delegation); 26 } 27 28 static void nfs_free_delegation_callback(struct rcu_head *head) 29 { 30 struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu); 31 32 nfs_do_free_delegation(delegation); 33 } 34 35 static void nfs_free_delegation(struct nfs_delegation *delegation) 36 { 37 struct rpc_cred *cred; 38 39 cred = rcu_dereference(delegation->cred); 40 rcu_assign_pointer(delegation->cred, NULL); 41 call_rcu(&delegation->rcu, nfs_free_delegation_callback); 42 if (cred) 43 put_rpccred(cred); 44 } 45 46 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) 47 { 48 struct inode *inode = state->inode; 49 struct file_lock *fl; 50 int status; 51 52 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 53 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 54 continue; 55 if (nfs_file_open_context(fl->fl_file) != ctx) 56 continue; 57 status = nfs4_lock_delegation_recall(state, fl); 58 if (status >= 0) 59 continue; 60 switch (status) { 61 default: 62 printk(KERN_ERR "%s: unhandled error %d.\n", 63 __func__, status); 64 case -NFS4ERR_EXPIRED: 65 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 66 case -NFS4ERR_STALE_CLIENTID: 67 nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs_client); 68 goto out_err; 69 } 70 } 71 return 0; 72 out_err: 73 return status; 74 } 75 76 static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid) 77 { 78 struct nfs_inode *nfsi = NFS_I(inode); 79 struct nfs_open_context *ctx; 80 struct nfs4_state *state; 81 int err; 82 83 again: 84 spin_lock(&inode->i_lock); 85 list_for_each_entry(ctx, &nfsi->open_files, list) { 86 state = ctx->state; 87 if (state == NULL) 88 continue; 89 if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) 90 continue; 91 if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0) 92 continue; 93 get_nfs_open_context(ctx); 94 spin_unlock(&inode->i_lock); 95 err = nfs4_open_delegation_recall(ctx, state, stateid); 96 if (err >= 0) 97 err = nfs_delegation_claim_locks(ctx, state); 98 put_nfs_open_context(ctx); 99 if (err != 0) 100 return; 101 goto again; 102 } 103 spin_unlock(&inode->i_lock); 104 } 105 106 /* 107 * Set up a delegation on an inode 108 */ 109 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 110 { 111 struct nfs_delegation *delegation = NFS_I(inode)->delegation; 112 struct rpc_cred *oldcred; 113 114 if (delegation == NULL) 115 return; 116 memcpy(delegation->stateid.data, res->delegation.data, 117 sizeof(delegation->stateid.data)); 118 delegation->type = res->delegation_type; 119 delegation->maxsize = res->maxsize; 120 oldcred = delegation->cred; 121 delegation->cred = get_rpccred(cred); 122 delegation->flags &= ~NFS_DELEGATION_NEED_RECLAIM; 123 NFS_I(inode)->delegation_state = delegation->type; 124 smp_wmb(); 125 put_rpccred(oldcred); 126 } 127 128 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) 129 { 130 int res = 0; 131 132 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync); 133 nfs_free_delegation(delegation); 134 return res; 135 } 136 137 static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid) 138 { 139 struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation); 140 141 if (delegation == NULL) 142 goto nomatch; 143 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, 144 sizeof(delegation->stateid.data)) != 0) 145 goto nomatch; 146 list_del_rcu(&delegation->super_list); 147 nfsi->delegation_state = 0; 148 rcu_assign_pointer(nfsi->delegation, NULL); 149 return delegation; 150 nomatch: 151 return NULL; 152 } 153 154 /* 155 * Set up a delegation on an inode 156 */ 157 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 158 { 159 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 160 struct nfs_inode *nfsi = NFS_I(inode); 161 struct nfs_delegation *delegation; 162 struct nfs_delegation *freeme = NULL; 163 int status = 0; 164 165 delegation = kmalloc(sizeof(*delegation), GFP_KERNEL); 166 if (delegation == NULL) 167 return -ENOMEM; 168 memcpy(delegation->stateid.data, res->delegation.data, 169 sizeof(delegation->stateid.data)); 170 delegation->type = res->delegation_type; 171 delegation->maxsize = res->maxsize; 172 delegation->change_attr = nfsi->change_attr; 173 delegation->cred = get_rpccred(cred); 174 delegation->inode = inode; 175 176 spin_lock(&clp->cl_lock); 177 if (rcu_dereference(nfsi->delegation) != NULL) { 178 if (memcmp(&delegation->stateid, &nfsi->delegation->stateid, 179 sizeof(delegation->stateid)) == 0 && 180 delegation->type == nfsi->delegation->type) { 181 goto out; 182 } 183 /* 184 * Deal with broken servers that hand out two 185 * delegations for the same file. 186 */ 187 dfprintk(FILE, "%s: server %s handed out " 188 "a duplicate delegation!\n", 189 __func__, clp->cl_hostname); 190 if (delegation->type <= nfsi->delegation->type) { 191 freeme = delegation; 192 delegation = NULL; 193 goto out; 194 } 195 freeme = nfs_detach_delegation_locked(nfsi, NULL); 196 } 197 list_add_rcu(&delegation->super_list, &clp->cl_delegations); 198 nfsi->delegation_state = delegation->type; 199 rcu_assign_pointer(nfsi->delegation, delegation); 200 delegation = NULL; 201 202 /* Ensure we revalidate the attributes and page cache! */ 203 spin_lock(&inode->i_lock); 204 nfsi->cache_validity |= NFS_INO_REVAL_FORCED; 205 spin_unlock(&inode->i_lock); 206 207 out: 208 spin_unlock(&clp->cl_lock); 209 if (delegation != NULL) 210 nfs_free_delegation(delegation); 211 if (freeme != NULL) 212 nfs_do_return_delegation(inode, freeme, 0); 213 return status; 214 } 215 216 /* Sync all data to disk upon delegation return */ 217 static void nfs_msync_inode(struct inode *inode) 218 { 219 filemap_fdatawrite(inode->i_mapping); 220 nfs_wb_all(inode); 221 filemap_fdatawait(inode->i_mapping); 222 } 223 224 /* 225 * Basic procedure for returning a delegation to the server 226 */ 227 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 228 { 229 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 230 struct nfs_inode *nfsi = NFS_I(inode); 231 232 nfs_msync_inode(inode); 233 down_read(&clp->cl_sem); 234 /* Guard against new delegated open calls */ 235 down_write(&nfsi->rwsem); 236 nfs_delegation_claim_opens(inode, &delegation->stateid); 237 up_write(&nfsi->rwsem); 238 up_read(&clp->cl_sem); 239 nfs_msync_inode(inode); 240 241 return nfs_do_return_delegation(inode, delegation, 1); 242 } 243 244 /* 245 * This function returns the delegation without reclaiming opens 246 * or protecting against delegation reclaims. 247 * It is therefore really only safe to be called from 248 * nfs4_clear_inode() 249 */ 250 void nfs_inode_return_delegation_noreclaim(struct inode *inode) 251 { 252 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 253 struct nfs_inode *nfsi = NFS_I(inode); 254 struct nfs_delegation *delegation; 255 256 if (rcu_dereference(nfsi->delegation) != NULL) { 257 spin_lock(&clp->cl_lock); 258 delegation = nfs_detach_delegation_locked(nfsi, NULL); 259 spin_unlock(&clp->cl_lock); 260 if (delegation != NULL) 261 nfs_do_return_delegation(inode, delegation, 0); 262 } 263 } 264 265 int nfs_inode_return_delegation(struct inode *inode) 266 { 267 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 268 struct nfs_inode *nfsi = NFS_I(inode); 269 struct nfs_delegation *delegation; 270 int err = 0; 271 272 if (rcu_dereference(nfsi->delegation) != NULL) { 273 spin_lock(&clp->cl_lock); 274 delegation = nfs_detach_delegation_locked(nfsi, NULL); 275 spin_unlock(&clp->cl_lock); 276 if (delegation != NULL) 277 err = __nfs_inode_return_delegation(inode, delegation); 278 } 279 return err; 280 } 281 282 /* 283 * Return all delegations associated to a super block 284 */ 285 void nfs_return_all_delegations(struct super_block *sb) 286 { 287 struct nfs_client *clp = NFS_SB(sb)->nfs_client; 288 struct nfs_delegation *delegation; 289 struct inode *inode; 290 291 if (clp == NULL) 292 return; 293 restart: 294 rcu_read_lock(); 295 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 296 if (delegation->inode->i_sb != sb) 297 continue; 298 inode = igrab(delegation->inode); 299 if (inode == NULL) 300 continue; 301 spin_lock(&clp->cl_lock); 302 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 303 spin_unlock(&clp->cl_lock); 304 rcu_read_unlock(); 305 if (delegation != NULL) 306 __nfs_inode_return_delegation(inode, delegation); 307 iput(inode); 308 goto restart; 309 } 310 rcu_read_unlock(); 311 } 312 313 static int nfs_do_expire_all_delegations(void *ptr) 314 { 315 struct nfs_client *clp = ptr; 316 struct nfs_delegation *delegation; 317 struct inode *inode; 318 319 allow_signal(SIGKILL); 320 restart: 321 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0) 322 goto out; 323 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) 324 goto out; 325 rcu_read_lock(); 326 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 327 inode = igrab(delegation->inode); 328 if (inode == NULL) 329 continue; 330 spin_lock(&clp->cl_lock); 331 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 332 spin_unlock(&clp->cl_lock); 333 rcu_read_unlock(); 334 if (delegation) 335 __nfs_inode_return_delegation(inode, delegation); 336 iput(inode); 337 goto restart; 338 } 339 rcu_read_unlock(); 340 out: 341 nfs_put_client(clp); 342 module_put_and_exit(0); 343 } 344 345 void nfs_expire_all_delegations(struct nfs_client *clp) 346 { 347 struct task_struct *task; 348 349 __module_get(THIS_MODULE); 350 atomic_inc(&clp->cl_count); 351 task = kthread_run(nfs_do_expire_all_delegations, clp, 352 "%s-delegreturn", 353 rpc_peeraddr2str(clp->cl_rpcclient, 354 RPC_DISPLAY_ADDR)); 355 if (!IS_ERR(task)) 356 return; 357 nfs_put_client(clp); 358 module_put(THIS_MODULE); 359 } 360 361 /* 362 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 363 */ 364 void nfs_handle_cb_pathdown(struct nfs_client *clp) 365 { 366 struct nfs_delegation *delegation; 367 struct inode *inode; 368 369 if (clp == NULL) 370 return; 371 restart: 372 rcu_read_lock(); 373 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 374 inode = igrab(delegation->inode); 375 if (inode == NULL) 376 continue; 377 spin_lock(&clp->cl_lock); 378 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 379 spin_unlock(&clp->cl_lock); 380 rcu_read_unlock(); 381 if (delegation != NULL) 382 __nfs_inode_return_delegation(inode, delegation); 383 iput(inode); 384 goto restart; 385 } 386 rcu_read_unlock(); 387 } 388 389 struct recall_threadargs { 390 struct inode *inode; 391 struct nfs_client *clp; 392 const nfs4_stateid *stateid; 393 394 struct completion started; 395 int result; 396 }; 397 398 static int recall_thread(void *data) 399 { 400 struct recall_threadargs *args = (struct recall_threadargs *)data; 401 struct inode *inode = igrab(args->inode); 402 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 403 struct nfs_inode *nfsi = NFS_I(inode); 404 struct nfs_delegation *delegation; 405 406 daemonize("nfsv4-delegreturn"); 407 408 nfs_msync_inode(inode); 409 down_read(&clp->cl_sem); 410 down_write(&nfsi->rwsem); 411 spin_lock(&clp->cl_lock); 412 delegation = nfs_detach_delegation_locked(nfsi, args->stateid); 413 if (delegation != NULL) 414 args->result = 0; 415 else 416 args->result = -ENOENT; 417 spin_unlock(&clp->cl_lock); 418 complete(&args->started); 419 nfs_delegation_claim_opens(inode, args->stateid); 420 up_write(&nfsi->rwsem); 421 up_read(&clp->cl_sem); 422 nfs_msync_inode(inode); 423 424 if (delegation != NULL) 425 nfs_do_return_delegation(inode, delegation, 1); 426 iput(inode); 427 module_put_and_exit(0); 428 } 429 430 /* 431 * Asynchronous delegation recall! 432 */ 433 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 434 { 435 struct recall_threadargs data = { 436 .inode = inode, 437 .stateid = stateid, 438 }; 439 int status; 440 441 init_completion(&data.started); 442 __module_get(THIS_MODULE); 443 status = kernel_thread(recall_thread, &data, CLONE_KERNEL); 444 if (status < 0) 445 goto out_module_put; 446 wait_for_completion(&data.started); 447 return data.result; 448 out_module_put: 449 module_put(THIS_MODULE); 450 return status; 451 } 452 453 /* 454 * Retrieve the inode associated with a delegation 455 */ 456 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle) 457 { 458 struct nfs_delegation *delegation; 459 struct inode *res = NULL; 460 rcu_read_lock(); 461 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 462 if (nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { 463 res = igrab(delegation->inode); 464 break; 465 } 466 } 467 rcu_read_unlock(); 468 return res; 469 } 470 471 /* 472 * Mark all delegations as needing to be reclaimed 473 */ 474 void nfs_delegation_mark_reclaim(struct nfs_client *clp) 475 { 476 struct nfs_delegation *delegation; 477 rcu_read_lock(); 478 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) 479 delegation->flags |= NFS_DELEGATION_NEED_RECLAIM; 480 rcu_read_unlock(); 481 } 482 483 /* 484 * Reap all unclaimed delegations after reboot recovery is done 485 */ 486 void nfs_delegation_reap_unclaimed(struct nfs_client *clp) 487 { 488 struct nfs_delegation *delegation; 489 restart: 490 rcu_read_lock(); 491 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 492 if ((delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0) 493 continue; 494 spin_lock(&clp->cl_lock); 495 delegation = nfs_detach_delegation_locked(NFS_I(delegation->inode), NULL); 496 spin_unlock(&clp->cl_lock); 497 rcu_read_unlock(); 498 if (delegation != NULL) 499 nfs_free_delegation(delegation); 500 goto restart; 501 } 502 rcu_read_unlock(); 503 } 504 505 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) 506 { 507 struct nfs_inode *nfsi = NFS_I(inode); 508 struct nfs_delegation *delegation; 509 int ret = 0; 510 511 rcu_read_lock(); 512 delegation = rcu_dereference(nfsi->delegation); 513 if (delegation != NULL) { 514 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data)); 515 ret = 1; 516 } 517 rcu_read_unlock(); 518 return ret; 519 } 520