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 != 0; 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 __FUNCTION__, 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 /* 129 * Set up a delegation on an inode 130 */ 131 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 132 { 133 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 134 struct nfs_inode *nfsi = NFS_I(inode); 135 struct nfs_delegation *delegation; 136 int status = 0; 137 138 delegation = kmalloc(sizeof(*delegation), GFP_KERNEL); 139 if (delegation == NULL) 140 return -ENOMEM; 141 memcpy(delegation->stateid.data, res->delegation.data, 142 sizeof(delegation->stateid.data)); 143 delegation->type = res->delegation_type; 144 delegation->maxsize = res->maxsize; 145 delegation->change_attr = nfsi->change_attr; 146 delegation->cred = get_rpccred(cred); 147 delegation->inode = inode; 148 149 spin_lock(&clp->cl_lock); 150 if (rcu_dereference(nfsi->delegation) == NULL) { 151 list_add_rcu(&delegation->super_list, &clp->cl_delegations); 152 nfsi->delegation_state = delegation->type; 153 rcu_assign_pointer(nfsi->delegation, delegation); 154 delegation = NULL; 155 } else { 156 if (memcmp(&delegation->stateid, &nfsi->delegation->stateid, 157 sizeof(delegation->stateid)) != 0 || 158 delegation->type != nfsi->delegation->type) { 159 printk("%s: server %u.%u.%u.%u, handed out a duplicate delegation!\n", 160 __FUNCTION__, NIPQUAD(clp->cl_addr.sin_addr)); 161 status = -EIO; 162 } 163 } 164 165 /* Ensure we revalidate the attributes and page cache! */ 166 spin_lock(&inode->i_lock); 167 nfsi->cache_validity |= NFS_INO_REVAL_FORCED; 168 spin_unlock(&inode->i_lock); 169 170 spin_unlock(&clp->cl_lock); 171 kfree(delegation); 172 return status; 173 } 174 175 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 176 { 177 int res = 0; 178 179 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); 180 nfs_free_delegation(delegation); 181 return res; 182 } 183 184 /* Sync all data to disk upon delegation return */ 185 static void nfs_msync_inode(struct inode *inode) 186 { 187 filemap_fdatawrite(inode->i_mapping); 188 nfs_wb_all(inode); 189 filemap_fdatawait(inode->i_mapping); 190 } 191 192 /* 193 * Basic procedure for returning a delegation to the server 194 */ 195 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 196 { 197 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 198 struct nfs_inode *nfsi = NFS_I(inode); 199 200 nfs_msync_inode(inode); 201 down_read(&clp->cl_sem); 202 /* Guard against new delegated open calls */ 203 down_write(&nfsi->rwsem); 204 nfs_delegation_claim_opens(inode, &delegation->stateid); 205 up_write(&nfsi->rwsem); 206 up_read(&clp->cl_sem); 207 nfs_msync_inode(inode); 208 209 return nfs_do_return_delegation(inode, delegation); 210 } 211 212 static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid) 213 { 214 struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation); 215 216 if (delegation == NULL) 217 goto nomatch; 218 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, 219 sizeof(delegation->stateid.data)) != 0) 220 goto nomatch; 221 list_del_rcu(&delegation->super_list); 222 nfsi->delegation_state = 0; 223 rcu_assign_pointer(nfsi->delegation, NULL); 224 return delegation; 225 nomatch: 226 return NULL; 227 } 228 229 int nfs_inode_return_delegation(struct inode *inode) 230 { 231 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 232 struct nfs_inode *nfsi = NFS_I(inode); 233 struct nfs_delegation *delegation; 234 int err = 0; 235 236 if (rcu_dereference(nfsi->delegation) != NULL) { 237 spin_lock(&clp->cl_lock); 238 delegation = nfs_detach_delegation_locked(nfsi, NULL); 239 spin_unlock(&clp->cl_lock); 240 if (delegation != NULL) 241 err = __nfs_inode_return_delegation(inode, delegation); 242 } 243 return err; 244 } 245 246 /* 247 * Return all delegations associated to a super block 248 */ 249 void nfs_return_all_delegations(struct super_block *sb) 250 { 251 struct nfs_client *clp = NFS_SB(sb)->nfs_client; 252 struct nfs_delegation *delegation; 253 struct inode *inode; 254 255 if (clp == NULL) 256 return; 257 restart: 258 rcu_read_lock(); 259 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 260 if (delegation->inode->i_sb != sb) 261 continue; 262 inode = igrab(delegation->inode); 263 if (inode == NULL) 264 continue; 265 spin_lock(&clp->cl_lock); 266 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 267 spin_unlock(&clp->cl_lock); 268 rcu_read_unlock(); 269 if (delegation != NULL) 270 __nfs_inode_return_delegation(inode, delegation); 271 iput(inode); 272 goto restart; 273 } 274 rcu_read_unlock(); 275 } 276 277 static int nfs_do_expire_all_delegations(void *ptr) 278 { 279 struct nfs_client *clp = ptr; 280 struct nfs_delegation *delegation; 281 struct inode *inode; 282 283 allow_signal(SIGKILL); 284 restart: 285 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0) 286 goto out; 287 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) 288 goto out; 289 rcu_read_lock(); 290 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 291 inode = igrab(delegation->inode); 292 if (inode == NULL) 293 continue; 294 spin_lock(&clp->cl_lock); 295 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 296 spin_unlock(&clp->cl_lock); 297 rcu_read_unlock(); 298 if (delegation) 299 __nfs_inode_return_delegation(inode, delegation); 300 iput(inode); 301 goto restart; 302 } 303 rcu_read_unlock(); 304 out: 305 nfs_put_client(clp); 306 module_put_and_exit(0); 307 } 308 309 void nfs_expire_all_delegations(struct nfs_client *clp) 310 { 311 struct task_struct *task; 312 313 __module_get(THIS_MODULE); 314 atomic_inc(&clp->cl_count); 315 task = kthread_run(nfs_do_expire_all_delegations, clp, 316 "%u.%u.%u.%u-delegreturn", 317 NIPQUAD(clp->cl_addr.sin_addr)); 318 if (!IS_ERR(task)) 319 return; 320 nfs_put_client(clp); 321 module_put(THIS_MODULE); 322 } 323 324 /* 325 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 326 */ 327 void nfs_handle_cb_pathdown(struct nfs_client *clp) 328 { 329 struct nfs_delegation *delegation; 330 struct inode *inode; 331 332 if (clp == NULL) 333 return; 334 restart: 335 rcu_read_lock(); 336 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 337 inode = igrab(delegation->inode); 338 if (inode == NULL) 339 continue; 340 spin_lock(&clp->cl_lock); 341 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 342 spin_unlock(&clp->cl_lock); 343 rcu_read_unlock(); 344 if (delegation != NULL) 345 __nfs_inode_return_delegation(inode, delegation); 346 iput(inode); 347 goto restart; 348 } 349 rcu_read_unlock(); 350 } 351 352 struct recall_threadargs { 353 struct inode *inode; 354 struct nfs_client *clp; 355 const nfs4_stateid *stateid; 356 357 struct completion started; 358 int result; 359 }; 360 361 static int recall_thread(void *data) 362 { 363 struct recall_threadargs *args = (struct recall_threadargs *)data; 364 struct inode *inode = igrab(args->inode); 365 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 366 struct nfs_inode *nfsi = NFS_I(inode); 367 struct nfs_delegation *delegation; 368 369 daemonize("nfsv4-delegreturn"); 370 371 nfs_msync_inode(inode); 372 down_read(&clp->cl_sem); 373 down_write(&nfsi->rwsem); 374 spin_lock(&clp->cl_lock); 375 delegation = nfs_detach_delegation_locked(nfsi, args->stateid); 376 if (delegation != NULL) 377 args->result = 0; 378 else 379 args->result = -ENOENT; 380 spin_unlock(&clp->cl_lock); 381 complete(&args->started); 382 nfs_delegation_claim_opens(inode, args->stateid); 383 up_write(&nfsi->rwsem); 384 up_read(&clp->cl_sem); 385 nfs_msync_inode(inode); 386 387 if (delegation != NULL) 388 nfs_do_return_delegation(inode, delegation); 389 iput(inode); 390 module_put_and_exit(0); 391 } 392 393 /* 394 * Asynchronous delegation recall! 395 */ 396 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 397 { 398 struct recall_threadargs data = { 399 .inode = inode, 400 .stateid = stateid, 401 }; 402 int status; 403 404 init_completion(&data.started); 405 __module_get(THIS_MODULE); 406 status = kernel_thread(recall_thread, &data, CLONE_KERNEL); 407 if (status < 0) 408 goto out_module_put; 409 wait_for_completion(&data.started); 410 return data.result; 411 out_module_put: 412 module_put(THIS_MODULE); 413 return status; 414 } 415 416 /* 417 * Retrieve the inode associated with a delegation 418 */ 419 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle) 420 { 421 struct nfs_delegation *delegation; 422 struct inode *res = NULL; 423 rcu_read_lock(); 424 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 425 if (nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { 426 res = igrab(delegation->inode); 427 break; 428 } 429 } 430 rcu_read_unlock(); 431 return res; 432 } 433 434 /* 435 * Mark all delegations as needing to be reclaimed 436 */ 437 void nfs_delegation_mark_reclaim(struct nfs_client *clp) 438 { 439 struct nfs_delegation *delegation; 440 rcu_read_lock(); 441 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) 442 delegation->flags |= NFS_DELEGATION_NEED_RECLAIM; 443 rcu_read_unlock(); 444 } 445 446 /* 447 * Reap all unclaimed delegations after reboot recovery is done 448 */ 449 void nfs_delegation_reap_unclaimed(struct nfs_client *clp) 450 { 451 struct nfs_delegation *delegation; 452 restart: 453 rcu_read_lock(); 454 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 455 if ((delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0) 456 continue; 457 spin_lock(&clp->cl_lock); 458 delegation = nfs_detach_delegation_locked(NFS_I(delegation->inode), NULL); 459 spin_unlock(&clp->cl_lock); 460 rcu_read_unlock(); 461 if (delegation != NULL) 462 nfs_free_delegation(delegation); 463 goto restart; 464 } 465 rcu_read_unlock(); 466 } 467 468 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) 469 { 470 struct nfs_inode *nfsi = NFS_I(inode); 471 struct nfs_delegation *delegation; 472 int ret = 0; 473 474 rcu_read_lock(); 475 delegation = rcu_dereference(nfsi->delegation); 476 if (delegation != NULL) { 477 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data)); 478 ret = 1; 479 } 480 rcu_read_unlock(); 481 return ret; 482 } 483