diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-17 10:56:51 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-17 10:56:51 -0400 |
commit | c0204fd2b8fe047b18b67e07e1bf2a03691240cd (patch) | |
tree | d6cf75bc11d08f190c0757ba98b5ae6baef49402 | |
parent | 535918f14176396646b5547b7d1353c932f24f5e (diff) |
NFS: Clean up nfs4_proc_create()
Remove all remaining references to the struct nameidata from the low level
NFS layers. Again pass down a partially initialised struct nfs_open_context
when we want to do atomic open+create.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/dir.c | 47 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 56 | ||||
-rw-r--r-- | fs/nfs/proc.c | 2 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
5 files changed, 58 insertions, 51 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index dc93d356341b..e37ffddd79c2 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -105,8 +105,9 @@ const struct inode_operations nfs3_dir_inode_operations = { | |||
105 | #ifdef CONFIG_NFS_V4 | 105 | #ifdef CONFIG_NFS_V4 |
106 | 106 | ||
107 | static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *); | 107 | static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *); |
108 | static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd); | ||
108 | const struct inode_operations nfs4_dir_inode_operations = { | 109 | const struct inode_operations nfs4_dir_inode_operations = { |
109 | .create = nfs_create, | 110 | .create = nfs_open_create, |
110 | .lookup = nfs_atomic_lookup, | 111 | .lookup = nfs_atomic_lookup, |
111 | .link = nfs_link, | 112 | .link = nfs_link, |
112 | .unlink = nfs_unlink, | 113 | .unlink = nfs_unlink, |
@@ -1239,6 +1240,44 @@ no_open_dput: | |||
1239 | no_open: | 1240 | no_open: |
1240 | return nfs_lookup_revalidate(dentry, nd); | 1241 | return nfs_lookup_revalidate(dentry, nd); |
1241 | } | 1242 | } |
1243 | |||
1244 | static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode, | ||
1245 | struct nameidata *nd) | ||
1246 | { | ||
1247 | struct nfs_open_context *ctx = NULL; | ||
1248 | struct iattr attr; | ||
1249 | int error; | ||
1250 | int open_flags = 0; | ||
1251 | |||
1252 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | ||
1253 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | ||
1254 | |||
1255 | attr.ia_mode = mode; | ||
1256 | attr.ia_valid = ATTR_MODE; | ||
1257 | |||
1258 | if ((nd->flags & LOOKUP_CREATE) != 0) { | ||
1259 | open_flags = nd->intent.open.flags; | ||
1260 | |||
1261 | ctx = nameidata_to_nfs_open_context(dentry, nd); | ||
1262 | error = PTR_ERR(ctx); | ||
1263 | if (IS_ERR(ctx)) | ||
1264 | goto out_err; | ||
1265 | } | ||
1266 | |||
1267 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx); | ||
1268 | if (error != 0) | ||
1269 | goto out_put_ctx; | ||
1270 | if (ctx != NULL) | ||
1271 | nfs_intent_set_file(nd, ctx); | ||
1272 | return 0; | ||
1273 | out_put_ctx: | ||
1274 | if (ctx != NULL) | ||
1275 | put_nfs_open_context(ctx); | ||
1276 | out_err: | ||
1277 | d_drop(dentry); | ||
1278 | return error; | ||
1279 | } | ||
1280 | |||
1242 | #endif /* CONFIG_NFSV4 */ | 1281 | #endif /* CONFIG_NFSV4 */ |
1243 | 1282 | ||
1244 | static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) | 1283 | static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) |
@@ -1369,7 +1408,6 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1369 | { | 1408 | { |
1370 | struct iattr attr; | 1409 | struct iattr attr; |
1371 | int error; | 1410 | int error; |
1372 | int open_flags = 0; | ||
1373 | 1411 | ||
1374 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | 1412 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", |
1375 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1413 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
@@ -1377,10 +1415,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1377 | attr.ia_mode = mode; | 1415 | attr.ia_mode = mode; |
1378 | attr.ia_valid = ATTR_MODE; | 1416 | attr.ia_valid = ATTR_MODE; |
1379 | 1417 | ||
1380 | if ((nd->flags & LOOKUP_CREATE) != 0) | 1418 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, 0, NULL); |
1381 | open_flags = nd->intent.open.flags; | ||
1382 | |||
1383 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd); | ||
1384 | if (error != 0) | 1419 | if (error != 0) |
1385 | goto out_err; | 1420 | goto out_err; |
1386 | return 0; | 1421 | return 0; |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index fabb4f2849a1..2be4a7f59f1c 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -313,7 +313,7 @@ static void nfs3_free_createdata(struct nfs3_createdata *data) | |||
313 | */ | 313 | */ |
314 | static int | 314 | static int |
315 | nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 315 | nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
316 | int flags, struct nameidata *nd) | 316 | int flags, struct nfs_open_context *ctx) |
317 | { | 317 | { |
318 | struct nfs3_createdata *data; | 318 | struct nfs3_createdata *data; |
319 | mode_t mode = sattr->ia_mode; | 319 | mode_t mode = sattr->ia_mode; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 83c5ef6e7cef..617b149ee16d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1998,32 +1998,6 @@ out: | |||
1998 | return status; | 1998 | return status; |
1999 | } | 1999 | } |
2000 | 2000 | ||
2001 | static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state, fmode_t fmode) | ||
2002 | { | ||
2003 | struct file *filp; | ||
2004 | int ret; | ||
2005 | |||
2006 | /* If the open_intent is for execute, we have an extra check to make */ | ||
2007 | if (fmode & FMODE_EXEC) { | ||
2008 | ret = nfs_may_open(state->inode, | ||
2009 | state->owner->so_cred, | ||
2010 | nd->intent.open.flags); | ||
2011 | if (ret < 0) | ||
2012 | goto out_close; | ||
2013 | } | ||
2014 | filp = lookup_instantiate_filp(nd, path->dentry, NULL); | ||
2015 | if (!IS_ERR(filp)) { | ||
2016 | struct nfs_open_context *ctx; | ||
2017 | ctx = nfs_file_open_context(filp); | ||
2018 | ctx->state = state; | ||
2019 | return 0; | ||
2020 | } | ||
2021 | ret = PTR_ERR(filp); | ||
2022 | out_close: | ||
2023 | nfs4_close_sync(path, state, fmode & (FMODE_READ|FMODE_WRITE)); | ||
2024 | return ret; | ||
2025 | } | ||
2026 | |||
2027 | struct inode * | 2001 | struct inode * |
2028 | nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr) | 2002 | nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr) |
2029 | { | 2003 | { |
@@ -2491,36 +2465,34 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page, | |||
2491 | 2465 | ||
2492 | static int | 2466 | static int |
2493 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 2467 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
2494 | int flags, struct nameidata *nd) | 2468 | int flags, struct nfs_open_context *ctx) |
2495 | { | 2469 | { |
2496 | struct path path = { | 2470 | struct path my_path = { |
2497 | .mnt = nd->path.mnt, | ||
2498 | .dentry = dentry, | 2471 | .dentry = dentry, |
2499 | }; | 2472 | }; |
2473 | struct path *path = &my_path; | ||
2500 | struct nfs4_state *state; | 2474 | struct nfs4_state *state; |
2501 | struct rpc_cred *cred; | 2475 | struct rpc_cred *cred = NULL; |
2502 | fmode_t fmode = flags & (FMODE_READ | FMODE_WRITE); | 2476 | fmode_t fmode = 0; |
2503 | int status = 0; | 2477 | int status = 0; |
2504 | 2478 | ||
2505 | cred = rpc_lookup_cred(); | 2479 | if (ctx != NULL) { |
2506 | if (IS_ERR(cred)) { | 2480 | cred = ctx->cred; |
2507 | status = PTR_ERR(cred); | 2481 | path = &ctx->path; |
2508 | goto out; | 2482 | fmode = ctx->mode; |
2509 | } | 2483 | } |
2510 | state = nfs4_do_open(dir, &path, fmode, flags, sattr, cred); | 2484 | state = nfs4_do_open(dir, path, fmode, flags, sattr, cred); |
2511 | d_drop(dentry); | 2485 | d_drop(dentry); |
2512 | if (IS_ERR(state)) { | 2486 | if (IS_ERR(state)) { |
2513 | status = PTR_ERR(state); | 2487 | status = PTR_ERR(state); |
2514 | goto out_putcred; | 2488 | goto out; |
2515 | } | 2489 | } |
2516 | d_add(dentry, igrab(state->inode)); | 2490 | d_add(dentry, igrab(state->inode)); |
2517 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 2491 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
2518 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) | 2492 | if (ctx != NULL) |
2519 | status = nfs4_intent_set_file(nd, &path, state, fmode); | 2493 | ctx->state = state; |
2520 | else | 2494 | else |
2521 | nfs4_close_sync(&path, state, fmode); | 2495 | nfs4_close_sync(path, state, fmode); |
2522 | out_putcred: | ||
2523 | put_rpccred(cred); | ||
2524 | out: | 2496 | out: |
2525 | return status; | 2497 | return status; |
2526 | } | 2498 | } |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 611bec22f552..4ef39ae88ea5 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -258,7 +258,7 @@ static void nfs_free_createdata(const struct nfs_createdata *data) | |||
258 | 258 | ||
259 | static int | 259 | static int |
260 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 260 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
261 | int flags, struct nameidata *nd) | 261 | int flags, struct nfs_open_context *ctx) |
262 | { | 262 | { |
263 | struct nfs_createdata *data; | 263 | struct nfs_createdata *data; |
264 | struct rpc_message msg = { | 264 | struct rpc_message msg = { |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index fc461926c412..b1484dad7bef 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -1032,7 +1032,7 @@ struct nfs_rpc_ops { | |||
1032 | int (*readlink)(struct inode *, struct page *, unsigned int, | 1032 | int (*readlink)(struct inode *, struct page *, unsigned int, |
1033 | unsigned int); | 1033 | unsigned int); |
1034 | int (*create) (struct inode *, struct dentry *, | 1034 | int (*create) (struct inode *, struct dentry *, |
1035 | struct iattr *, int, struct nameidata *); | 1035 | struct iattr *, int, struct nfs_open_context *); |
1036 | int (*remove) (struct inode *, struct qstr *); | 1036 | int (*remove) (struct inode *, struct qstr *); |
1037 | void (*unlink_setup) (struct rpc_message *, struct inode *dir); | 1037 | void (*unlink_setup) (struct rpc_message *, struct inode *dir); |
1038 | int (*unlink_done) (struct rpc_task *, struct inode *); | 1038 | int (*unlink_done) (struct rpc_task *, struct inode *); |