diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 74 |
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 | ||
531 | static 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 | |||
539 | static 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 | |||
554 | struct 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 | |||
581 | void 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 | |||
578 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | 638 | struct 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); |