aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c74
1 files changed, 67 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 099b3518feea..581d8f081e68 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -413,10 +413,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
413 return 0; 413 return 0;
414 414
415 /* Write all dirty data */ 415 /* Write all dirty data */
416 if (S_ISREG(inode->i_mode)) { 416 if (S_ISREG(inode->i_mode))
417 filemap_write_and_wait(inode->i_mapping);
418 nfs_wb_all(inode); 417 nfs_wb_all(inode);
419 }
420 418
421 fattr = nfs_alloc_fattr(); 419 fattr = nfs_alloc_fattr();
422 if (fattr == NULL) 420 if (fattr == NULL)
@@ -530,6 +528,68 @@ out:
530 return err; 528 return err;
531} 529}
532 530
531static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
532{
533 atomic_set(&l_ctx->count, 1);
534 l_ctx->lockowner = current->files;
535 l_ctx->pid = current->tgid;
536 INIT_LIST_HEAD(&l_ctx->list);
537}
538
539static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
540{
541 struct nfs_lock_context *pos;
542
543 list_for_each_entry(pos, &ctx->lock_context.list, list) {
544 if (pos->lockowner != current->files)
545 continue;
546 if (pos->pid != current->tgid)
547 continue;
548 atomic_inc(&pos->count);
549 return pos;
550 }
551 return NULL;
552}
553
554struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
555{
556 struct nfs_lock_context *res, *new = NULL;
557 struct inode *inode = ctx->path.dentry->d_inode;
558
559 spin_lock(&inode->i_lock);
560 res = __nfs_find_lock_context(ctx);
561 if (res == NULL) {
562 spin_unlock(&inode->i_lock);
563 new = kmalloc(sizeof(*new), GFP_KERNEL);
564 if (new == NULL)
565 return NULL;
566 nfs_init_lock_context(new);
567 spin_lock(&inode->i_lock);
568 res = __nfs_find_lock_context(ctx);
569 if (res == NULL) {
570 list_add_tail(&new->list, &ctx->lock_context.list);
571 new->open_context = ctx;
572 res = new;
573 new = NULL;
574 }
575 }
576 spin_unlock(&inode->i_lock);
577 kfree(new);
578 return res;
579}
580
581void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
582{
583 struct nfs_open_context *ctx = l_ctx->open_context;
584 struct inode *inode = ctx->path.dentry->d_inode;
585
586 if (!atomic_dec_and_lock(&l_ctx->count, &inode->i_lock))
587 return;
588 list_del(&l_ctx->list);
589 spin_unlock(&inode->i_lock);
590 kfree(l_ctx);
591}
592
533/** 593/**
534 * nfs_close_context - Common close_context() routine NFSv2/v3 594 * nfs_close_context - Common close_context() routine NFSv2/v3
535 * @ctx: pointer to context 595 * @ctx: pointer to context
@@ -566,11 +626,11 @@ static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct
566 path_get(&ctx->path); 626 path_get(&ctx->path);
567 ctx->cred = get_rpccred(cred); 627 ctx->cred = get_rpccred(cred);
568 ctx->state = NULL; 628 ctx->state = NULL;
569 ctx->lockowner = current->files;
570 ctx->flags = 0; 629 ctx->flags = 0;
571 ctx->error = 0; 630 ctx->error = 0;
572 ctx->dir_cookie = 0; 631 ctx->dir_cookie = 0;
573 atomic_set(&ctx->count, 1); 632 nfs_init_lock_context(&ctx->lock_context);
633 ctx->lock_context.open_context = ctx;
574 } 634 }
575 return ctx; 635 return ctx;
576} 636}
@@ -578,7 +638,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct
578struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) 638struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
579{ 639{
580 if (ctx != NULL) 640 if (ctx != NULL)
581 atomic_inc(&ctx->count); 641 atomic_inc(&ctx->lock_context.count);
582 return ctx; 642 return ctx;
583} 643}
584 644
@@ -586,7 +646,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
586{ 646{
587 struct inode *inode = ctx->path.dentry->d_inode; 647 struct inode *inode = ctx->path.dentry->d_inode;
588 648
589 if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) 649 if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock))
590 return; 650 return;
591 list_del(&ctx->list); 651 list_del(&ctx->list);
592 spin_unlock(&inode->i_lock); 652 spin_unlock(&inode->i_lock);