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); |
