diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d0cb6e163320..45f64701d4a6 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -70,6 +70,9 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf | |||
70 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); | 70 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); |
71 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 71 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); |
72 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 72 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); |
73 | static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | ||
74 | struct nfs_fattr *fattr, struct iattr *sattr, | ||
75 | struct nfs4_state *state); | ||
73 | 76 | ||
74 | /* Prevent leaks of NFSv4 errors into userland */ | 77 | /* Prevent leaks of NFSv4 errors into userland */ |
75 | static int nfs4_map_errors(int err) | 78 | static int nfs4_map_errors(int err) |
@@ -1659,15 +1662,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1659 | if (status != 0) | 1662 | if (status != 0) |
1660 | goto err_opendata_put; | 1663 | goto err_opendata_put; |
1661 | 1664 | ||
1662 | if (opendata->o_arg.open_flags & O_EXCL) | ||
1663 | nfs4_exclusive_attrset(opendata, sattr); | ||
1664 | |||
1665 | state = nfs4_opendata_to_nfs4_state(opendata); | 1665 | state = nfs4_opendata_to_nfs4_state(opendata); |
1666 | status = PTR_ERR(state); | 1666 | status = PTR_ERR(state); |
1667 | if (IS_ERR(state)) | 1667 | if (IS_ERR(state)) |
1668 | goto err_opendata_put; | 1668 | goto err_opendata_put; |
1669 | if (server->caps & NFS_CAP_POSIX_LOCK) | 1669 | if (server->caps & NFS_CAP_POSIX_LOCK) |
1670 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); | 1670 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); |
1671 | |||
1672 | if (opendata->o_arg.open_flags & O_EXCL) { | ||
1673 | nfs4_exclusive_attrset(opendata, sattr); | ||
1674 | |||
1675 | nfs_fattr_init(opendata->o_res.f_attr); | ||
1676 | status = nfs4_do_setattr(state->inode, cred, | ||
1677 | opendata->o_res.f_attr, sattr, | ||
1678 | state); | ||
1679 | if (status == 0) | ||
1680 | nfs_setattr_update_inode(state->inode, sattr); | ||
1681 | nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); | ||
1682 | } | ||
1671 | nfs4_opendata_put(opendata); | 1683 | nfs4_opendata_put(opendata); |
1672 | nfs4_put_state_owner(sp); | 1684 | nfs4_put_state_owner(sp); |
1673 | *res = state; | 1685 | *res = state; |
@@ -2565,13 +2577,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2565 | } | 2577 | } |
2566 | d_add(dentry, igrab(state->inode)); | 2578 | d_add(dentry, igrab(state->inode)); |
2567 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 2579 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
2568 | if (flags & O_EXCL) { | ||
2569 | struct nfs_fattr fattr; | ||
2570 | status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state); | ||
2571 | if (status == 0) | ||
2572 | nfs_setattr_update_inode(state->inode, sattr); | ||
2573 | nfs_post_op_update_inode(state->inode, &fattr); | ||
2574 | } | ||
2575 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) | 2580 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) |
2576 | status = nfs4_intent_set_file(nd, &path, state, fmode); | 2581 | status = nfs4_intent_set_file(nd, &path, state, fmode); |
2577 | else | 2582 | else |