diff options
-rw-r--r-- | fs/nfs/inode.c | 19 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 35 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 4 |
4 files changed, 26 insertions, 38 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index cc7a9064be90..23ecf0334a18 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -490,7 +490,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
490 | spin_unlock(&inode->i_lock); | 490 | spin_unlock(&inode->i_lock); |
491 | } | 491 | } |
492 | if (ctx->state != NULL) | 492 | if (ctx->state != NULL) |
493 | nfs4_close_state(ctx->state, ctx->mode); | 493 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); |
494 | if (ctx->cred != NULL) | 494 | if (ctx->cred != NULL) |
495 | put_rpccred(ctx->cred); | 495 | put_rpccred(ctx->cred); |
496 | dput(ctx->path.dentry); | 496 | dput(ctx->path.dentry); |
@@ -1103,27 +1103,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1103 | */ | 1103 | */ |
1104 | void nfs4_clear_inode(struct inode *inode) | 1104 | void nfs4_clear_inode(struct inode *inode) |
1105 | { | 1105 | { |
1106 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1107 | |||
1108 | /* If we are holding a delegation, return it! */ | 1106 | /* If we are holding a delegation, return it! */ |
1109 | nfs_inode_return_delegation(inode); | 1107 | nfs_inode_return_delegation(inode); |
1110 | /* First call standard NFS clear_inode() code */ | 1108 | /* First call standard NFS clear_inode() code */ |
1111 | nfs_clear_inode(inode); | 1109 | 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 | } | 1110 | } |
1128 | #endif | 1111 | #endif |
1129 | 1112 | ||
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index cf3a17eb5c09..c97a0ad8430e 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -165,7 +165,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc | |||
165 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); | 165 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); |
166 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); | 166 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); |
167 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); | 167 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); |
168 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); | 168 | extern int nfs4_do_close(struct path *path, struct nfs4_state *state); |
169 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 169 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
170 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 170 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
171 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); | 171 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); |
@@ -196,7 +196,7 @@ extern void nfs4_put_state_owner(struct nfs4_state_owner *); | |||
196 | extern void nfs4_drop_state_owner(struct nfs4_state_owner *); | 196 | extern void nfs4_drop_state_owner(struct nfs4_state_owner *); |
197 | extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); | 197 | extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); |
198 | extern void nfs4_put_open_state(struct nfs4_state *); | 198 | extern void nfs4_put_open_state(struct nfs4_state *); |
199 | extern void nfs4_close_state(struct nfs4_state *, mode_t); | 199 | extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t); |
200 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); | 200 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); |
201 | extern void nfs4_schedule_state_recovery(struct nfs_client *); | 201 | extern void nfs4_schedule_state_recovery(struct nfs_client *); |
202 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); | 202 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
@@ -222,7 +222,7 @@ extern struct svc_version nfs4_callback_version1; | |||
222 | 222 | ||
223 | #else | 223 | #else |
224 | 224 | ||
225 | #define nfs4_close_state(a, b) do { } while (0) | 225 | #define nfs4_close_state(a, b, c) do { } while (0) |
226 | 226 | ||
227 | #endif /* CONFIG_NFS_V4 */ | 227 | #endif /* CONFIG_NFS_V4 */ |
228 | #endif /* __LINUX_FS_NFS_NFS4_FS.H */ | 228 | #endif /* __LINUX_FS_NFS_NFS4_FS.H */ |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 895e8e649c91..8feaf232f2e4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -453,7 +453,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state * | |||
453 | opendata->owner->so_cred, | 453 | opendata->owner->so_cred, |
454 | &opendata->o_res); | 454 | &opendata->o_res); |
455 | } | 455 | } |
456 | nfs4_close_state(newstate, opendata->o_arg.open_flags); | 456 | nfs4_close_state(&opendata->path, newstate, opendata->o_arg.open_flags); |
457 | } | 457 | } |
458 | if (newstate != state) | 458 | if (newstate != state) |
459 | return -ESTALE; | 459 | return -ESTALE; |
@@ -603,7 +603,7 @@ static void nfs4_open_confirm_release(void *calldata) | |||
603 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | 603 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
604 | state = nfs4_opendata_to_nfs4_state(data); | 604 | state = nfs4_opendata_to_nfs4_state(data); |
605 | if (state != NULL) | 605 | if (state != NULL) |
606 | nfs4_close_state(state, data->o_arg.open_flags); | 606 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
607 | out_free: | 607 | out_free: |
608 | nfs4_opendata_free(data); | 608 | nfs4_opendata_free(data); |
609 | } | 609 | } |
@@ -706,7 +706,7 @@ static void nfs4_open_release(void *calldata) | |||
706 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | 706 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
707 | state = nfs4_opendata_to_nfs4_state(data); | 707 | state = nfs4_opendata_to_nfs4_state(data); |
708 | if (state != NULL) | 708 | if (state != NULL) |
709 | nfs4_close_state(state, data->o_arg.open_flags); | 709 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
710 | out_free: | 710 | out_free: |
711 | nfs4_opendata_free(data); | 711 | nfs4_opendata_free(data); |
712 | } | 712 | } |
@@ -1103,6 +1103,7 @@ static int nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, | |||
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | struct nfs4_closedata { | 1105 | struct nfs4_closedata { |
1106 | struct path path; | ||
1106 | struct inode *inode; | 1107 | struct inode *inode; |
1107 | struct nfs4_state *state; | 1108 | struct nfs4_state *state; |
1108 | struct nfs_closeargs arg; | 1109 | struct nfs_closeargs arg; |
@@ -1119,6 +1120,8 @@ static void nfs4_free_closedata(void *data) | |||
1119 | nfs4_put_open_state(calldata->state); | 1120 | nfs4_put_open_state(calldata->state); |
1120 | nfs_free_seqid(calldata->arg.seqid); | 1121 | nfs_free_seqid(calldata->arg.seqid); |
1121 | nfs4_put_state_owner(sp); | 1122 | nfs4_put_state_owner(sp); |
1123 | dput(calldata->path.dentry); | ||
1124 | mntput(calldata->path.mnt); | ||
1122 | kfree(calldata); | 1125 | kfree(calldata); |
1123 | } | 1126 | } |
1124 | 1127 | ||
@@ -1211,18 +1214,18 @@ static const struct rpc_call_ops nfs4_close_ops = { | |||
1211 | * | 1214 | * |
1212 | * NOTE: Caller must be holding the sp->so_owner semaphore! | 1215 | * NOTE: Caller must be holding the sp->so_owner semaphore! |
1213 | */ | 1216 | */ |
1214 | int nfs4_do_close(struct inode *inode, struct nfs4_state *state) | 1217 | int nfs4_do_close(struct path *path, struct nfs4_state *state) |
1215 | { | 1218 | { |
1216 | struct nfs_server *server = NFS_SERVER(inode); | 1219 | struct nfs_server *server = NFS_SERVER(state->inode); |
1217 | struct nfs4_closedata *calldata; | 1220 | struct nfs4_closedata *calldata; |
1218 | int status = -ENOMEM; | 1221 | int status = -ENOMEM; |
1219 | 1222 | ||
1220 | calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); | 1223 | calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); |
1221 | if (calldata == NULL) | 1224 | if (calldata == NULL) |
1222 | goto out; | 1225 | goto out; |
1223 | calldata->inode = inode; | 1226 | calldata->inode = state->inode; |
1224 | calldata->state = state; | 1227 | calldata->state = state; |
1225 | calldata->arg.fh = NFS_FH(inode); | 1228 | calldata->arg.fh = NFS_FH(state->inode); |
1226 | calldata->arg.stateid = &state->stateid; | 1229 | calldata->arg.stateid = &state->stateid; |
1227 | /* Serialization for the sequence id */ | 1230 | /* Serialization for the sequence id */ |
1228 | calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); | 1231 | calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); |
@@ -1231,6 +1234,8 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state) | |||
1231 | calldata->arg.bitmask = server->attr_bitmask; | 1234 | calldata->arg.bitmask = server->attr_bitmask; |
1232 | calldata->res.fattr = &calldata->fattr; | 1235 | calldata->res.fattr = &calldata->fattr; |
1233 | calldata->res.server = server; | 1236 | calldata->res.server = server; |
1237 | calldata->path.mnt = mntget(path->mnt); | ||
1238 | calldata->path.dentry = dget(path->dentry); | ||
1234 | 1239 | ||
1235 | status = nfs4_call_async(server->client, &nfs4_close_ops, calldata); | 1240 | status = nfs4_call_async(server->client, &nfs4_close_ops, calldata); |
1236 | if (status == 0) | 1241 | if (status == 0) |
@@ -1243,18 +1248,18 @@ out: | |||
1243 | return status; | 1248 | return status; |
1244 | } | 1249 | } |
1245 | 1250 | ||
1246 | static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state) | 1251 | static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state) |
1247 | { | 1252 | { |
1248 | struct file *filp; | 1253 | struct file *filp; |
1249 | 1254 | ||
1250 | filp = lookup_instantiate_filp(nd, dentry, NULL); | 1255 | filp = lookup_instantiate_filp(nd, path->dentry, NULL); |
1251 | if (!IS_ERR(filp)) { | 1256 | if (!IS_ERR(filp)) { |
1252 | struct nfs_open_context *ctx; | 1257 | struct nfs_open_context *ctx; |
1253 | ctx = (struct nfs_open_context *)filp->private_data; | 1258 | ctx = (struct nfs_open_context *)filp->private_data; |
1254 | ctx->state = state; | 1259 | ctx->state = state; |
1255 | return 0; | 1260 | return 0; |
1256 | } | 1261 | } |
1257 | nfs4_close_state(state, nd->intent.open.flags); | 1262 | nfs4_close_state(path, state, nd->intent.open.flags); |
1258 | return PTR_ERR(filp); | 1263 | return PTR_ERR(filp); |
1259 | } | 1264 | } |
1260 | 1265 | ||
@@ -1293,7 +1298,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
1293 | res = d_add_unique(dentry, igrab(state->inode)); | 1298 | res = d_add_unique(dentry, igrab(state->inode)); |
1294 | if (res != NULL) | 1299 | if (res != NULL) |
1295 | dentry = res; | 1300 | dentry = res; |
1296 | nfs4_intent_set_file(nd, dentry, state); | 1301 | nfs4_intent_set_file(nd, &path, state); |
1297 | return res; | 1302 | return res; |
1298 | } | 1303 | } |
1299 | 1304 | ||
@@ -1328,10 +1333,10 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st | |||
1328 | } | 1333 | } |
1329 | } | 1334 | } |
1330 | if (state->inode == dentry->d_inode) { | 1335 | if (state->inode == dentry->d_inode) { |
1331 | nfs4_intent_set_file(nd, dentry, state); | 1336 | nfs4_intent_set_file(nd, &path, state); |
1332 | return 1; | 1337 | return 1; |
1333 | } | 1338 | } |
1334 | nfs4_close_state(state, openflags); | 1339 | nfs4_close_state(&path, state, openflags); |
1335 | out_drop: | 1340 | out_drop: |
1336 | d_drop(dentry); | 1341 | d_drop(dentry); |
1337 | return 0; | 1342 | return 0; |
@@ -1789,9 +1794,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
1789 | nfs_setattr_update_inode(state->inode, sattr); | 1794 | nfs_setattr_update_inode(state->inode, sattr); |
1790 | } | 1795 | } |
1791 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) | 1796 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) |
1792 | status = nfs4_intent_set_file(nd, dentry, state); | 1797 | status = nfs4_intent_set_file(nd, &path, state); |
1793 | else | 1798 | else |
1794 | nfs4_close_state(state, flags); | 1799 | nfs4_close_state(&path, state, flags); |
1795 | out: | 1800 | out: |
1796 | return status; | 1801 | return status; |
1797 | } | 1802 | } |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 8ed79d5c54f9..a85138ef67ad 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -341,7 +341,7 @@ void nfs4_put_open_state(struct nfs4_state *state) | |||
341 | /* | 341 | /* |
342 | * Close the current file. | 342 | * Close the current file. |
343 | */ | 343 | */ |
344 | void nfs4_close_state(struct nfs4_state *state, mode_t mode) | 344 | void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode) |
345 | { | 345 | { |
346 | struct inode *inode = state->inode; | 346 | struct inode *inode = state->inode; |
347 | struct nfs4_state_owner *owner = state->owner; | 347 | struct nfs4_state_owner *owner = state->owner; |
@@ -375,7 +375,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
375 | spin_unlock(&inode->i_lock); | 375 | spin_unlock(&inode->i_lock); |
376 | spin_unlock(&owner->so_lock); | 376 | spin_unlock(&owner->so_lock); |
377 | 377 | ||
378 | if (oldstate != newstate && nfs4_do_close(inode, state) == 0) | 378 | if (oldstate != newstate && nfs4_do_close(path, state) == 0) |
379 | return; | 379 | return; |
380 | nfs4_put_open_state(state); | 380 | nfs4_put_open_state(state); |
381 | nfs4_put_state_owner(owner); | 381 | nfs4_put_state_owner(owner); |