diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 177 |
1 files changed, 110 insertions, 67 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 638067007c65..70015dd60a98 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) |
@@ -714,17 +717,18 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p) | |||
714 | 717 | ||
715 | static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | 718 | static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, |
716 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, | 719 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, |
717 | const struct iattr *attrs) | 720 | const struct iattr *attrs, |
721 | gfp_t gfp_mask) | ||
718 | { | 722 | { |
719 | struct dentry *parent = dget_parent(path->dentry); | 723 | struct dentry *parent = dget_parent(path->dentry); |
720 | struct inode *dir = parent->d_inode; | 724 | struct inode *dir = parent->d_inode; |
721 | struct nfs_server *server = NFS_SERVER(dir); | 725 | struct nfs_server *server = NFS_SERVER(dir); |
722 | struct nfs4_opendata *p; | 726 | struct nfs4_opendata *p; |
723 | 727 | ||
724 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 728 | p = kzalloc(sizeof(*p), gfp_mask); |
725 | if (p == NULL) | 729 | if (p == NULL) |
726 | goto err; | 730 | goto err; |
727 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 731 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); |
728 | if (p->o_arg.seqid == NULL) | 732 | if (p->o_arg.seqid == NULL) |
729 | goto err_free; | 733 | goto err_free; |
730 | path_get(path); | 734 | path_get(path); |
@@ -1060,7 +1064,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context | |||
1060 | { | 1064 | { |
1061 | struct nfs4_opendata *opendata; | 1065 | struct nfs4_opendata *opendata; |
1062 | 1066 | ||
1063 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL); | 1067 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS); |
1064 | if (opendata == NULL) | 1068 | if (opendata == NULL) |
1065 | return ERR_PTR(-ENOMEM); | 1069 | return ERR_PTR(-ENOMEM); |
1066 | opendata->state = state; | 1070 | opendata->state = state; |
@@ -1648,7 +1652,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1648 | if (path->dentry->d_inode != NULL) | 1652 | if (path->dentry->d_inode != NULL) |
1649 | nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); | 1653 | nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode); |
1650 | status = -ENOMEM; | 1654 | status = -ENOMEM; |
1651 | opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr); | 1655 | opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL); |
1652 | if (opendata == NULL) | 1656 | if (opendata == NULL) |
1653 | goto err_put_state_owner; | 1657 | goto err_put_state_owner; |
1654 | 1658 | ||
@@ -1659,15 +1663,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1659 | if (status != 0) | 1663 | if (status != 0) |
1660 | goto err_opendata_put; | 1664 | goto err_opendata_put; |
1661 | 1665 | ||
1662 | if (opendata->o_arg.open_flags & O_EXCL) | ||
1663 | nfs4_exclusive_attrset(opendata, sattr); | ||
1664 | |||
1665 | state = nfs4_opendata_to_nfs4_state(opendata); | 1666 | state = nfs4_opendata_to_nfs4_state(opendata); |
1666 | status = PTR_ERR(state); | 1667 | status = PTR_ERR(state); |
1667 | if (IS_ERR(state)) | 1668 | if (IS_ERR(state)) |
1668 | goto err_opendata_put; | 1669 | goto err_opendata_put; |
1669 | if (server->caps & NFS_CAP_POSIX_LOCK) | 1670 | if (server->caps & NFS_CAP_POSIX_LOCK) |
1670 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); | 1671 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); |
1672 | |||
1673 | if (opendata->o_arg.open_flags & O_EXCL) { | ||
1674 | nfs4_exclusive_attrset(opendata, sattr); | ||
1675 | |||
1676 | nfs_fattr_init(opendata->o_res.f_attr); | ||
1677 | status = nfs4_do_setattr(state->inode, cred, | ||
1678 | opendata->o_res.f_attr, sattr, | ||
1679 | state); | ||
1680 | if (status == 0) | ||
1681 | nfs_setattr_update_inode(state->inode, sattr); | ||
1682 | nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); | ||
1683 | } | ||
1671 | nfs4_opendata_put(opendata); | 1684 | nfs4_opendata_put(opendata); |
1672 | nfs4_put_state_owner(sp); | 1685 | nfs4_put_state_owner(sp); |
1673 | *res = state; | 1686 | *res = state; |
@@ -1914,7 +1927,7 @@ static const struct rpc_call_ops nfs4_close_ops = { | |||
1914 | * | 1927 | * |
1915 | * NOTE: Caller must be holding the sp->so_owner semaphore! | 1928 | * NOTE: Caller must be holding the sp->so_owner semaphore! |
1916 | */ | 1929 | */ |
1917 | int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | 1930 | int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait) |
1918 | { | 1931 | { |
1919 | struct nfs_server *server = NFS_SERVER(state->inode); | 1932 | struct nfs_server *server = NFS_SERVER(state->inode); |
1920 | struct nfs4_closedata *calldata; | 1933 | struct nfs4_closedata *calldata; |
@@ -1933,7 +1946,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1933 | }; | 1946 | }; |
1934 | int status = -ENOMEM; | 1947 | int status = -ENOMEM; |
1935 | 1948 | ||
1936 | calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); | 1949 | calldata = kzalloc(sizeof(*calldata), gfp_mask); |
1937 | if (calldata == NULL) | 1950 | if (calldata == NULL) |
1938 | goto out; | 1951 | goto out; |
1939 | calldata->inode = state->inode; | 1952 | calldata->inode = state->inode; |
@@ -1941,7 +1954,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1941 | calldata->arg.fh = NFS_FH(state->inode); | 1954 | calldata->arg.fh = NFS_FH(state->inode); |
1942 | calldata->arg.stateid = &state->open_stateid; | 1955 | calldata->arg.stateid = &state->open_stateid; |
1943 | /* Serialization for the sequence id */ | 1956 | /* Serialization for the sequence id */ |
1944 | calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); | 1957 | calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid, gfp_mask); |
1945 | if (calldata->arg.seqid == NULL) | 1958 | if (calldata->arg.seqid == NULL) |
1946 | goto out_free_calldata; | 1959 | goto out_free_calldata; |
1947 | calldata->arg.fmode = 0; | 1960 | calldata->arg.fmode = 0; |
@@ -2404,14 +2417,12 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh | |||
2404 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) | 2417 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
2405 | { | 2418 | { |
2406 | struct nfs_server *server = NFS_SERVER(inode); | 2419 | struct nfs_server *server = NFS_SERVER(inode); |
2407 | struct nfs_fattr fattr; | ||
2408 | struct nfs4_accessargs args = { | 2420 | struct nfs4_accessargs args = { |
2409 | .fh = NFS_FH(inode), | 2421 | .fh = NFS_FH(inode), |
2410 | .bitmask = server->attr_bitmask, | 2422 | .bitmask = server->attr_bitmask, |
2411 | }; | 2423 | }; |
2412 | struct nfs4_accessres res = { | 2424 | struct nfs4_accessres res = { |
2413 | .server = server, | 2425 | .server = server, |
2414 | .fattr = &fattr, | ||
2415 | }; | 2426 | }; |
2416 | struct rpc_message msg = { | 2427 | struct rpc_message msg = { |
2417 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], | 2428 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], |
@@ -2438,7 +2449,11 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry | |||
2438 | if (mode & MAY_EXEC) | 2449 | if (mode & MAY_EXEC) |
2439 | args.access |= NFS4_ACCESS_EXECUTE; | 2450 | args.access |= NFS4_ACCESS_EXECUTE; |
2440 | } | 2451 | } |
2441 | nfs_fattr_init(&fattr); | 2452 | |
2453 | res.fattr = nfs_alloc_fattr(); | ||
2454 | if (res.fattr == NULL) | ||
2455 | return -ENOMEM; | ||
2456 | |||
2442 | status = nfs4_call_sync(server, &msg, &args, &res, 0); | 2457 | status = nfs4_call_sync(server, &msg, &args, &res, 0); |
2443 | if (!status) { | 2458 | if (!status) { |
2444 | entry->mask = 0; | 2459 | entry->mask = 0; |
@@ -2448,8 +2463,9 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry | |||
2448 | entry->mask |= MAY_WRITE; | 2463 | entry->mask |= MAY_WRITE; |
2449 | if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) | 2464 | if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) |
2450 | entry->mask |= MAY_EXEC; | 2465 | entry->mask |= MAY_EXEC; |
2451 | nfs_refresh_inode(inode, &fattr); | 2466 | nfs_refresh_inode(inode, res.fattr); |
2452 | } | 2467 | } |
2468 | nfs_free_fattr(res.fattr); | ||
2453 | return status; | 2469 | return status; |
2454 | } | 2470 | } |
2455 | 2471 | ||
@@ -2562,13 +2578,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2562 | } | 2578 | } |
2563 | d_add(dentry, igrab(state->inode)); | 2579 | d_add(dentry, igrab(state->inode)); |
2564 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 2580 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
2565 | if (flags & O_EXCL) { | ||
2566 | struct nfs_fattr fattr; | ||
2567 | status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state); | ||
2568 | if (status == 0) | ||
2569 | nfs_setattr_update_inode(state->inode, sattr); | ||
2570 | nfs_post_op_update_inode(state->inode, &fattr); | ||
2571 | } | ||
2572 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) | 2581 | if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) |
2573 | status = nfs4_intent_set_file(nd, &path, state, fmode); | 2582 | status = nfs4_intent_set_file(nd, &path, state, fmode); |
2574 | else | 2583 | else |
@@ -2596,14 +2605,19 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) | |||
2596 | .rpc_argp = &args, | 2605 | .rpc_argp = &args, |
2597 | .rpc_resp = &res, | 2606 | .rpc_resp = &res, |
2598 | }; | 2607 | }; |
2599 | int status; | 2608 | int status = -ENOMEM; |
2609 | |||
2610 | res.dir_attr = nfs_alloc_fattr(); | ||
2611 | if (res.dir_attr == NULL) | ||
2612 | goto out; | ||
2600 | 2613 | ||
2601 | nfs_fattr_init(&res.dir_attr); | ||
2602 | status = nfs4_call_sync(server, &msg, &args, &res, 1); | 2614 | status = nfs4_call_sync(server, &msg, &args, &res, 1); |
2603 | if (status == 0) { | 2615 | if (status == 0) { |
2604 | update_changeattr(dir, &res.cinfo); | 2616 | update_changeattr(dir, &res.cinfo); |
2605 | nfs_post_op_update_inode(dir, &res.dir_attr); | 2617 | nfs_post_op_update_inode(dir, res.dir_attr); |
2606 | } | 2618 | } |
2619 | nfs_free_fattr(res.dir_attr); | ||
2620 | out: | ||
2607 | return status; | 2621 | return status; |
2608 | } | 2622 | } |
2609 | 2623 | ||
@@ -2638,7 +2652,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) | |||
2638 | if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) | 2652 | if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) |
2639 | return 0; | 2653 | return 0; |
2640 | update_changeattr(dir, &res->cinfo); | 2654 | update_changeattr(dir, &res->cinfo); |
2641 | nfs_post_op_update_inode(dir, &res->dir_attr); | 2655 | nfs_post_op_update_inode(dir, res->dir_attr); |
2642 | return 1; | 2656 | return 1; |
2643 | } | 2657 | } |
2644 | 2658 | ||
@@ -2653,29 +2667,31 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, | |||
2653 | .new_name = new_name, | 2667 | .new_name = new_name, |
2654 | .bitmask = server->attr_bitmask, | 2668 | .bitmask = server->attr_bitmask, |
2655 | }; | 2669 | }; |
2656 | struct nfs_fattr old_fattr, new_fattr; | ||
2657 | struct nfs4_rename_res res = { | 2670 | struct nfs4_rename_res res = { |
2658 | .server = server, | 2671 | .server = server, |
2659 | .old_fattr = &old_fattr, | ||
2660 | .new_fattr = &new_fattr, | ||
2661 | }; | 2672 | }; |
2662 | struct rpc_message msg = { | 2673 | struct rpc_message msg = { |
2663 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME], | 2674 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME], |
2664 | .rpc_argp = &arg, | 2675 | .rpc_argp = &arg, |
2665 | .rpc_resp = &res, | 2676 | .rpc_resp = &res, |
2666 | }; | 2677 | }; |
2667 | int status; | 2678 | int status = -ENOMEM; |
2668 | 2679 | ||
2669 | nfs_fattr_init(res.old_fattr); | 2680 | res.old_fattr = nfs_alloc_fattr(); |
2670 | nfs_fattr_init(res.new_fattr); | 2681 | res.new_fattr = nfs_alloc_fattr(); |
2671 | status = nfs4_call_sync(server, &msg, &arg, &res, 1); | 2682 | if (res.old_fattr == NULL || res.new_fattr == NULL) |
2683 | goto out; | ||
2672 | 2684 | ||
2685 | status = nfs4_call_sync(server, &msg, &arg, &res, 1); | ||
2673 | if (!status) { | 2686 | if (!status) { |
2674 | update_changeattr(old_dir, &res.old_cinfo); | 2687 | update_changeattr(old_dir, &res.old_cinfo); |
2675 | nfs_post_op_update_inode(old_dir, res.old_fattr); | 2688 | nfs_post_op_update_inode(old_dir, res.old_fattr); |
2676 | update_changeattr(new_dir, &res.new_cinfo); | 2689 | update_changeattr(new_dir, &res.new_cinfo); |
2677 | nfs_post_op_update_inode(new_dir, res.new_fattr); | 2690 | nfs_post_op_update_inode(new_dir, res.new_fattr); |
2678 | } | 2691 | } |
2692 | out: | ||
2693 | nfs_free_fattr(res.new_fattr); | ||
2694 | nfs_free_fattr(res.old_fattr); | ||
2679 | return status; | 2695 | return status; |
2680 | } | 2696 | } |
2681 | 2697 | ||
@@ -2702,28 +2718,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr * | |||
2702 | .name = name, | 2718 | .name = name, |
2703 | .bitmask = server->attr_bitmask, | 2719 | .bitmask = server->attr_bitmask, |
2704 | }; | 2720 | }; |
2705 | struct nfs_fattr fattr, dir_attr; | ||
2706 | struct nfs4_link_res res = { | 2721 | struct nfs4_link_res res = { |
2707 | .server = server, | 2722 | .server = server, |
2708 | .fattr = &fattr, | ||
2709 | .dir_attr = &dir_attr, | ||
2710 | }; | 2723 | }; |
2711 | struct rpc_message msg = { | 2724 | struct rpc_message msg = { |
2712 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], | 2725 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], |
2713 | .rpc_argp = &arg, | 2726 | .rpc_argp = &arg, |
2714 | .rpc_resp = &res, | 2727 | .rpc_resp = &res, |
2715 | }; | 2728 | }; |
2716 | int status; | 2729 | int status = -ENOMEM; |
2730 | |||
2731 | res.fattr = nfs_alloc_fattr(); | ||
2732 | res.dir_attr = nfs_alloc_fattr(); | ||
2733 | if (res.fattr == NULL || res.dir_attr == NULL) | ||
2734 | goto out; | ||
2717 | 2735 | ||
2718 | nfs_fattr_init(res.fattr); | ||
2719 | nfs_fattr_init(res.dir_attr); | ||
2720 | status = nfs4_call_sync(server, &msg, &arg, &res, 1); | 2736 | status = nfs4_call_sync(server, &msg, &arg, &res, 1); |
2721 | if (!status) { | 2737 | if (!status) { |
2722 | update_changeattr(dir, &res.cinfo); | 2738 | update_changeattr(dir, &res.cinfo); |
2723 | nfs_post_op_update_inode(dir, res.dir_attr); | 2739 | nfs_post_op_update_inode(dir, res.dir_attr); |
2724 | nfs_post_op_update_inode(inode, res.fattr); | 2740 | nfs_post_op_update_inode(inode, res.fattr); |
2725 | } | 2741 | } |
2726 | 2742 | out: | |
2743 | nfs_free_fattr(res.dir_attr); | ||
2744 | nfs_free_fattr(res.fattr); | ||
2727 | return status; | 2745 | return status; |
2728 | } | 2746 | } |
2729 | 2747 | ||
@@ -3146,23 +3164,31 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa | |||
3146 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; | 3164 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; |
3147 | } | 3165 | } |
3148 | 3166 | ||
3167 | struct nfs4_renewdata { | ||
3168 | struct nfs_client *client; | ||
3169 | unsigned long timestamp; | ||
3170 | }; | ||
3171 | |||
3149 | /* | 3172 | /* |
3150 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special | 3173 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special |
3151 | * standalone procedure for queueing an asynchronous RENEW. | 3174 | * standalone procedure for queueing an asynchronous RENEW. |
3152 | */ | 3175 | */ |
3153 | static void nfs4_renew_release(void *data) | 3176 | static void nfs4_renew_release(void *calldata) |
3154 | { | 3177 | { |
3155 | struct nfs_client *clp = data; | 3178 | struct nfs4_renewdata *data = calldata; |
3179 | struct nfs_client *clp = data->client; | ||
3156 | 3180 | ||
3157 | if (atomic_read(&clp->cl_count) > 1) | 3181 | if (atomic_read(&clp->cl_count) > 1) |
3158 | nfs4_schedule_state_renewal(clp); | 3182 | nfs4_schedule_state_renewal(clp); |
3159 | nfs_put_client(clp); | 3183 | nfs_put_client(clp); |
3184 | kfree(data); | ||
3160 | } | 3185 | } |
3161 | 3186 | ||
3162 | static void nfs4_renew_done(struct rpc_task *task, void *data) | 3187 | static void nfs4_renew_done(struct rpc_task *task, void *calldata) |
3163 | { | 3188 | { |
3164 | struct nfs_client *clp = data; | 3189 | struct nfs4_renewdata *data = calldata; |
3165 | unsigned long timestamp = task->tk_start; | 3190 | struct nfs_client *clp = data->client; |
3191 | unsigned long timestamp = data->timestamp; | ||
3166 | 3192 | ||
3167 | if (task->tk_status < 0) { | 3193 | if (task->tk_status < 0) { |
3168 | /* Unless we're shutting down, schedule state recovery! */ | 3194 | /* 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) | |||
3188 | .rpc_argp = clp, | 3214 | .rpc_argp = clp, |
3189 | .rpc_cred = cred, | 3215 | .rpc_cred = cred, |
3190 | }; | 3216 | }; |
3217 | struct nfs4_renewdata *data; | ||
3191 | 3218 | ||
3192 | if (!atomic_inc_not_zero(&clp->cl_count)) | 3219 | if (!atomic_inc_not_zero(&clp->cl_count)) |
3193 | return -EIO; | 3220 | return -EIO; |
3221 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
3222 | if (data == NULL) | ||
3223 | return -ENOMEM; | ||
3224 | data->client = clp; | ||
3225 | data->timestamp = jiffies; | ||
3194 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, | 3226 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, |
3195 | &nfs4_renew_ops, clp); | 3227 | &nfs4_renew_ops, data); |
3196 | } | 3228 | } |
3197 | 3229 | ||
3198 | int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) | 3230 | 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, | |||
3494 | return _nfs4_async_handle_error(task, server, server->nfs_client, state); | 3526 | return _nfs4_async_handle_error(task, server, server->nfs_client, state); |
3495 | } | 3527 | } |
3496 | 3528 | ||
3497 | int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) | 3529 | int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, |
3530 | unsigned short port, struct rpc_cred *cred, | ||
3531 | struct nfs4_setclientid_res *res) | ||
3498 | { | 3532 | { |
3499 | nfs4_verifier sc_verifier; | 3533 | nfs4_verifier sc_verifier; |
3500 | struct nfs4_setclientid setclientid = { | 3534 | struct nfs4_setclientid setclientid = { |
@@ -3504,7 +3538,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po | |||
3504 | struct rpc_message msg = { | 3538 | struct rpc_message msg = { |
3505 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], | 3539 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], |
3506 | .rpc_argp = &setclientid, | 3540 | .rpc_argp = &setclientid, |
3507 | .rpc_resp = clp, | 3541 | .rpc_resp = res, |
3508 | .rpc_cred = cred, | 3542 | .rpc_cred = cred, |
3509 | }; | 3543 | }; |
3510 | __be32 *p; | 3544 | __be32 *p; |
@@ -3547,12 +3581,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po | |||
3547 | return status; | 3581 | return status; |
3548 | } | 3582 | } |
3549 | 3583 | ||
3550 | static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) | 3584 | static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, |
3585 | struct nfs4_setclientid_res *arg, | ||
3586 | struct rpc_cred *cred) | ||
3551 | { | 3587 | { |
3552 | struct nfs_fsinfo fsinfo; | 3588 | struct nfs_fsinfo fsinfo; |
3553 | struct rpc_message msg = { | 3589 | struct rpc_message msg = { |
3554 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], | 3590 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], |
3555 | .rpc_argp = clp, | 3591 | .rpc_argp = arg, |
3556 | .rpc_resp = &fsinfo, | 3592 | .rpc_resp = &fsinfo, |
3557 | .rpc_cred = cred, | 3593 | .rpc_cred = cred, |
3558 | }; | 3594 | }; |
@@ -3570,12 +3606,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre | |||
3570 | return status; | 3606 | return status; |
3571 | } | 3607 | } |
3572 | 3608 | ||
3573 | int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) | 3609 | int nfs4_proc_setclientid_confirm(struct nfs_client *clp, |
3610 | struct nfs4_setclientid_res *arg, | ||
3611 | struct rpc_cred *cred) | ||
3574 | { | 3612 | { |
3575 | long timeout = 0; | 3613 | long timeout = 0; |
3576 | int err; | 3614 | int err; |
3577 | do { | 3615 | do { |
3578 | err = _nfs4_proc_setclientid_confirm(clp, cred); | 3616 | err = _nfs4_proc_setclientid_confirm(clp, arg, cred); |
3579 | switch (err) { | 3617 | switch (err) { |
3580 | case 0: | 3618 | case 0: |
3581 | return err; | 3619 | return err; |
@@ -3667,7 +3705,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
3667 | }; | 3705 | }; |
3668 | int status = 0; | 3706 | int status = 0; |
3669 | 3707 | ||
3670 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 3708 | data = kzalloc(sizeof(*data), GFP_NOFS); |
3671 | if (data == NULL) | 3709 | if (data == NULL) |
3672 | return -ENOMEM; | 3710 | return -ENOMEM; |
3673 | data->args.fhandle = &data->fh; | 3711 | data->args.fhandle = &data->fh; |
@@ -3823,7 +3861,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, | |||
3823 | struct nfs4_unlockdata *p; | 3861 | struct nfs4_unlockdata *p; |
3824 | struct inode *inode = lsp->ls_state->inode; | 3862 | struct inode *inode = lsp->ls_state->inode; |
3825 | 3863 | ||
3826 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 3864 | p = kzalloc(sizeof(*p), GFP_NOFS); |
3827 | if (p == NULL) | 3865 | if (p == NULL) |
3828 | return NULL; | 3866 | return NULL; |
3829 | p->arg.fh = NFS_FH(inode); | 3867 | p->arg.fh = NFS_FH(inode); |
@@ -3961,7 +3999,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * | |||
3961 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) | 3999 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) |
3962 | goto out; | 4000 | goto out; |
3963 | lsp = request->fl_u.nfs4_fl.owner; | 4001 | lsp = request->fl_u.nfs4_fl.owner; |
3964 | seqid = nfs_alloc_seqid(&lsp->ls_seqid); | 4002 | seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL); |
3965 | status = -ENOMEM; | 4003 | status = -ENOMEM; |
3966 | if (seqid == NULL) | 4004 | if (seqid == NULL) |
3967 | goto out; | 4005 | goto out; |
@@ -3989,22 +4027,23 @@ struct nfs4_lockdata { | |||
3989 | }; | 4027 | }; |
3990 | 4028 | ||
3991 | static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, | 4029 | static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, |
3992 | struct nfs_open_context *ctx, struct nfs4_lock_state *lsp) | 4030 | struct nfs_open_context *ctx, struct nfs4_lock_state *lsp, |
4031 | gfp_t gfp_mask) | ||
3993 | { | 4032 | { |
3994 | struct nfs4_lockdata *p; | 4033 | struct nfs4_lockdata *p; |
3995 | struct inode *inode = lsp->ls_state->inode; | 4034 | struct inode *inode = lsp->ls_state->inode; |
3996 | struct nfs_server *server = NFS_SERVER(inode); | 4035 | struct nfs_server *server = NFS_SERVER(inode); |
3997 | 4036 | ||
3998 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 4037 | p = kzalloc(sizeof(*p), gfp_mask); |
3999 | if (p == NULL) | 4038 | if (p == NULL) |
4000 | return NULL; | 4039 | return NULL; |
4001 | 4040 | ||
4002 | p->arg.fh = NFS_FH(inode); | 4041 | p->arg.fh = NFS_FH(inode); |
4003 | p->arg.fl = &p->fl; | 4042 | p->arg.fl = &p->fl; |
4004 | p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); | 4043 | p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask); |
4005 | if (p->arg.open_seqid == NULL) | 4044 | if (p->arg.open_seqid == NULL) |
4006 | goto out_free; | 4045 | goto out_free; |
4007 | p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); | 4046 | p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid, gfp_mask); |
4008 | if (p->arg.lock_seqid == NULL) | 4047 | if (p->arg.lock_seqid == NULL) |
4009 | goto out_free_seqid; | 4048 | goto out_free_seqid; |
4010 | p->arg.lock_stateid = &lsp->ls_stateid; | 4049 | 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 | |||
4158 | 4197 | ||
4159 | dprintk("%s: begin!\n", __func__); | 4198 | dprintk("%s: begin!\n", __func__); |
4160 | data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), | 4199 | data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), |
4161 | fl->fl_u.nfs4_fl.owner); | 4200 | fl->fl_u.nfs4_fl.owner, |
4201 | recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS); | ||
4162 | if (data == NULL) | 4202 | if (data == NULL) |
4163 | return -ENOMEM; | 4203 | return -ENOMEM; |
4164 | if (IS_SETLKW(cmd)) | 4204 | if (IS_SETLKW(cmd)) |
@@ -4647,7 +4687,7 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, | |||
4647 | if (max_reqs != tbl->max_slots) { | 4687 | if (max_reqs != tbl->max_slots) { |
4648 | ret = -ENOMEM; | 4688 | ret = -ENOMEM; |
4649 | new = kmalloc(max_reqs * sizeof(struct nfs4_slot), | 4689 | new = kmalloc(max_reqs * sizeof(struct nfs4_slot), |
4650 | GFP_KERNEL); | 4690 | GFP_NOFS); |
4651 | if (!new) | 4691 | if (!new) |
4652 | goto out; | 4692 | goto out; |
4653 | ret = 0; | 4693 | ret = 0; |
@@ -4712,7 +4752,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, | |||
4712 | 4752 | ||
4713 | dprintk("--> %s: max_reqs=%u\n", __func__, max_slots); | 4753 | dprintk("--> %s: max_reqs=%u\n", __func__, max_slots); |
4714 | 4754 | ||
4715 | slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); | 4755 | slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS); |
4716 | if (!slot) | 4756 | if (!slot) |
4717 | goto out; | 4757 | goto out; |
4718 | ret = 0; | 4758 | ret = 0; |
@@ -4761,7 +4801,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | |||
4761 | struct nfs4_session *session; | 4801 | struct nfs4_session *session; |
4762 | struct nfs4_slot_table *tbl; | 4802 | struct nfs4_slot_table *tbl; |
4763 | 4803 | ||
4764 | session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL); | 4804 | session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); |
4765 | if (!session) | 4805 | if (!session) |
4766 | return NULL; | 4806 | return NULL; |
4767 | 4807 | ||
@@ -5105,8 +5145,8 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, | |||
5105 | 5145 | ||
5106 | if (!atomic_inc_not_zero(&clp->cl_count)) | 5146 | if (!atomic_inc_not_zero(&clp->cl_count)) |
5107 | return -EIO; | 5147 | return -EIO; |
5108 | args = kzalloc(sizeof(*args), GFP_KERNEL); | 5148 | args = kzalloc(sizeof(*args), GFP_NOFS); |
5109 | res = kzalloc(sizeof(*res), GFP_KERNEL); | 5149 | res = kzalloc(sizeof(*res), GFP_NOFS); |
5110 | if (!args || !res) { | 5150 | if (!args || !res) { |
5111 | kfree(args); | 5151 | kfree(args); |
5112 | kfree(res); | 5152 | kfree(res); |
@@ -5207,7 +5247,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) | |||
5207 | int status = -ENOMEM; | 5247 | int status = -ENOMEM; |
5208 | 5248 | ||
5209 | dprintk("--> %s\n", __func__); | 5249 | dprintk("--> %s\n", __func__); |
5210 | calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); | 5250 | calldata = kzalloc(sizeof(*calldata), GFP_NOFS); |
5211 | if (calldata == NULL) | 5251 | if (calldata == NULL) |
5212 | goto out; | 5252 | goto out; |
5213 | calldata->clp = clp; | 5253 | calldata->clp = clp; |
@@ -5218,9 +5258,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) | |||
5218 | msg.rpc_resp = &calldata->res; | 5258 | msg.rpc_resp = &calldata->res; |
5219 | task_setup_data.callback_data = calldata; | 5259 | task_setup_data.callback_data = calldata; |
5220 | task = rpc_run_task(&task_setup_data); | 5260 | task = rpc_run_task(&task_setup_data); |
5221 | if (IS_ERR(task)) | 5261 | if (IS_ERR(task)) { |
5222 | status = PTR_ERR(task); | 5262 | status = PTR_ERR(task); |
5263 | goto out; | ||
5264 | } | ||
5223 | rpc_put_task(task); | 5265 | rpc_put_task(task); |
5266 | return 0; | ||
5224 | out: | 5267 | out: |
5225 | dprintk("<-- %s status=%d\n", __func__, status); | 5268 | dprintk("<-- %s status=%d\n", __func__, status); |
5226 | return status; | 5269 | return status; |