aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 93ef77666efc..079614deca3f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -766,8 +766,8 @@ struct nfs4_opendata {
766 struct nfs_open_confirmres c_res; 766 struct nfs_open_confirmres c_res;
767 struct nfs_fattr f_attr; 767 struct nfs_fattr f_attr;
768 struct nfs_fattr dir_attr; 768 struct nfs_fattr dir_attr;
769 struct path path;
770 struct dentry *dir; 769 struct dentry *dir;
770 struct dentry *dentry;
771 struct nfs4_state_owner *owner; 771 struct nfs4_state_owner *owner;
772 struct nfs4_state *state; 772 struct nfs4_state *state;
773 struct iattr attrs; 773 struct iattr attrs;
@@ -789,12 +789,12 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
789 nfs_fattr_init(&p->dir_attr); 789 nfs_fattr_init(&p->dir_attr);
790} 790}
791 791
792static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, 792static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
793 struct nfs4_state_owner *sp, fmode_t fmode, int flags, 793 struct nfs4_state_owner *sp, fmode_t fmode, int flags,
794 const struct iattr *attrs, 794 const struct iattr *attrs,
795 gfp_t gfp_mask) 795 gfp_t gfp_mask)
796{ 796{
797 struct dentry *parent = dget_parent(path->dentry); 797 struct dentry *parent = dget_parent(dentry);
798 struct inode *dir = parent->d_inode; 798 struct inode *dir = parent->d_inode;
799 struct nfs_server *server = NFS_SERVER(dir); 799 struct nfs_server *server = NFS_SERVER(dir);
800 struct nfs4_opendata *p; 800 struct nfs4_opendata *p;
@@ -805,8 +805,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
805 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); 805 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
806 if (p->o_arg.seqid == NULL) 806 if (p->o_arg.seqid == NULL)
807 goto err_free; 807 goto err_free;
808 path_get(path); 808 nfs_sb_active(dentry->d_sb);
809 p->path = *path; 809 p->dentry = dget(dentry);
810 p->dir = parent; 810 p->dir = parent;
811 p->owner = sp; 811 p->owner = sp;
812 atomic_inc(&sp->so_count); 812 atomic_inc(&sp->so_count);
@@ -815,7 +815,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
815 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); 815 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
816 p->o_arg.clientid = server->nfs_client->cl_clientid; 816 p->o_arg.clientid = server->nfs_client->cl_clientid;
817 p->o_arg.id = sp->so_owner_id.id; 817 p->o_arg.id = sp->so_owner_id.id;
818 p->o_arg.name = &p->path.dentry->d_name; 818 p->o_arg.name = &dentry->d_name;
819 p->o_arg.server = server; 819 p->o_arg.server = server;
820 p->o_arg.bitmask = server->attr_bitmask; 820 p->o_arg.bitmask = server->attr_bitmask;
821 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 821 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
@@ -845,13 +845,15 @@ static void nfs4_opendata_free(struct kref *kref)
845{ 845{
846 struct nfs4_opendata *p = container_of(kref, 846 struct nfs4_opendata *p = container_of(kref,
847 struct nfs4_opendata, kref); 847 struct nfs4_opendata, kref);
848 struct super_block *sb = p->dentry->d_sb;
848 849
849 nfs_free_seqid(p->o_arg.seqid); 850 nfs_free_seqid(p->o_arg.seqid);
850 if (p->state != NULL) 851 if (p->state != NULL)
851 nfs4_put_open_state(p->state); 852 nfs4_put_open_state(p->state);
852 nfs4_put_state_owner(p->owner); 853 nfs4_put_state_owner(p->owner);
853 dput(p->dir); 854 dput(p->dir);
854 path_put(&p->path); 855 dput(p->dentry);
856 nfs_sb_deactive(sb);
855 kfree(p); 857 kfree(p);
856} 858}
857 859
@@ -1133,7 +1135,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
1133{ 1135{
1134 struct nfs4_opendata *opendata; 1136 struct nfs4_opendata *opendata;
1135 1137
1136 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS); 1138 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, NULL, GFP_NOFS);
1137 if (opendata == NULL) 1139 if (opendata == NULL)
1138 return ERR_PTR(-ENOMEM); 1140 return ERR_PTR(-ENOMEM);
1139 opendata->state = state; 1141 opendata->state = state;
@@ -1157,7 +1159,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod
1157 newstate = nfs4_opendata_to_nfs4_state(opendata); 1159 newstate = nfs4_opendata_to_nfs4_state(opendata);
1158 if (IS_ERR(newstate)) 1160 if (IS_ERR(newstate))
1159 return PTR_ERR(newstate); 1161 return PTR_ERR(newstate);
1160 nfs4_close_state(&opendata->path, newstate, fmode); 1162 nfs4_close_state(newstate, fmode);
1161 *res = newstate; 1163 *res = newstate;
1162 return 0; 1164 return 0;
1163} 1165}
@@ -1355,7 +1357,7 @@ static void nfs4_open_confirm_release(void *calldata)
1355 goto out_free; 1357 goto out_free;
1356 state = nfs4_opendata_to_nfs4_state(data); 1358 state = nfs4_opendata_to_nfs4_state(data);
1357 if (!IS_ERR(state)) 1359 if (!IS_ERR(state))
1358 nfs4_close_state(&data->path, state, data->o_arg.fmode); 1360 nfs4_close_state(state, data->o_arg.fmode);
1359out_free: 1361out_free:
1360 nfs4_opendata_put(data); 1362 nfs4_opendata_put(data);
1361} 1363}
@@ -1500,7 +1502,7 @@ static void nfs4_open_release(void *calldata)
1500 goto out_free; 1502 goto out_free;
1501 state = nfs4_opendata_to_nfs4_state(data); 1503 state = nfs4_opendata_to_nfs4_state(data);
1502 if (!IS_ERR(state)) 1504 if (!IS_ERR(state))
1503 nfs4_close_state(&data->path, state, data->o_arg.fmode); 1505 nfs4_close_state(state, data->o_arg.fmode);
1504out_free: 1506out_free:
1505 nfs4_opendata_put(data); 1507 nfs4_opendata_put(data);
1506} 1508}
@@ -1651,7 +1653,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1651 return PTR_ERR(opendata); 1653 return PTR_ERR(opendata);
1652 ret = nfs4_open_recover(opendata, state); 1654 ret = nfs4_open_recover(opendata, state);
1653 if (ret == -ESTALE) 1655 if (ret == -ESTALE)
1654 d_drop(ctx->path.dentry); 1656 d_drop(ctx->dentry);
1655 nfs4_opendata_put(opendata); 1657 nfs4_opendata_put(opendata);
1656 return ret; 1658 return ret;
1657} 1659}
@@ -1723,7 +1725,7 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
1723/* 1725/*
1724 * Returns a referenced nfs4_state 1726 * Returns a referenced nfs4_state
1725 */ 1727 */
1726static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) 1728static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
1727{ 1729{
1728 struct nfs4_state_owner *sp; 1730 struct nfs4_state_owner *sp;
1729 struct nfs4_state *state = NULL; 1731 struct nfs4_state *state = NULL;
@@ -1740,15 +1742,15 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
1740 status = nfs4_recover_expired_lease(server); 1742 status = nfs4_recover_expired_lease(server);
1741 if (status != 0) 1743 if (status != 0)
1742 goto err_put_state_owner; 1744 goto err_put_state_owner;
1743 if (path->dentry->d_inode != NULL) 1745 if (dentry->d_inode != NULL)
1744 nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); 1746 nfs4_return_incompatible_delegation(dentry->d_inode, fmode);
1745 status = -ENOMEM; 1747 status = -ENOMEM;
1746 opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL); 1748 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, GFP_KERNEL);
1747 if (opendata == NULL) 1749 if (opendata == NULL)
1748 goto err_put_state_owner; 1750 goto err_put_state_owner;
1749 1751
1750 if (path->dentry->d_inode != NULL) 1752 if (dentry->d_inode != NULL)
1751 opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp); 1753 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
1752 1754
1753 status = _nfs4_proc_open(opendata); 1755 status = _nfs4_proc_open(opendata);
1754 if (status != 0) 1756 if (status != 0)
@@ -1786,14 +1788,14 @@ out_err:
1786} 1788}
1787 1789
1788 1790
1789static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) 1791static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred)
1790{ 1792{
1791 struct nfs4_exception exception = { }; 1793 struct nfs4_exception exception = { };
1792 struct nfs4_state *res; 1794 struct nfs4_state *res;
1793 int status; 1795 int status;
1794 1796
1795 do { 1797 do {
1796 status = _nfs4_do_open(dir, path, fmode, flags, sattr, cred, &res); 1798 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res);
1797 if (status == 0) 1799 if (status == 0)
1798 break; 1800 break;
1799 /* NOTE: BAD_SEQID means the server and client disagree about the 1801 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -1890,7 +1892,6 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
1890} 1892}
1891 1893
1892struct nfs4_closedata { 1894struct nfs4_closedata {
1893 struct path path;
1894 struct inode *inode; 1895 struct inode *inode;
1895 struct nfs4_state *state; 1896 struct nfs4_state *state;
1896 struct nfs_closeargs arg; 1897 struct nfs_closeargs arg;
@@ -1905,13 +1906,14 @@ static void nfs4_free_closedata(void *data)
1905{ 1906{
1906 struct nfs4_closedata *calldata = data; 1907 struct nfs4_closedata *calldata = data;
1907 struct nfs4_state_owner *sp = calldata->state->owner; 1908 struct nfs4_state_owner *sp = calldata->state->owner;
1909 struct super_block *sb = calldata->state->inode->i_sb;
1908 1910
1909 if (calldata->roc) 1911 if (calldata->roc)
1910 pnfs_roc_release(calldata->state->inode); 1912 pnfs_roc_release(calldata->state->inode);
1911 nfs4_put_open_state(calldata->state); 1913 nfs4_put_open_state(calldata->state);
1912 nfs_free_seqid(calldata->arg.seqid); 1914 nfs_free_seqid(calldata->arg.seqid);
1913 nfs4_put_state_owner(sp); 1915 nfs4_put_state_owner(sp);
1914 path_put(&calldata->path); 1916 nfs_sb_deactive(sb);
1915 kfree(calldata); 1917 kfree(calldata);
1916} 1918}
1917 1919
@@ -2031,7 +2033,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
2031 * 2033 *
2032 * NOTE: Caller must be holding the sp->so_owner semaphore! 2034 * NOTE: Caller must be holding the sp->so_owner semaphore!
2033 */ 2035 */
2034int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc) 2036int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
2035{ 2037{
2036 struct nfs_server *server = NFS_SERVER(state->inode); 2038 struct nfs_server *server = NFS_SERVER(state->inode);
2037 struct nfs4_closedata *calldata; 2039 struct nfs4_closedata *calldata;
@@ -2067,8 +2069,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
2067 calldata->res.seqid = calldata->arg.seqid; 2069 calldata->res.seqid = calldata->arg.seqid;
2068 calldata->res.server = server; 2070 calldata->res.server = server;
2069 calldata->roc = roc; 2071 calldata->roc = roc;
2070 path_get(path); 2072 nfs_sb_active(calldata->inode->i_sb);
2071 calldata->path = *path;
2072 2073
2073 msg.rpc_argp = &calldata->arg; 2074 msg.rpc_argp = &calldata->arg;
2074 msg.rpc_resp = &calldata->res; 2075 msg.rpc_resp = &calldata->res;
@@ -2097,7 +2098,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags
2097 struct nfs4_state *state; 2098 struct nfs4_state *state;
2098 2099
2099 /* Protect against concurrent sillydeletes */ 2100 /* Protect against concurrent sillydeletes */
2100 state = nfs4_do_open(dir, &ctx->path, ctx->mode, open_flags, attr, ctx->cred); 2101 state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred);
2101 if (IS_ERR(state)) 2102 if (IS_ERR(state))
2102 return ERR_CAST(state); 2103 return ERR_CAST(state);
2103 ctx->state = state; 2104 ctx->state = state;
@@ -2109,9 +2110,9 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
2109 if (ctx->state == NULL) 2110 if (ctx->state == NULL)
2110 return; 2111 return;
2111 if (is_sync) 2112 if (is_sync)
2112 nfs4_close_sync(&ctx->path, ctx->state, ctx->mode); 2113 nfs4_close_sync(ctx->state, ctx->mode);
2113 else 2114 else
2114 nfs4_close_state(&ctx->path, ctx->state, ctx->mode); 2115 nfs4_close_state(ctx->state, ctx->mode);
2115} 2116}
2116 2117
2117static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 2118static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
@@ -2634,10 +2635,7 @@ static int
2634nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 2635nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2635 int flags, struct nfs_open_context *ctx) 2636 int flags, struct nfs_open_context *ctx)
2636{ 2637{
2637 struct path my_path = { 2638 struct dentry *de = dentry;
2638 .dentry = dentry,
2639 };
2640 struct path *path = &my_path;
2641 struct nfs4_state *state; 2639 struct nfs4_state *state;
2642 struct rpc_cred *cred = NULL; 2640 struct rpc_cred *cred = NULL;
2643 fmode_t fmode = 0; 2641 fmode_t fmode = 0;
@@ -2645,11 +2643,11 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2645 2643
2646 if (ctx != NULL) { 2644 if (ctx != NULL) {
2647 cred = ctx->cred; 2645 cred = ctx->cred;
2648 path = &ctx->path; 2646 de = ctx->dentry;
2649 fmode = ctx->mode; 2647 fmode = ctx->mode;
2650 } 2648 }
2651 sattr->ia_mode &= ~current_umask(); 2649 sattr->ia_mode &= ~current_umask();
2652 state = nfs4_do_open(dir, path, fmode, flags, sattr, cred); 2650 state = nfs4_do_open(dir, de, fmode, flags, sattr, cred);
2653 d_drop(dentry); 2651 d_drop(dentry);
2654 if (IS_ERR(state)) { 2652 if (IS_ERR(state)) {
2655 status = PTR_ERR(state); 2653 status = PTR_ERR(state);
@@ -2660,7 +2658,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2660 if (ctx != NULL) 2658 if (ctx != NULL)
2661 ctx->state = state; 2659 ctx->state = state;
2662 else 2660 else
2663 nfs4_close_sync(path, state, fmode); 2661 nfs4_close_sync(state, fmode);
2664out: 2662out:
2665 return status; 2663 return status;
2666} 2664}
@@ -4312,7 +4310,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
4312 memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, 4310 memcpy(data->lsp->ls_stateid.data, data->res.stateid.data,
4313 sizeof(data->lsp->ls_stateid.data)); 4311 sizeof(data->lsp->ls_stateid.data));
4314 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; 4312 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
4315 renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp); 4313 renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
4316 } 4314 }
4317out: 4315out:
4318 dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); 4316 dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status);