diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 73 |
1 files changed, 30 insertions, 43 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bd9f5a836592..3d9fccf4ef93 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -461,14 +461,14 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str | |||
461 | 461 | ||
462 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 462 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
463 | if (ctx != NULL) { | 463 | if (ctx != NULL) { |
464 | atomic_set(&ctx->count, 1); | 464 | ctx->path.dentry = dget(dentry); |
465 | ctx->dentry = dget(dentry); | 465 | ctx->path.mnt = mntget(mnt); |
466 | ctx->vfsmnt = mntget(mnt); | ||
467 | ctx->cred = get_rpccred(cred); | 466 | ctx->cred = get_rpccred(cred); |
468 | ctx->state = NULL; | 467 | ctx->state = NULL; |
469 | ctx->lockowner = current->files; | 468 | ctx->lockowner = current->files; |
470 | ctx->error = 0; | 469 | ctx->error = 0; |
471 | ctx->dir_cookie = 0; | 470 | ctx->dir_cookie = 0; |
471 | kref_init(&ctx->kref); | ||
472 | } | 472 | } |
473 | return ctx; | 473 | return ctx; |
474 | } | 474 | } |
@@ -476,27 +476,33 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str | |||
476 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | 476 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) |
477 | { | 477 | { |
478 | if (ctx != NULL) | 478 | if (ctx != NULL) |
479 | atomic_inc(&ctx->count); | 479 | kref_get(&ctx->kref); |
480 | return ctx; | 480 | return ctx; |
481 | } | 481 | } |
482 | 482 | ||
483 | void put_nfs_open_context(struct nfs_open_context *ctx) | 483 | static void nfs_free_open_context(struct kref *kref) |
484 | { | 484 | { |
485 | if (atomic_dec_and_test(&ctx->count)) { | 485 | struct nfs_open_context *ctx = container_of(kref, |
486 | if (!list_empty(&ctx->list)) { | 486 | struct nfs_open_context, kref); |
487 | struct inode *inode = ctx->dentry->d_inode; | 487 | |
488 | spin_lock(&inode->i_lock); | 488 | if (!list_empty(&ctx->list)) { |
489 | list_del(&ctx->list); | 489 | struct inode *inode = ctx->path.dentry->d_inode; |
490 | spin_unlock(&inode->i_lock); | 490 | spin_lock(&inode->i_lock); |
491 | } | 491 | list_del(&ctx->list); |
492 | if (ctx->state != NULL) | 492 | spin_unlock(&inode->i_lock); |
493 | nfs4_close_state(ctx->state, ctx->mode); | ||
494 | if (ctx->cred != NULL) | ||
495 | put_rpccred(ctx->cred); | ||
496 | dput(ctx->dentry); | ||
497 | mntput(ctx->vfsmnt); | ||
498 | kfree(ctx); | ||
499 | } | 493 | } |
494 | if (ctx->state != NULL) | ||
495 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); | ||
496 | if (ctx->cred != NULL) | ||
497 | put_rpccred(ctx->cred); | ||
498 | dput(ctx->path.dentry); | ||
499 | mntput(ctx->path.mnt); | ||
500 | kfree(ctx); | ||
501 | } | ||
502 | |||
503 | void put_nfs_open_context(struct nfs_open_context *ctx) | ||
504 | { | ||
505 | kref_put(&ctx->kref, nfs_free_open_context); | ||
500 | } | 506 | } |
501 | 507 | ||
502 | /* | 508 | /* |
@@ -961,8 +967,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
961 | goto out_changed; | 967 | goto out_changed; |
962 | 968 | ||
963 | server = NFS_SERVER(inode); | 969 | server = NFS_SERVER(inode); |
964 | /* Update the fsid if and only if this is the root directory */ | 970 | /* Update the fsid? */ |
965 | if (inode == inode->i_sb->s_root->d_inode | 971 | if (S_ISDIR(inode->i_mode) |
966 | && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) | 972 | && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) |
967 | server->fsid = fattr->fsid; | 973 | server->fsid = fattr->fsid; |
968 | 974 | ||
@@ -1066,8 +1072,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1066 | invalid &= ~NFS_INO_INVALID_DATA; | 1072 | invalid &= ~NFS_INO_INVALID_DATA; |
1067 | if (data_stable) | 1073 | if (data_stable) |
1068 | invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); | 1074 | invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); |
1069 | if (!nfs_have_delegation(inode, FMODE_READ)) | 1075 | if (!nfs_have_delegation(inode, FMODE_READ) || |
1076 | (nfsi->cache_validity & NFS_INO_REVAL_FORCED)) | ||
1070 | nfsi->cache_validity |= invalid; | 1077 | nfsi->cache_validity |= invalid; |
1078 | nfsi->cache_validity &= ~NFS_INO_REVAL_FORCED; | ||
1071 | 1079 | ||
1072 | return 0; | 1080 | return 0; |
1073 | out_changed: | 1081 | out_changed: |
@@ -1103,27 +1111,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1103 | */ | 1111 | */ |
1104 | void nfs4_clear_inode(struct inode *inode) | 1112 | void nfs4_clear_inode(struct inode *inode) |
1105 | { | 1113 | { |
1106 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1107 | |||
1108 | /* If we are holding a delegation, return it! */ | 1114 | /* If we are holding a delegation, return it! */ |
1109 | nfs_inode_return_delegation(inode); | 1115 | nfs_inode_return_delegation(inode); |
1110 | /* First call standard NFS clear_inode() code */ | 1116 | /* First call standard NFS clear_inode() code */ |
1111 | nfs_clear_inode(inode); | 1117 | nfs_clear_inode(inode); |
1112 | /* Now clear out any remaining state */ | ||
1113 | while (!list_empty(&nfsi->open_states)) { | ||
1114 | struct nfs4_state *state; | ||
1115 | |||
1116 | state = list_entry(nfsi->open_states.next, | ||
1117 | struct nfs4_state, | ||
1118 | inode_states); | ||
1119 | dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n", | ||
1120 | __FUNCTION__, | ||
1121 | inode->i_sb->s_id, | ||
1122 | (long long)NFS_FILEID(inode), | ||
1123 | state); | ||
1124 | BUG_ON(atomic_read(&state->count) != 1); | ||
1125 | nfs4_close_state(state, state->state); | ||
1126 | } | ||
1127 | } | 1118 | } |
1128 | #endif | 1119 | #endif |
1129 | 1120 | ||
@@ -1165,15 +1156,11 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
1165 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; | 1156 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; |
1166 | 1157 | ||
1167 | inode_init_once(&nfsi->vfs_inode); | 1158 | inode_init_once(&nfsi->vfs_inode); |
1168 | spin_lock_init(&nfsi->req_lock); | ||
1169 | INIT_LIST_HEAD(&nfsi->dirty); | ||
1170 | INIT_LIST_HEAD(&nfsi->commit); | ||
1171 | INIT_LIST_HEAD(&nfsi->open_files); | 1159 | INIT_LIST_HEAD(&nfsi->open_files); |
1172 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); | 1160 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); |
1173 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); | 1161 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); |
1174 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); | 1162 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); |
1175 | atomic_set(&nfsi->data_updates, 0); | 1163 | atomic_set(&nfsi->data_updates, 0); |
1176 | nfsi->ndirty = 0; | ||
1177 | nfsi->ncommit = 0; | 1164 | nfsi->ncommit = 0; |
1178 | nfsi->npages = 0; | 1165 | nfsi->npages = 0; |
1179 | nfs4_init_once(nfsi); | 1166 | nfs4_init_once(nfsi); |