diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 70 |
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 | ||
792 | static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | 792 | static 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); |
1359 | out_free: | 1361 | out_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); |
1504 | out_free: | 1506 | out_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 | */ |
1726 | static 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) | 1728 | static 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 | ||
1789 | static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) | 1791 | static 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 | ||
1892 | struct nfs4_closedata { | 1894 | struct 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 | */ |
2034 | int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc) | 2036 | int 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 | ||
2117 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) | 2118 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) |
@@ -2634,10 +2635,7 @@ static int | |||
2634 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 2635 | nfs4_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); |
2664 | out: | 2662 | out: |
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 | } |
4317 | out: | 4315 | out: |
4318 | dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); | 4316 | dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); |