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 5879b23e0c99..26bece8f3083 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -763,8 +763,8 @@ struct nfs4_opendata { | |||
763 | struct nfs_open_confirmres c_res; | 763 | struct nfs_open_confirmres c_res; |
764 | struct nfs_fattr f_attr; | 764 | struct nfs_fattr f_attr; |
765 | struct nfs_fattr dir_attr; | 765 | struct nfs_fattr dir_attr; |
766 | struct path path; | ||
767 | struct dentry *dir; | 766 | struct dentry *dir; |
767 | struct dentry *dentry; | ||
768 | struct nfs4_state_owner *owner; | 768 | struct nfs4_state_owner *owner; |
769 | struct nfs4_state *state; | 769 | struct nfs4_state *state; |
770 | struct iattr attrs; | 770 | struct iattr attrs; |
@@ -786,12 +786,12 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p) | |||
786 | nfs_fattr_init(&p->dir_attr); | 786 | nfs_fattr_init(&p->dir_attr); |
787 | } | 787 | } |
788 | 788 | ||
789 | static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | 789 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, |
790 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, | 790 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, |
791 | const struct iattr *attrs, | 791 | const struct iattr *attrs, |
792 | gfp_t gfp_mask) | 792 | gfp_t gfp_mask) |
793 | { | 793 | { |
794 | struct dentry *parent = dget_parent(path->dentry); | 794 | struct dentry *parent = dget_parent(dentry); |
795 | struct inode *dir = parent->d_inode; | 795 | struct inode *dir = parent->d_inode; |
796 | struct nfs_server *server = NFS_SERVER(dir); | 796 | struct nfs_server *server = NFS_SERVER(dir); |
797 | struct nfs4_opendata *p; | 797 | struct nfs4_opendata *p; |
@@ -802,8 +802,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | |||
802 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); | 802 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); |
803 | if (p->o_arg.seqid == NULL) | 803 | if (p->o_arg.seqid == NULL) |
804 | goto err_free; | 804 | goto err_free; |
805 | path_get(path); | 805 | nfs_sb_active(dentry->d_sb); |
806 | p->path = *path; | 806 | p->dentry = dget(dentry); |
807 | p->dir = parent; | 807 | p->dir = parent; |
808 | p->owner = sp; | 808 | p->owner = sp; |
809 | atomic_inc(&sp->so_count); | 809 | atomic_inc(&sp->so_count); |
@@ -812,7 +812,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | |||
812 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); | 812 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); |
813 | p->o_arg.clientid = server->nfs_client->cl_clientid; | 813 | p->o_arg.clientid = server->nfs_client->cl_clientid; |
814 | p->o_arg.id = sp->so_owner_id.id; | 814 | p->o_arg.id = sp->so_owner_id.id; |
815 | p->o_arg.name = &p->path.dentry->d_name; | 815 | p->o_arg.name = &dentry->d_name; |
816 | p->o_arg.server = server; | 816 | p->o_arg.server = server; |
817 | p->o_arg.bitmask = server->attr_bitmask; | 817 | p->o_arg.bitmask = server->attr_bitmask; |
818 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; | 818 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; |
@@ -842,13 +842,15 @@ static void nfs4_opendata_free(struct kref *kref) | |||
842 | { | 842 | { |
843 | struct nfs4_opendata *p = container_of(kref, | 843 | struct nfs4_opendata *p = container_of(kref, |
844 | struct nfs4_opendata, kref); | 844 | struct nfs4_opendata, kref); |
845 | struct super_block *sb = p->dentry->d_sb; | ||
845 | 846 | ||
846 | nfs_free_seqid(p->o_arg.seqid); | 847 | nfs_free_seqid(p->o_arg.seqid); |
847 | if (p->state != NULL) | 848 | if (p->state != NULL) |
848 | nfs4_put_open_state(p->state); | 849 | nfs4_put_open_state(p->state); |
849 | nfs4_put_state_owner(p->owner); | 850 | nfs4_put_state_owner(p->owner); |
850 | dput(p->dir); | 851 | dput(p->dir); |
851 | path_put(&p->path); | 852 | dput(p->dentry); |
853 | nfs_sb_deactive(sb); | ||
852 | kfree(p); | 854 | kfree(p); |
853 | } | 855 | } |
854 | 856 | ||
@@ -1130,7 +1132,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context | |||
1130 | { | 1132 | { |
1131 | struct nfs4_opendata *opendata; | 1133 | struct nfs4_opendata *opendata; |
1132 | 1134 | ||
1133 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS); | 1135 | opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, NULL, GFP_NOFS); |
1134 | if (opendata == NULL) | 1136 | if (opendata == NULL) |
1135 | return ERR_PTR(-ENOMEM); | 1137 | return ERR_PTR(-ENOMEM); |
1136 | opendata->state = state; | 1138 | opendata->state = state; |
@@ -1154,7 +1156,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod | |||
1154 | newstate = nfs4_opendata_to_nfs4_state(opendata); | 1156 | newstate = nfs4_opendata_to_nfs4_state(opendata); |
1155 | if (IS_ERR(newstate)) | 1157 | if (IS_ERR(newstate)) |
1156 | return PTR_ERR(newstate); | 1158 | return PTR_ERR(newstate); |
1157 | nfs4_close_state(&opendata->path, newstate, fmode); | 1159 | nfs4_close_state(newstate, fmode); |
1158 | *res = newstate; | 1160 | *res = newstate; |
1159 | return 0; | 1161 | return 0; |
1160 | } | 1162 | } |
@@ -1352,7 +1354,7 @@ static void nfs4_open_confirm_release(void *calldata) | |||
1352 | goto out_free; | 1354 | goto out_free; |
1353 | state = nfs4_opendata_to_nfs4_state(data); | 1355 | state = nfs4_opendata_to_nfs4_state(data); |
1354 | if (!IS_ERR(state)) | 1356 | if (!IS_ERR(state)) |
1355 | nfs4_close_state(&data->path, state, data->o_arg.fmode); | 1357 | nfs4_close_state(state, data->o_arg.fmode); |
1356 | out_free: | 1358 | out_free: |
1357 | nfs4_opendata_put(data); | 1359 | nfs4_opendata_put(data); |
1358 | } | 1360 | } |
@@ -1497,7 +1499,7 @@ static void nfs4_open_release(void *calldata) | |||
1497 | goto out_free; | 1499 | goto out_free; |
1498 | state = nfs4_opendata_to_nfs4_state(data); | 1500 | state = nfs4_opendata_to_nfs4_state(data); |
1499 | if (!IS_ERR(state)) | 1501 | if (!IS_ERR(state)) |
1500 | nfs4_close_state(&data->path, state, data->o_arg.fmode); | 1502 | nfs4_close_state(state, data->o_arg.fmode); |
1501 | out_free: | 1503 | out_free: |
1502 | nfs4_opendata_put(data); | 1504 | nfs4_opendata_put(data); |
1503 | } | 1505 | } |
@@ -1648,7 +1650,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s | |||
1648 | return PTR_ERR(opendata); | 1650 | return PTR_ERR(opendata); |
1649 | ret = nfs4_open_recover(opendata, state); | 1651 | ret = nfs4_open_recover(opendata, state); |
1650 | if (ret == -ESTALE) | 1652 | if (ret == -ESTALE) |
1651 | d_drop(ctx->path.dentry); | 1653 | d_drop(ctx->dentry); |
1652 | nfs4_opendata_put(opendata); | 1654 | nfs4_opendata_put(opendata); |
1653 | return ret; | 1655 | return ret; |
1654 | } | 1656 | } |
@@ -1706,7 +1708,7 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct | |||
1706 | /* | 1708 | /* |
1707 | * Returns a referenced nfs4_state | 1709 | * Returns a referenced nfs4_state |
1708 | */ | 1710 | */ |
1709 | 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) | 1711 | 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) |
1710 | { | 1712 | { |
1711 | struct nfs4_state_owner *sp; | 1713 | struct nfs4_state_owner *sp; |
1712 | struct nfs4_state *state = NULL; | 1714 | struct nfs4_state *state = NULL; |
@@ -1723,15 +1725,15 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1723 | status = nfs4_recover_expired_lease(server); | 1725 | status = nfs4_recover_expired_lease(server); |
1724 | if (status != 0) | 1726 | if (status != 0) |
1725 | goto err_put_state_owner; | 1727 | goto err_put_state_owner; |
1726 | if (path->dentry->d_inode != NULL) | 1728 | if (dentry->d_inode != NULL) |
1727 | nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); | 1729 | nfs4_return_incompatible_delegation(dentry->d_inode, fmode); |
1728 | status = -ENOMEM; | 1730 | status = -ENOMEM; |
1729 | opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL); | 1731 | opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, GFP_KERNEL); |
1730 | if (opendata == NULL) | 1732 | if (opendata == NULL) |
1731 | goto err_put_state_owner; | 1733 | goto err_put_state_owner; |
1732 | 1734 | ||
1733 | if (path->dentry->d_inode != NULL) | 1735 | if (dentry->d_inode != NULL) |
1734 | opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp); | 1736 | opendata->state = nfs4_get_open_state(dentry->d_inode, sp); |
1735 | 1737 | ||
1736 | status = _nfs4_proc_open(opendata); | 1738 | status = _nfs4_proc_open(opendata); |
1737 | if (status != 0) | 1739 | if (status != 0) |
@@ -1769,14 +1771,14 @@ out_err: | |||
1769 | } | 1771 | } |
1770 | 1772 | ||
1771 | 1773 | ||
1772 | 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) | 1774 | 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) |
1773 | { | 1775 | { |
1774 | struct nfs4_exception exception = { }; | 1776 | struct nfs4_exception exception = { }; |
1775 | struct nfs4_state *res; | 1777 | struct nfs4_state *res; |
1776 | int status; | 1778 | int status; |
1777 | 1779 | ||
1778 | do { | 1780 | do { |
1779 | status = _nfs4_do_open(dir, path, fmode, flags, sattr, cred, &res); | 1781 | status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res); |
1780 | if (status == 0) | 1782 | if (status == 0) |
1781 | break; | 1783 | break; |
1782 | /* NOTE: BAD_SEQID means the server and client disagree about the | 1784 | /* NOTE: BAD_SEQID means the server and client disagree about the |
@@ -1873,7 +1875,6 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | |||
1873 | } | 1875 | } |
1874 | 1876 | ||
1875 | struct nfs4_closedata { | 1877 | struct nfs4_closedata { |
1876 | struct path path; | ||
1877 | struct inode *inode; | 1878 | struct inode *inode; |
1878 | struct nfs4_state *state; | 1879 | struct nfs4_state *state; |
1879 | struct nfs_closeargs arg; | 1880 | struct nfs_closeargs arg; |
@@ -1888,13 +1889,14 @@ static void nfs4_free_closedata(void *data) | |||
1888 | { | 1889 | { |
1889 | struct nfs4_closedata *calldata = data; | 1890 | struct nfs4_closedata *calldata = data; |
1890 | struct nfs4_state_owner *sp = calldata->state->owner; | 1891 | struct nfs4_state_owner *sp = calldata->state->owner; |
1892 | struct super_block *sb = calldata->state->inode->i_sb; | ||
1891 | 1893 | ||
1892 | if (calldata->roc) | 1894 | if (calldata->roc) |
1893 | pnfs_roc_release(calldata->state->inode); | 1895 | pnfs_roc_release(calldata->state->inode); |
1894 | nfs4_put_open_state(calldata->state); | 1896 | nfs4_put_open_state(calldata->state); |
1895 | nfs_free_seqid(calldata->arg.seqid); | 1897 | nfs_free_seqid(calldata->arg.seqid); |
1896 | nfs4_put_state_owner(sp); | 1898 | nfs4_put_state_owner(sp); |
1897 | path_put(&calldata->path); | 1899 | nfs_sb_deactive(sb); |
1898 | kfree(calldata); | 1900 | kfree(calldata); |
1899 | } | 1901 | } |
1900 | 1902 | ||
@@ -2014,7 +2016,7 @@ static const struct rpc_call_ops nfs4_close_ops = { | |||
2014 | * | 2016 | * |
2015 | * NOTE: Caller must be holding the sp->so_owner semaphore! | 2017 | * NOTE: Caller must be holding the sp->so_owner semaphore! |
2016 | */ | 2018 | */ |
2017 | int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc) | 2019 | int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc) |
2018 | { | 2020 | { |
2019 | struct nfs_server *server = NFS_SERVER(state->inode); | 2021 | struct nfs_server *server = NFS_SERVER(state->inode); |
2020 | struct nfs4_closedata *calldata; | 2022 | struct nfs4_closedata *calldata; |
@@ -2050,8 +2052,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i | |||
2050 | calldata->res.seqid = calldata->arg.seqid; | 2052 | calldata->res.seqid = calldata->arg.seqid; |
2051 | calldata->res.server = server; | 2053 | calldata->res.server = server; |
2052 | calldata->roc = roc; | 2054 | calldata->roc = roc; |
2053 | path_get(path); | 2055 | nfs_sb_active(calldata->inode->i_sb); |
2054 | calldata->path = *path; | ||
2055 | 2056 | ||
2056 | msg.rpc_argp = &calldata->arg; | 2057 | msg.rpc_argp = &calldata->arg; |
2057 | msg.rpc_resp = &calldata->res; | 2058 | msg.rpc_resp = &calldata->res; |
@@ -2080,7 +2081,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags | |||
2080 | struct nfs4_state *state; | 2081 | struct nfs4_state *state; |
2081 | 2082 | ||
2082 | /* Protect against concurrent sillydeletes */ | 2083 | /* Protect against concurrent sillydeletes */ |
2083 | state = nfs4_do_open(dir, &ctx->path, ctx->mode, open_flags, attr, ctx->cred); | 2084 | state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred); |
2084 | if (IS_ERR(state)) | 2085 | if (IS_ERR(state)) |
2085 | return ERR_CAST(state); | 2086 | return ERR_CAST(state); |
2086 | ctx->state = state; | 2087 | ctx->state = state; |
@@ -2092,9 +2093,9 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) | |||
2092 | if (ctx->state == NULL) | 2093 | if (ctx->state == NULL) |
2093 | return; | 2094 | return; |
2094 | if (is_sync) | 2095 | if (is_sync) |
2095 | nfs4_close_sync(&ctx->path, ctx->state, ctx->mode); | 2096 | nfs4_close_sync(ctx->state, ctx->mode); |
2096 | else | 2097 | else |
2097 | nfs4_close_state(&ctx->path, ctx->state, ctx->mode); | 2098 | nfs4_close_state(ctx->state, ctx->mode); |
2098 | } | 2099 | } |
2099 | 2100 | ||
2100 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) | 2101 | static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) |
@@ -2616,10 +2617,7 @@ static int | |||
2616 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 2617 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
2617 | int flags, struct nfs_open_context *ctx) | 2618 | int flags, struct nfs_open_context *ctx) |
2618 | { | 2619 | { |
2619 | struct path my_path = { | 2620 | struct dentry *de = dentry; |
2620 | .dentry = dentry, | ||
2621 | }; | ||
2622 | struct path *path = &my_path; | ||
2623 | struct nfs4_state *state; | 2621 | struct nfs4_state *state; |
2624 | struct rpc_cred *cred = NULL; | 2622 | struct rpc_cred *cred = NULL; |
2625 | fmode_t fmode = 0; | 2623 | fmode_t fmode = 0; |
@@ -2627,11 +2625,11 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2627 | 2625 | ||
2628 | if (ctx != NULL) { | 2626 | if (ctx != NULL) { |
2629 | cred = ctx->cred; | 2627 | cred = ctx->cred; |
2630 | path = &ctx->path; | 2628 | de = ctx->dentry; |
2631 | fmode = ctx->mode; | 2629 | fmode = ctx->mode; |
2632 | } | 2630 | } |
2633 | sattr->ia_mode &= ~current_umask(); | 2631 | sattr->ia_mode &= ~current_umask(); |
2634 | state = nfs4_do_open(dir, path, fmode, flags, sattr, cred); | 2632 | state = nfs4_do_open(dir, de, fmode, flags, sattr, cred); |
2635 | d_drop(dentry); | 2633 | d_drop(dentry); |
2636 | if (IS_ERR(state)) { | 2634 | if (IS_ERR(state)) { |
2637 | status = PTR_ERR(state); | 2635 | status = PTR_ERR(state); |
@@ -2642,7 +2640,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2642 | if (ctx != NULL) | 2640 | if (ctx != NULL) |
2643 | ctx->state = state; | 2641 | ctx->state = state; |
2644 | else | 2642 | else |
2645 | nfs4_close_sync(path, state, fmode); | 2643 | nfs4_close_sync(state, fmode); |
2646 | out: | 2644 | out: |
2647 | return status; | 2645 | return status; |
2648 | } | 2646 | } |
@@ -4294,7 +4292,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) | |||
4294 | memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, | 4292 | memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, |
4295 | sizeof(data->lsp->ls_stateid.data)); | 4293 | sizeof(data->lsp->ls_stateid.data)); |
4296 | data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; | 4294 | data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; |
4297 | renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp); | 4295 | renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp); |
4298 | } | 4296 | } |
4299 | out: | 4297 | out: |
4300 | dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); | 4298 | dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); |