|
@@ -70,6 +70,9 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
|
|
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
|
|
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
|
|
static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
|
|
|
+static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
|
|
|
+ struct nfs_fattr *fattr, struct iattr *sattr,
|
|
|
|
+ struct nfs4_state *state);
|
|
|
|
|
|
/* Prevent leaks of NFSv4 errors into userland */
|
|
/* Prevent leaks of NFSv4 errors into userland */
|
|
static int nfs4_map_errors(int err)
|
|
static int nfs4_map_errors(int err)
|
|
@@ -714,17 +717,18 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
|
|
|
|
|
|
static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
|
|
static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
|
|
struct nfs4_state_owner *sp, fmode_t fmode, int flags,
|
|
struct nfs4_state_owner *sp, fmode_t fmode, int flags,
|
|
- const struct iattr *attrs)
|
|
|
|
|
|
+ const struct iattr *attrs,
|
|
|
|
+ gfp_t gfp_mask)
|
|
{
|
|
{
|
|
struct dentry *parent = dget_parent(path->dentry);
|
|
struct dentry *parent = dget_parent(path->dentry);
|
|
struct inode *dir = parent->d_inode;
|
|
struct inode *dir = parent->d_inode;
|
|
struct nfs_server *server = NFS_SERVER(dir);
|
|
struct nfs_server *server = NFS_SERVER(dir);
|
|
struct nfs4_opendata *p;
|
|
struct nfs4_opendata *p;
|
|
|
|
|
|
- p = kzalloc(sizeof(*p), GFP_KERNEL);
|
|
|
|
|
|
+ p = kzalloc(sizeof(*p), gfp_mask);
|
|
if (p == NULL)
|
|
if (p == NULL)
|
|
goto err;
|
|
goto err;
|
|
- p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
|
|
|
|
|
|
+ p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
|
|
if (p->o_arg.seqid == NULL)
|
|
if (p->o_arg.seqid == NULL)
|
|
goto err_free;
|
|
goto err_free;
|
|
path_get(path);
|
|
path_get(path);
|
|
@@ -1060,7 +1064,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
|
|
{
|
|
{
|
|
struct nfs4_opendata *opendata;
|
|
struct nfs4_opendata *opendata;
|
|
|
|
|
|
- opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL);
|
|
|
|
|
|
+ opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS);
|
|
if (opendata == NULL)
|
|
if (opendata == NULL)
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
opendata->state = state;
|
|
opendata->state = state;
|
|
@@ -1648,7 +1652,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
|
|
if (path->dentry->d_inode != NULL)
|
|
if (path->dentry->d_inode != NULL)
|
|
nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode);
|
|
nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode);
|
|
status = -ENOMEM;
|
|
status = -ENOMEM;
|
|
- opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr);
|
|
|
|
|
|
+ opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL);
|
|
if (opendata == NULL)
|
|
if (opendata == NULL)
|
|
goto err_put_state_owner;
|
|
goto err_put_state_owner;
|
|
|
|
|
|
@@ -1659,15 +1663,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
|
|
if (status != 0)
|
|
if (status != 0)
|
|
goto err_opendata_put;
|
|
goto err_opendata_put;
|
|
|
|
|
|
- if (opendata->o_arg.open_flags & O_EXCL)
|
|
|
|
- nfs4_exclusive_attrset(opendata, sattr);
|
|
|
|
-
|
|
|
|
state = nfs4_opendata_to_nfs4_state(opendata);
|
|
state = nfs4_opendata_to_nfs4_state(opendata);
|
|
status = PTR_ERR(state);
|
|
status = PTR_ERR(state);
|
|
if (IS_ERR(state))
|
|
if (IS_ERR(state))
|
|
goto err_opendata_put;
|
|
goto err_opendata_put;
|
|
if (server->caps & NFS_CAP_POSIX_LOCK)
|
|
if (server->caps & NFS_CAP_POSIX_LOCK)
|
|
set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
|
|
set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
|
|
|
|
+
|
|
|
|
+ if (opendata->o_arg.open_flags & O_EXCL) {
|
|
|
|
+ nfs4_exclusive_attrset(opendata, sattr);
|
|
|
|
+
|
|
|
|
+ nfs_fattr_init(opendata->o_res.f_attr);
|
|
|
|
+ status = nfs4_do_setattr(state->inode, cred,
|
|
|
|
+ opendata->o_res.f_attr, sattr,
|
|
|
|
+ state);
|
|
|
|
+ if (status == 0)
|
|
|
|
+ nfs_setattr_update_inode(state->inode, sattr);
|
|
|
|
+ nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
|
|
|
|
+ }
|
|
nfs4_opendata_put(opendata);
|
|
nfs4_opendata_put(opendata);
|
|
nfs4_put_state_owner(sp);
|
|
nfs4_put_state_owner(sp);
|
|
*res = state;
|
|
*res = state;
|
|
@@ -1914,7 +1927,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
|
|
*
|
|
*
|
|
* NOTE: Caller must be holding the sp->so_owner semaphore!
|
|
* NOTE: Caller must be holding the sp->so_owner semaphore!
|
|
*/
|
|
*/
|
|
-int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
|
|
|
|
|
|
+int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait)
|
|
{
|
|
{
|
|
struct nfs_server *server = NFS_SERVER(state->inode);
|
|
struct nfs_server *server = NFS_SERVER(state->inode);
|
|
struct nfs4_closedata *calldata;
|
|
struct nfs4_closedata *calldata;
|
|
@@ -1933,7 +1946,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
|
|
};
|
|
};
|
|
int status = -ENOMEM;
|
|
int status = -ENOMEM;
|
|
|
|
|
|
- calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
|
|
|
|
|
|
+ calldata = kzalloc(sizeof(*calldata), gfp_mask);
|
|
if (calldata == NULL)
|
|
if (calldata == NULL)
|
|
goto out;
|
|
goto out;
|
|
calldata->inode = state->inode;
|
|
calldata->inode = state->inode;
|
|
@@ -1941,7 +1954,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
|
|
calldata->arg.fh = NFS_FH(state->inode);
|
|
calldata->arg.fh = NFS_FH(state->inode);
|
|
calldata->arg.stateid = &state->open_stateid;
|
|
calldata->arg.stateid = &state->open_stateid;
|
|
/* Serialization for the sequence id */
|
|
/* Serialization for the sequence id */
|
|
- calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
|
|
|
|
|
|
+ calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid, gfp_mask);
|
|
if (calldata->arg.seqid == NULL)
|
|
if (calldata->arg.seqid == NULL)
|
|
goto out_free_calldata;
|
|
goto out_free_calldata;
|
|
calldata->arg.fmode = 0;
|
|
calldata->arg.fmode = 0;
|
|
@@ -2404,14 +2417,12 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh
|
|
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
|
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
|
{
|
|
{
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
- struct nfs_fattr fattr;
|
|
|
|
struct nfs4_accessargs args = {
|
|
struct nfs4_accessargs args = {
|
|
.fh = NFS_FH(inode),
|
|
.fh = NFS_FH(inode),
|
|
.bitmask = server->attr_bitmask,
|
|
.bitmask = server->attr_bitmask,
|
|
};
|
|
};
|
|
struct nfs4_accessres res = {
|
|
struct nfs4_accessres res = {
|
|
.server = server,
|
|
.server = server,
|
|
- .fattr = &fattr,
|
|
|
|
};
|
|
};
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
|
|
@@ -2438,7 +2449,11 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
|
|
if (mode & MAY_EXEC)
|
|
if (mode & MAY_EXEC)
|
|
args.access |= NFS4_ACCESS_EXECUTE;
|
|
args.access |= NFS4_ACCESS_EXECUTE;
|
|
}
|
|
}
|
|
- nfs_fattr_init(&fattr);
|
|
|
|
|
|
+
|
|
|
|
+ res.fattr = nfs_alloc_fattr();
|
|
|
|
+ if (res.fattr == NULL)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
status = nfs4_call_sync(server, &msg, &args, &res, 0);
|
|
status = nfs4_call_sync(server, &msg, &args, &res, 0);
|
|
if (!status) {
|
|
if (!status) {
|
|
entry->mask = 0;
|
|
entry->mask = 0;
|
|
@@ -2448,8 +2463,9 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
|
|
entry->mask |= MAY_WRITE;
|
|
entry->mask |= MAY_WRITE;
|
|
if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
|
|
if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
|
|
entry->mask |= MAY_EXEC;
|
|
entry->mask |= MAY_EXEC;
|
|
- nfs_refresh_inode(inode, &fattr);
|
|
|
|
|
|
+ nfs_refresh_inode(inode, res.fattr);
|
|
}
|
|
}
|
|
|
|
+ nfs_free_fattr(res.fattr);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2562,13 +2578,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
|
}
|
|
}
|
|
d_add(dentry, igrab(state->inode));
|
|
d_add(dentry, igrab(state->inode));
|
|
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
|
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
|
- if (flags & O_EXCL) {
|
|
|
|
- struct nfs_fattr fattr;
|
|
|
|
- status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state);
|
|
|
|
- if (status == 0)
|
|
|
|
- nfs_setattr_update_inode(state->inode, sattr);
|
|
|
|
- nfs_post_op_update_inode(state->inode, &fattr);
|
|
|
|
- }
|
|
|
|
if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
|
|
if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
|
|
status = nfs4_intent_set_file(nd, &path, state, fmode);
|
|
status = nfs4_intent_set_file(nd, &path, state, fmode);
|
|
else
|
|
else
|
|
@@ -2596,14 +2605,19 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
|
|
.rpc_argp = &args,
|
|
.rpc_argp = &args,
|
|
.rpc_resp = &res,
|
|
.rpc_resp = &res,
|
|
};
|
|
};
|
|
- int status;
|
|
|
|
|
|
+ int status = -ENOMEM;
|
|
|
|
+
|
|
|
|
+ res.dir_attr = nfs_alloc_fattr();
|
|
|
|
+ if (res.dir_attr == NULL)
|
|
|
|
+ goto out;
|
|
|
|
|
|
- nfs_fattr_init(&res.dir_attr);
|
|
|
|
status = nfs4_call_sync(server, &msg, &args, &res, 1);
|
|
status = nfs4_call_sync(server, &msg, &args, &res, 1);
|
|
if (status == 0) {
|
|
if (status == 0) {
|
|
update_changeattr(dir, &res.cinfo);
|
|
update_changeattr(dir, &res.cinfo);
|
|
- nfs_post_op_update_inode(dir, &res.dir_attr);
|
|
|
|
|
|
+ nfs_post_op_update_inode(dir, res.dir_attr);
|
|
}
|
|
}
|
|
|
|
+ nfs_free_fattr(res.dir_attr);
|
|
|
|
+out:
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2638,7 +2652,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
|
|
if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
|
|
if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
|
|
return 0;
|
|
return 0;
|
|
update_changeattr(dir, &res->cinfo);
|
|
update_changeattr(dir, &res->cinfo);
|
|
- nfs_post_op_update_inode(dir, &res->dir_attr);
|
|
|
|
|
|
+ nfs_post_op_update_inode(dir, res->dir_attr);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2653,29 +2667,31 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
|
|
.new_name = new_name,
|
|
.new_name = new_name,
|
|
.bitmask = server->attr_bitmask,
|
|
.bitmask = server->attr_bitmask,
|
|
};
|
|
};
|
|
- struct nfs_fattr old_fattr, new_fattr;
|
|
|
|
struct nfs4_rename_res res = {
|
|
struct nfs4_rename_res res = {
|
|
.server = server,
|
|
.server = server,
|
|
- .old_fattr = &old_fattr,
|
|
|
|
- .new_fattr = &new_fattr,
|
|
|
|
};
|
|
};
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
|
|
.rpc_argp = &arg,
|
|
.rpc_argp = &arg,
|
|
.rpc_resp = &res,
|
|
.rpc_resp = &res,
|
|
};
|
|
};
|
|
- int status;
|
|
|
|
|
|
+ int status = -ENOMEM;
|
|
|
|
|
|
- nfs_fattr_init(res.old_fattr);
|
|
|
|
- nfs_fattr_init(res.new_fattr);
|
|
|
|
- status = nfs4_call_sync(server, &msg, &arg, &res, 1);
|
|
|
|
|
|
+ res.old_fattr = nfs_alloc_fattr();
|
|
|
|
+ res.new_fattr = nfs_alloc_fattr();
|
|
|
|
+ if (res.old_fattr == NULL || res.new_fattr == NULL)
|
|
|
|
+ goto out;
|
|
|
|
|
|
|
|
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
|
|
if (!status) {
|
|
if (!status) {
|
|
update_changeattr(old_dir, &res.old_cinfo);
|
|
update_changeattr(old_dir, &res.old_cinfo);
|
|
nfs_post_op_update_inode(old_dir, res.old_fattr);
|
|
nfs_post_op_update_inode(old_dir, res.old_fattr);
|
|
update_changeattr(new_dir, &res.new_cinfo);
|
|
update_changeattr(new_dir, &res.new_cinfo);
|
|
nfs_post_op_update_inode(new_dir, res.new_fattr);
|
|
nfs_post_op_update_inode(new_dir, res.new_fattr);
|
|
}
|
|
}
|
|
|
|
+out:
|
|
|
|
+ nfs_free_fattr(res.new_fattr);
|
|
|
|
+ nfs_free_fattr(res.old_fattr);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2702,28 +2718,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
|
|
.name = name,
|
|
.name = name,
|
|
.bitmask = server->attr_bitmask,
|
|
.bitmask = server->attr_bitmask,
|
|
};
|
|
};
|
|
- struct nfs_fattr fattr, dir_attr;
|
|
|
|
struct nfs4_link_res res = {
|
|
struct nfs4_link_res res = {
|
|
.server = server,
|
|
.server = server,
|
|
- .fattr = &fattr,
|
|
|
|
- .dir_attr = &dir_attr,
|
|
|
|
};
|
|
};
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
|
|
.rpc_argp = &arg,
|
|
.rpc_argp = &arg,
|
|
.rpc_resp = &res,
|
|
.rpc_resp = &res,
|
|
};
|
|
};
|
|
- int status;
|
|
|
|
|
|
+ int status = -ENOMEM;
|
|
|
|
+
|
|
|
|
+ res.fattr = nfs_alloc_fattr();
|
|
|
|
+ res.dir_attr = nfs_alloc_fattr();
|
|
|
|
+ if (res.fattr == NULL || res.dir_attr == NULL)
|
|
|
|
+ goto out;
|
|
|
|
|
|
- nfs_fattr_init(res.fattr);
|
|
|
|
- nfs_fattr_init(res.dir_attr);
|
|
|
|
status = nfs4_call_sync(server, &msg, &arg, &res, 1);
|
|
status = nfs4_call_sync(server, &msg, &arg, &res, 1);
|
|
if (!status) {
|
|
if (!status) {
|
|
update_changeattr(dir, &res.cinfo);
|
|
update_changeattr(dir, &res.cinfo);
|
|
nfs_post_op_update_inode(dir, res.dir_attr);
|
|
nfs_post_op_update_inode(dir, res.dir_attr);
|
|
nfs_post_op_update_inode(inode, res.fattr);
|
|
nfs_post_op_update_inode(inode, res.fattr);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+out:
|
|
|
|
+ nfs_free_fattr(res.dir_attr);
|
|
|
|
+ nfs_free_fattr(res.fattr);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3146,23 +3164,31 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
|
|
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
|
|
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct nfs4_renewdata {
|
|
|
|
+ struct nfs_client *client;
|
|
|
|
+ unsigned long timestamp;
|
|
|
|
+};
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
|
|
* nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
|
|
* standalone procedure for queueing an asynchronous RENEW.
|
|
* standalone procedure for queueing an asynchronous RENEW.
|
|
*/
|
|
*/
|
|
-static void nfs4_renew_release(void *data)
|
|
|
|
|
|
+static void nfs4_renew_release(void *calldata)
|
|
{
|
|
{
|
|
- struct nfs_client *clp = data;
|
|
|
|
|
|
+ struct nfs4_renewdata *data = calldata;
|
|
|
|
+ struct nfs_client *clp = data->client;
|
|
|
|
|
|
if (atomic_read(&clp->cl_count) > 1)
|
|
if (atomic_read(&clp->cl_count) > 1)
|
|
nfs4_schedule_state_renewal(clp);
|
|
nfs4_schedule_state_renewal(clp);
|
|
nfs_put_client(clp);
|
|
nfs_put_client(clp);
|
|
|
|
+ kfree(data);
|
|
}
|
|
}
|
|
|
|
|
|
-static void nfs4_renew_done(struct rpc_task *task, void *data)
|
|
|
|
|
|
+static void nfs4_renew_done(struct rpc_task *task, void *calldata)
|
|
{
|
|
{
|
|
- struct nfs_client *clp = data;
|
|
|
|
- unsigned long timestamp = task->tk_start;
|
|
|
|
|
|
+ struct nfs4_renewdata *data = calldata;
|
|
|
|
+ struct nfs_client *clp = data->client;
|
|
|
|
+ unsigned long timestamp = data->timestamp;
|
|
|
|
|
|
if (task->tk_status < 0) {
|
|
if (task->tk_status < 0) {
|
|
/* Unless we're shutting down, schedule state recovery! */
|
|
/* Unless we're shutting down, schedule state recovery! */
|
|
@@ -3188,11 +3214,17 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
|
.rpc_argp = clp,
|
|
.rpc_argp = clp,
|
|
.rpc_cred = cred,
|
|
.rpc_cred = cred,
|
|
};
|
|
};
|
|
|
|
+ struct nfs4_renewdata *data;
|
|
|
|
|
|
if (!atomic_inc_not_zero(&clp->cl_count))
|
|
if (!atomic_inc_not_zero(&clp->cl_count))
|
|
return -EIO;
|
|
return -EIO;
|
|
|
|
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
|
|
|
|
+ if (data == NULL)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ data->client = clp;
|
|
|
|
+ data->timestamp = jiffies;
|
|
return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
|
|
return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
|
|
- &nfs4_renew_ops, clp);
|
|
|
|
|
|
+ &nfs4_renew_ops, data);
|
|
}
|
|
}
|
|
|
|
|
|
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
|
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
|
@@ -3494,7 +3526,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
|
|
return _nfs4_async_handle_error(task, server, server->nfs_client, state);
|
|
return _nfs4_async_handle_error(task, server, server->nfs_client, state);
|
|
}
|
|
}
|
|
|
|
|
|
-int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
|
|
|
|
|
|
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
|
|
|
+ unsigned short port, struct rpc_cred *cred,
|
|
|
|
+ struct nfs4_setclientid_res *res)
|
|
{
|
|
{
|
|
nfs4_verifier sc_verifier;
|
|
nfs4_verifier sc_verifier;
|
|
struct nfs4_setclientid setclientid = {
|
|
struct nfs4_setclientid setclientid = {
|
|
@@ -3504,7 +3538,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
|
|
.rpc_argp = &setclientid,
|
|
.rpc_argp = &setclientid,
|
|
- .rpc_resp = clp,
|
|
|
|
|
|
+ .rpc_resp = res,
|
|
.rpc_cred = cred,
|
|
.rpc_cred = cred,
|
|
};
|
|
};
|
|
__be32 *p;
|
|
__be32 *p;
|
|
@@ -3547,12 +3581,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
-static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
|
|
|
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
|
|
|
+ struct nfs4_setclientid_res *arg,
|
|
|
|
+ struct rpc_cred *cred)
|
|
{
|
|
{
|
|
struct nfs_fsinfo fsinfo;
|
|
struct nfs_fsinfo fsinfo;
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
|
|
- .rpc_argp = clp,
|
|
|
|
|
|
+ .rpc_argp = arg,
|
|
.rpc_resp = &fsinfo,
|
|
.rpc_resp = &fsinfo,
|
|
.rpc_cred = cred,
|
|
.rpc_cred = cred,
|
|
};
|
|
};
|
|
@@ -3570,12 +3606,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
-int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
|
|
|
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
|
|
|
+ struct nfs4_setclientid_res *arg,
|
|
|
|
+ struct rpc_cred *cred)
|
|
{
|
|
{
|
|
long timeout = 0;
|
|
long timeout = 0;
|
|
int err;
|
|
int err;
|
|
do {
|
|
do {
|
|
- err = _nfs4_proc_setclientid_confirm(clp, cred);
|
|
|
|
|
|
+ err = _nfs4_proc_setclientid_confirm(clp, arg, cred);
|
|
switch (err) {
|
|
switch (err) {
|
|
case 0:
|
|
case 0:
|
|
return err;
|
|
return err;
|
|
@@ -3667,7 +3705,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
|
|
};
|
|
};
|
|
int status = 0;
|
|
int status = 0;
|
|
|
|
|
|
- data = kzalloc(sizeof(*data), GFP_KERNEL);
|
|
|
|
|
|
+ data = kzalloc(sizeof(*data), GFP_NOFS);
|
|
if (data == NULL)
|
|
if (data == NULL)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
data->args.fhandle = &data->fh;
|
|
data->args.fhandle = &data->fh;
|
|
@@ -3823,7 +3861,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
|
|
struct nfs4_unlockdata *p;
|
|
struct nfs4_unlockdata *p;
|
|
struct inode *inode = lsp->ls_state->inode;
|
|
struct inode *inode = lsp->ls_state->inode;
|
|
|
|
|
|
- p = kzalloc(sizeof(*p), GFP_KERNEL);
|
|
|
|
|
|
+ p = kzalloc(sizeof(*p), GFP_NOFS);
|
|
if (p == NULL)
|
|
if (p == NULL)
|
|
return NULL;
|
|
return NULL;
|
|
p->arg.fh = NFS_FH(inode);
|
|
p->arg.fh = NFS_FH(inode);
|
|
@@ -3961,7 +3999,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
|
|
if (test_bit(NFS_DELEGATED_STATE, &state->flags))
|
|
if (test_bit(NFS_DELEGATED_STATE, &state->flags))
|
|
goto out;
|
|
goto out;
|
|
lsp = request->fl_u.nfs4_fl.owner;
|
|
lsp = request->fl_u.nfs4_fl.owner;
|
|
- seqid = nfs_alloc_seqid(&lsp->ls_seqid);
|
|
|
|
|
|
+ seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL);
|
|
status = -ENOMEM;
|
|
status = -ENOMEM;
|
|
if (seqid == NULL)
|
|
if (seqid == NULL)
|
|
goto out;
|
|
goto out;
|
|
@@ -3989,22 +4027,23 @@ struct nfs4_lockdata {
|
|
};
|
|
};
|
|
|
|
|
|
static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
|
|
static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
|
|
- struct nfs_open_context *ctx, struct nfs4_lock_state *lsp)
|
|
|
|
|
|
+ struct nfs_open_context *ctx, struct nfs4_lock_state *lsp,
|
|
|
|
+ gfp_t gfp_mask)
|
|
{
|
|
{
|
|
struct nfs4_lockdata *p;
|
|
struct nfs4_lockdata *p;
|
|
struct inode *inode = lsp->ls_state->inode;
|
|
struct inode *inode = lsp->ls_state->inode;
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
|
|
|
|
- p = kzalloc(sizeof(*p), GFP_KERNEL);
|
|
|
|
|
|
+ p = kzalloc(sizeof(*p), gfp_mask);
|
|
if (p == NULL)
|
|
if (p == NULL)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
p->arg.fh = NFS_FH(inode);
|
|
p->arg.fh = NFS_FH(inode);
|
|
p->arg.fl = &p->fl;
|
|
p->arg.fl = &p->fl;
|
|
- p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid);
|
|
|
|
|
|
+ p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask);
|
|
if (p->arg.open_seqid == NULL)
|
|
if (p->arg.open_seqid == NULL)
|
|
goto out_free;
|
|
goto out_free;
|
|
- p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
|
|
|
|
|
|
+ p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid, gfp_mask);
|
|
if (p->arg.lock_seqid == NULL)
|
|
if (p->arg.lock_seqid == NULL)
|
|
goto out_free_seqid;
|
|
goto out_free_seqid;
|
|
p->arg.lock_stateid = &lsp->ls_stateid;
|
|
p->arg.lock_stateid = &lsp->ls_stateid;
|
|
@@ -4158,7 +4197,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
|
|
|
|
|
|
dprintk("%s: begin!\n", __func__);
|
|
dprintk("%s: begin!\n", __func__);
|
|
data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
|
|
data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
|
|
- fl->fl_u.nfs4_fl.owner);
|
|
|
|
|
|
+ fl->fl_u.nfs4_fl.owner,
|
|
|
|
+ recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS);
|
|
if (data == NULL)
|
|
if (data == NULL)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
if (IS_SETLKW(cmd))
|
|
if (IS_SETLKW(cmd))
|
|
@@ -4647,7 +4687,7 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
|
|
if (max_reqs != tbl->max_slots) {
|
|
if (max_reqs != tbl->max_slots) {
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
|
|
new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
|
|
- GFP_KERNEL);
|
|
|
|
|
|
+ GFP_NOFS);
|
|
if (!new)
|
|
if (!new)
|
|
goto out;
|
|
goto out;
|
|
ret = 0;
|
|
ret = 0;
|
|
@@ -4712,7 +4752,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
|
|
|
|
|
|
dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
|
|
dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
|
|
|
|
|
|
- slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
|
|
|
|
|
|
+ slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
|
|
if (!slot)
|
|
if (!slot)
|
|
goto out;
|
|
goto out;
|
|
ret = 0;
|
|
ret = 0;
|
|
@@ -4761,7 +4801,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
|
|
struct nfs4_session *session;
|
|
struct nfs4_session *session;
|
|
struct nfs4_slot_table *tbl;
|
|
struct nfs4_slot_table *tbl;
|
|
|
|
|
|
- session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL);
|
|
|
|
|
|
+ session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
|
|
if (!session)
|
|
if (!session)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
@@ -5105,8 +5145,8 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
|
|
|
|
|
|
if (!atomic_inc_not_zero(&clp->cl_count))
|
|
if (!atomic_inc_not_zero(&clp->cl_count))
|
|
return -EIO;
|
|
return -EIO;
|
|
- args = kzalloc(sizeof(*args), GFP_KERNEL);
|
|
|
|
- res = kzalloc(sizeof(*res), GFP_KERNEL);
|
|
|
|
|
|
+ args = kzalloc(sizeof(*args), GFP_NOFS);
|
|
|
|
+ res = kzalloc(sizeof(*res), GFP_NOFS);
|
|
if (!args || !res) {
|
|
if (!args || !res) {
|
|
kfree(args);
|
|
kfree(args);
|
|
kfree(res);
|
|
kfree(res);
|
|
@@ -5207,7 +5247,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
|
|
int status = -ENOMEM;
|
|
int status = -ENOMEM;
|
|
|
|
|
|
dprintk("--> %s\n", __func__);
|
|
dprintk("--> %s\n", __func__);
|
|
- calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
|
|
|
|
|
|
+ calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
|
|
if (calldata == NULL)
|
|
if (calldata == NULL)
|
|
goto out;
|
|
goto out;
|
|
calldata->clp = clp;
|
|
calldata->clp = clp;
|