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