aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c19
-rw-r--r--fs/nfs/nfs4_fs.h6
-rw-r--r--fs/nfs/nfs4proc.c35
-rw-r--r--fs/nfs/nfs4state.c4
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 */
1104void nfs4_clear_inode(struct inode *inode) 1104void 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
165extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); 165extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
166extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); 166extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
167extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); 167extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
168extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); 168extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
169extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 169extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
170extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 170extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
171extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); 171extern 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 *);
196extern void nfs4_drop_state_owner(struct nfs4_state_owner *); 196extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
197extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); 197extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
198extern void nfs4_put_open_state(struct nfs4_state *); 198extern void nfs4_put_open_state(struct nfs4_state *);
199extern void nfs4_close_state(struct nfs4_state *, mode_t); 199extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
200extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); 200extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
201extern void nfs4_schedule_state_recovery(struct nfs_client *); 201extern void nfs4_schedule_state_recovery(struct nfs_client *);
202extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 202extern 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);
607out_free: 607out_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);
710out_free: 710out_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
1105struct nfs4_closedata { 1105struct 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 */
1214int nfs4_do_close(struct inode *inode, struct nfs4_state *state) 1217int 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
1246static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state) 1251static 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);
1335out_drop: 1340out_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);
1795out: 1800out:
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 */
344void nfs4_close_state(struct nfs4_state *state, mode_t mode) 344void 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);