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