diff options
-rw-r--r-- | fs/nfs/idmap.c | 83 | ||||
-rw-r--r-- | fs/nfs/inode.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 106 | ||||
-rw-r--r-- | include/linux/nfs_idmap.h | 8 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 17 |
6 files changed, 162 insertions, 64 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 47d1c6ff2d8e..2c05f1991e1e 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -38,6 +38,89 @@ | |||
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/nfs_idmap.h> | 40 | #include <linux/nfs_idmap.h> |
41 | #include <linux/nfs_fs.h> | ||
42 | |||
43 | /** | ||
44 | * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields | ||
45 | * @fattr: fully initialised struct nfs_fattr | ||
46 | * @owner_name: owner name string cache | ||
47 | * @group_name: group name string cache | ||
48 | */ | ||
49 | void nfs_fattr_init_names(struct nfs_fattr *fattr, | ||
50 | struct nfs4_string *owner_name, | ||
51 | struct nfs4_string *group_name) | ||
52 | { | ||
53 | fattr->owner_name = owner_name; | ||
54 | fattr->group_name = group_name; | ||
55 | } | ||
56 | |||
57 | static void nfs_fattr_free_owner_name(struct nfs_fattr *fattr) | ||
58 | { | ||
59 | fattr->valid &= ~NFS_ATTR_FATTR_OWNER_NAME; | ||
60 | kfree(fattr->owner_name->data); | ||
61 | } | ||
62 | |||
63 | static void nfs_fattr_free_group_name(struct nfs_fattr *fattr) | ||
64 | { | ||
65 | fattr->valid &= ~NFS_ATTR_FATTR_GROUP_NAME; | ||
66 | kfree(fattr->group_name->data); | ||
67 | } | ||
68 | |||
69 | static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr) | ||
70 | { | ||
71 | struct nfs4_string *owner = fattr->owner_name; | ||
72 | __u32 uid; | ||
73 | |||
74 | if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) | ||
75 | return false; | ||
76 | if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) { | ||
77 | fattr->uid = uid; | ||
78 | fattr->valid |= NFS_ATTR_FATTR_OWNER; | ||
79 | } | ||
80 | return true; | ||
81 | } | ||
82 | |||
83 | static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr) | ||
84 | { | ||
85 | struct nfs4_string *group = fattr->group_name; | ||
86 | __u32 gid; | ||
87 | |||
88 | if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) | ||
89 | return false; | ||
90 | if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) { | ||
91 | fattr->gid = gid; | ||
92 | fattr->valid |= NFS_ATTR_FATTR_GROUP; | ||
93 | } | ||
94 | return true; | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * nfs_fattr_free_names - free up the NFSv4 owner and group strings | ||
99 | * @fattr: a fully initialised nfs_fattr structure | ||
100 | */ | ||
101 | void nfs_fattr_free_names(struct nfs_fattr *fattr) | ||
102 | { | ||
103 | if (fattr->valid & NFS_ATTR_FATTR_OWNER_NAME) | ||
104 | nfs_fattr_free_owner_name(fattr); | ||
105 | if (fattr->valid & NFS_ATTR_FATTR_GROUP_NAME) | ||
106 | nfs_fattr_free_group_name(fattr); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * nfs_fattr_map_and_free_names - map owner/group strings into uid/gid and free | ||
111 | * @server: pointer to the filesystem nfs_server structure | ||
112 | * @fattr: a fully initialised nfs_fattr structure | ||
113 | * | ||
114 | * This helper maps the cached NFSv4 owner/group strings in fattr into | ||
115 | * their numeric uid/gid equivalents, and then frees the cached strings. | ||
116 | */ | ||
117 | void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *fattr) | ||
118 | { | ||
119 | if (nfs_fattr_map_owner_name(server, fattr)) | ||
120 | nfs_fattr_free_owner_name(fattr); | ||
121 | if (nfs_fattr_map_group_name(server, fattr)) | ||
122 | nfs_fattr_free_group_name(fattr); | ||
123 | } | ||
41 | 124 | ||
42 | static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) | 125 | static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) |
43 | { | 126 | { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 50a15fa8cf98..f59cab12a8ee 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1019,6 +1019,8 @@ void nfs_fattr_init(struct nfs_fattr *fattr) | |||
1019 | fattr->valid = 0; | 1019 | fattr->valid = 0; |
1020 | fattr->time_start = jiffies; | 1020 | fattr->time_start = jiffies; |
1021 | fattr->gencount = nfs_inc_attr_generation_counter(); | 1021 | fattr->gencount = nfs_inc_attr_generation_counter(); |
1022 | fattr->owner_name = NULL; | ||
1023 | fattr->group_name = NULL; | ||
1022 | } | 1024 | } |
1023 | 1025 | ||
1024 | struct nfs_fattr *nfs_alloc_fattr(void) | 1026 | struct nfs_fattr *nfs_alloc_fattr(void) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3b1080118452..df3d3068242e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/namei.h> | 52 | #include <linux/namei.h> |
53 | #include <linux/mount.h> | 53 | #include <linux/mount.h> |
54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
55 | #include <linux/nfs_idmap.h> | ||
55 | #include <linux/sunrpc/bc_xprt.h> | 56 | #include <linux/sunrpc/bc_xprt.h> |
56 | #include <linux/xattr.h> | 57 | #include <linux/xattr.h> |
57 | #include <linux/utsname.h> | 58 | #include <linux/utsname.h> |
@@ -760,6 +761,8 @@ struct nfs4_opendata { | |||
760 | struct nfs_openres o_res; | 761 | struct nfs_openres o_res; |
761 | struct nfs_open_confirmargs c_arg; | 762 | struct nfs_open_confirmargs c_arg; |
762 | struct nfs_open_confirmres c_res; | 763 | struct nfs_open_confirmres c_res; |
764 | struct nfs4_string owner_name; | ||
765 | struct nfs4_string group_name; | ||
763 | struct nfs_fattr f_attr; | 766 | struct nfs_fattr f_attr; |
764 | struct nfs_fattr dir_attr; | 767 | struct nfs_fattr dir_attr; |
765 | struct dentry *dir; | 768 | struct dentry *dir; |
@@ -783,6 +786,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p) | |||
783 | p->o_res.server = p->o_arg.server; | 786 | p->o_res.server = p->o_arg.server; |
784 | nfs_fattr_init(&p->f_attr); | 787 | nfs_fattr_init(&p->f_attr); |
785 | nfs_fattr_init(&p->dir_attr); | 788 | nfs_fattr_init(&p->dir_attr); |
789 | nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name); | ||
786 | } | 790 | } |
787 | 791 | ||
788 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | 792 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, |
@@ -814,6 +818,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
814 | p->o_arg.name = &dentry->d_name; | 818 | p->o_arg.name = &dentry->d_name; |
815 | p->o_arg.server = server; | 819 | p->o_arg.server = server; |
816 | p->o_arg.bitmask = server->attr_bitmask; | 820 | p->o_arg.bitmask = server->attr_bitmask; |
821 | p->o_arg.dir_bitmask = server->cache_consistency_bitmask; | ||
817 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; | 822 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; |
818 | if (flags & O_CREAT) { | 823 | if (flags & O_CREAT) { |
819 | u32 *s; | 824 | u32 *s; |
@@ -850,6 +855,7 @@ static void nfs4_opendata_free(struct kref *kref) | |||
850 | dput(p->dir); | 855 | dput(p->dir); |
851 | dput(p->dentry); | 856 | dput(p->dentry); |
852 | nfs_sb_deactive(sb); | 857 | nfs_sb_deactive(sb); |
858 | nfs_fattr_free_names(&p->f_attr); | ||
853 | kfree(p); | 859 | kfree(p); |
854 | } | 860 | } |
855 | 861 | ||
@@ -1574,6 +1580,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data) | |||
1574 | if (status != 0 || !data->rpc_done) | 1580 | if (status != 0 || !data->rpc_done) |
1575 | return status; | 1581 | return status; |
1576 | 1582 | ||
1583 | nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr); | ||
1584 | |||
1577 | nfs_refresh_inode(dir, o_res->dir_attr); | 1585 | nfs_refresh_inode(dir, o_res->dir_attr); |
1578 | 1586 | ||
1579 | if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { | 1587 | if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { |
@@ -1606,6 +1614,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
1606 | return status; | 1614 | return status; |
1607 | } | 1615 | } |
1608 | 1616 | ||
1617 | nfs_fattr_map_and_free_names(server, &data->f_attr); | ||
1618 | |||
1609 | if (o_arg->open_flags & O_CREAT) { | 1619 | if (o_arg->open_flags & O_CREAT) { |
1610 | update_changeattr(dir, &o_res->cinfo); | 1620 | update_changeattr(dir, &o_res->cinfo); |
1611 | nfs_post_op_update_inode(dir, o_res->dir_attr); | 1621 | nfs_post_op_update_inode(dir, o_res->dir_attr); |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index dcaf69309d8e..95e92e438407 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -2298,7 +2298,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2298 | encode_getfh(xdr, &hdr); | 2298 | encode_getfh(xdr, &hdr); |
2299 | encode_getfattr(xdr, args->bitmask, &hdr); | 2299 | encode_getfattr(xdr, args->bitmask, &hdr); |
2300 | encode_restorefh(xdr, &hdr); | 2300 | encode_restorefh(xdr, &hdr); |
2301 | encode_getfattr(xdr, args->bitmask, &hdr); | 2301 | encode_getfattr(xdr, args->dir_bitmask, &hdr); |
2302 | encode_nops(&hdr); | 2302 | encode_nops(&hdr); |
2303 | } | 2303 | } |
2304 | 2304 | ||
@@ -3792,7 +3792,8 @@ out_overflow: | |||
3792 | } | 3792 | } |
3793 | 3793 | ||
3794 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, | 3794 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, |
3795 | const struct nfs_server *server, uint32_t *uid, int may_sleep) | 3795 | const struct nfs_server *server, uint32_t *uid, |
3796 | struct nfs4_string *owner_name) | ||
3796 | { | 3797 | { |
3797 | uint32_t len; | 3798 | uint32_t len; |
3798 | __be32 *p; | 3799 | __be32 *p; |
@@ -3809,8 +3810,12 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3809 | p = xdr_inline_decode(xdr, len); | 3810 | p = xdr_inline_decode(xdr, len); |
3810 | if (unlikely(!p)) | 3811 | if (unlikely(!p)) |
3811 | goto out_overflow; | 3812 | goto out_overflow; |
3812 | if (!may_sleep) { | 3813 | if (owner_name != NULL) { |
3813 | /* do nothing */ | 3814 | owner_name->data = kmemdup(p, len, GFP_NOWAIT); |
3815 | if (owner_name->data != NULL) { | ||
3816 | owner_name->len = len; | ||
3817 | ret = NFS_ATTR_FATTR_OWNER_NAME; | ||
3818 | } | ||
3814 | } else if (len < XDR_MAX_NETOBJ) { | 3819 | } else if (len < XDR_MAX_NETOBJ) { |
3815 | if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) | 3820 | if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) |
3816 | ret = NFS_ATTR_FATTR_OWNER; | 3821 | ret = NFS_ATTR_FATTR_OWNER; |
@@ -3830,7 +3835,8 @@ out_overflow: | |||
3830 | } | 3835 | } |
3831 | 3836 | ||
3832 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | 3837 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, |
3833 | const struct nfs_server *server, uint32_t *gid, int may_sleep) | 3838 | const struct nfs_server *server, uint32_t *gid, |
3839 | struct nfs4_string *group_name) | ||
3834 | { | 3840 | { |
3835 | uint32_t len; | 3841 | uint32_t len; |
3836 | __be32 *p; | 3842 | __be32 *p; |
@@ -3847,8 +3853,12 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3847 | p = xdr_inline_decode(xdr, len); | 3853 | p = xdr_inline_decode(xdr, len); |
3848 | if (unlikely(!p)) | 3854 | if (unlikely(!p)) |
3849 | goto out_overflow; | 3855 | goto out_overflow; |
3850 | if (!may_sleep) { | 3856 | if (group_name != NULL) { |
3851 | /* do nothing */ | 3857 | group_name->data = kmemdup(p, len, GFP_NOWAIT); |
3858 | if (group_name->data != NULL) { | ||
3859 | group_name->len = len; | ||
3860 | ret = NFS_ATTR_FATTR_GROUP_NAME; | ||
3861 | } | ||
3852 | } else if (len < XDR_MAX_NETOBJ) { | 3862 | } else if (len < XDR_MAX_NETOBJ) { |
3853 | if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) | 3863 | if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) |
3854 | ret = NFS_ATTR_FATTR_GROUP; | 3864 | ret = NFS_ATTR_FATTR_GROUP; |
@@ -4285,7 +4295,7 @@ xdr_error: | |||
4285 | 4295 | ||
4286 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | 4296 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, |
4287 | struct nfs_fattr *fattr, struct nfs_fh *fh, | 4297 | struct nfs_fattr *fattr, struct nfs_fh *fh, |
4288 | const struct nfs_server *server, int may_sleep) | 4298 | const struct nfs_server *server) |
4289 | { | 4299 | { |
4290 | int status; | 4300 | int status; |
4291 | umode_t fmode = 0; | 4301 | umode_t fmode = 0; |
@@ -4352,12 +4362,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4352 | goto xdr_error; | 4362 | goto xdr_error; |
4353 | fattr->valid |= status; | 4363 | fattr->valid |= status; |
4354 | 4364 | ||
4355 | status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, may_sleep); | 4365 | status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name); |
4356 | if (status < 0) | 4366 | if (status < 0) |
4357 | goto xdr_error; | 4367 | goto xdr_error; |
4358 | fattr->valid |= status; | 4368 | fattr->valid |= status; |
4359 | 4369 | ||
4360 | status = decode_attr_group(xdr, bitmap, server, &fattr->gid, may_sleep); | 4370 | status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name); |
4361 | if (status < 0) | 4371 | if (status < 0) |
4362 | goto xdr_error; | 4372 | goto xdr_error; |
4363 | fattr->valid |= status; | 4373 | fattr->valid |= status; |
@@ -4398,7 +4408,7 @@ xdr_error: | |||
4398 | } | 4408 | } |
4399 | 4409 | ||
4400 | static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, | 4410 | static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, |
4401 | struct nfs_fh *fh, const struct nfs_server *server, int may_sleep) | 4411 | struct nfs_fh *fh, const struct nfs_server *server) |
4402 | { | 4412 | { |
4403 | __be32 *savep; | 4413 | __be32 *savep; |
4404 | uint32_t attrlen, | 4414 | uint32_t attrlen, |
@@ -4417,7 +4427,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat | |||
4417 | if (status < 0) | 4427 | if (status < 0) |
4418 | goto xdr_error; | 4428 | goto xdr_error; |
4419 | 4429 | ||
4420 | status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server, may_sleep); | 4430 | status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server); |
4421 | if (status < 0) | 4431 | if (status < 0) |
4422 | goto xdr_error; | 4432 | goto xdr_error; |
4423 | 4433 | ||
@@ -4428,9 +4438,9 @@ xdr_error: | |||
4428 | } | 4438 | } |
4429 | 4439 | ||
4430 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, | 4440 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, |
4431 | const struct nfs_server *server, int may_sleep) | 4441 | const struct nfs_server *server) |
4432 | { | 4442 | { |
4433 | return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep); | 4443 | return decode_getfattr_generic(xdr, fattr, NULL, server); |
4434 | } | 4444 | } |
4435 | 4445 | ||
4436 | /* | 4446 | /* |
@@ -5711,8 +5721,7 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, | |||
5711 | status = decode_open_downgrade(xdr, res); | 5721 | status = decode_open_downgrade(xdr, res); |
5712 | if (status != 0) | 5722 | if (status != 0) |
5713 | goto out; | 5723 | goto out; |
5714 | decode_getfattr(xdr, res->fattr, res->server, | 5724 | decode_getfattr(xdr, res->fattr, res->server); |
5715 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5716 | out: | 5725 | out: |
5717 | return status; | 5726 | return status; |
5718 | } | 5727 | } |
@@ -5738,8 +5747,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5738 | status = decode_access(xdr, res); | 5747 | status = decode_access(xdr, res); |
5739 | if (status != 0) | 5748 | if (status != 0) |
5740 | goto out; | 5749 | goto out; |
5741 | decode_getfattr(xdr, res->fattr, res->server, | 5750 | decode_getfattr(xdr, res->fattr, res->server); |
5742 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5743 | out: | 5751 | out: |
5744 | return status; | 5752 | return status; |
5745 | } | 5753 | } |
@@ -5768,8 +5776,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5768 | status = decode_getfh(xdr, res->fh); | 5776 | status = decode_getfh(xdr, res->fh); |
5769 | if (status) | 5777 | if (status) |
5770 | goto out; | 5778 | goto out; |
5771 | status = decode_getfattr(xdr, res->fattr, res->server | 5779 | status = decode_getfattr(xdr, res->fattr, res->server); |
5772 | ,!RPC_IS_ASYNC(rqstp->rq_task)); | ||
5773 | out: | 5780 | out: |
5774 | return status; | 5781 | return status; |
5775 | } | 5782 | } |
@@ -5795,8 +5802,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, | |||
5795 | goto out; | 5802 | goto out; |
5796 | status = decode_getfh(xdr, res->fh); | 5803 | status = decode_getfh(xdr, res->fh); |
5797 | if (status == 0) | 5804 | if (status == 0) |
5798 | status = decode_getfattr(xdr, res->fattr, res->server, | 5805 | status = decode_getfattr(xdr, res->fattr, res->server); |
5799 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5800 | out: | 5806 | out: |
5801 | return status; | 5807 | return status; |
5802 | } | 5808 | } |
@@ -5822,8 +5828,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5822 | status = decode_remove(xdr, &res->cinfo); | 5828 | status = decode_remove(xdr, &res->cinfo); |
5823 | if (status) | 5829 | if (status) |
5824 | goto out; | 5830 | goto out; |
5825 | decode_getfattr(xdr, res->dir_attr, res->server, | 5831 | decode_getfattr(xdr, res->dir_attr, res->server); |
5826 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5827 | out: | 5832 | out: |
5828 | return status; | 5833 | return status; |
5829 | } | 5834 | } |
@@ -5856,14 +5861,12 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5856 | if (status) | 5861 | if (status) |
5857 | goto out; | 5862 | goto out; |
5858 | /* Current FH is target directory */ | 5863 | /* Current FH is target directory */ |
5859 | if (decode_getfattr(xdr, res->new_fattr, res->server, | 5864 | if (decode_getfattr(xdr, res->new_fattr, res->server)) |
5860 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
5861 | goto out; | 5865 | goto out; |
5862 | status = decode_restorefh(xdr); | 5866 | status = decode_restorefh(xdr); |
5863 | if (status) | 5867 | if (status) |
5864 | goto out; | 5868 | goto out; |
5865 | decode_getfattr(xdr, res->old_fattr, res->server, | 5869 | decode_getfattr(xdr, res->old_fattr, res->server); |
5866 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5867 | out: | 5870 | out: |
5868 | return status; | 5871 | return status; |
5869 | } | 5872 | } |
@@ -5899,14 +5902,12 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5899 | * Note order: OP_LINK leaves the directory as the current | 5902 | * Note order: OP_LINK leaves the directory as the current |
5900 | * filehandle. | 5903 | * filehandle. |
5901 | */ | 5904 | */ |
5902 | if (decode_getfattr(xdr, res->dir_attr, res->server, | 5905 | if (decode_getfattr(xdr, res->dir_attr, res->server)) |
5903 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
5904 | goto out; | 5906 | goto out; |
5905 | status = decode_restorefh(xdr); | 5907 | status = decode_restorefh(xdr); |
5906 | if (status) | 5908 | if (status) |
5907 | goto out; | 5909 | goto out; |
5908 | decode_getfattr(xdr, res->fattr, res->server, | 5910 | decode_getfattr(xdr, res->fattr, res->server); |
5909 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5910 | out: | 5911 | out: |
5911 | return status; | 5912 | return status; |
5912 | } | 5913 | } |
@@ -5938,14 +5939,12 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5938 | status = decode_getfh(xdr, res->fh); | 5939 | status = decode_getfh(xdr, res->fh); |
5939 | if (status) | 5940 | if (status) |
5940 | goto out; | 5941 | goto out; |
5941 | if (decode_getfattr(xdr, res->fattr, res->server, | 5942 | if (decode_getfattr(xdr, res->fattr, res->server)) |
5942 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
5943 | goto out; | 5943 | goto out; |
5944 | status = decode_restorefh(xdr); | 5944 | status = decode_restorefh(xdr); |
5945 | if (status) | 5945 | if (status) |
5946 | goto out; | 5946 | goto out; |
5947 | decode_getfattr(xdr, res->dir_fattr, res->server, | 5947 | decode_getfattr(xdr, res->dir_fattr, res->server); |
5948 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5949 | out: | 5948 | out: |
5950 | return status; | 5949 | return status; |
5951 | } | 5950 | } |
@@ -5977,8 +5976,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5977 | status = decode_putfh(xdr); | 5976 | status = decode_putfh(xdr); |
5978 | if (status) | 5977 | if (status) |
5979 | goto out; | 5978 | goto out; |
5980 | status = decode_getfattr(xdr, res->fattr, res->server, | 5979 | status = decode_getfattr(xdr, res->fattr, res->server); |
5981 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
5982 | out: | 5980 | out: |
5983 | return status; | 5981 | return status; |
5984 | } | 5982 | } |
@@ -6076,8 +6074,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6076 | * an ESTALE error. Shouldn't be a problem, | 6074 | * an ESTALE error. Shouldn't be a problem, |
6077 | * though, since fattr->valid will remain unset. | 6075 | * though, since fattr->valid will remain unset. |
6078 | */ | 6076 | */ |
6079 | decode_getfattr(xdr, res->fattr, res->server, | 6077 | decode_getfattr(xdr, res->fattr, res->server); |
6080 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6081 | out: | 6078 | out: |
6082 | return status; | 6079 | return status; |
6083 | } | 6080 | } |
@@ -6108,13 +6105,11 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6108 | goto out; | 6105 | goto out; |
6109 | if (decode_getfh(xdr, &res->fh) != 0) | 6106 | if (decode_getfh(xdr, &res->fh) != 0) |
6110 | goto out; | 6107 | goto out; |
6111 | if (decode_getfattr(xdr, res->f_attr, res->server, | 6108 | if (decode_getfattr(xdr, res->f_attr, res->server) != 0) |
6112 | !RPC_IS_ASYNC(rqstp->rq_task)) != 0) | ||
6113 | goto out; | 6109 | goto out; |
6114 | if (decode_restorefh(xdr) != 0) | 6110 | if (decode_restorefh(xdr) != 0) |
6115 | goto out; | 6111 | goto out; |
6116 | decode_getfattr(xdr, res->dir_attr, res->server, | 6112 | decode_getfattr(xdr, res->dir_attr, res->server); |
6117 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6118 | out: | 6113 | out: |
6119 | return status; | 6114 | return status; |
6120 | } | 6115 | } |
@@ -6162,8 +6157,7 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, | |||
6162 | status = decode_open(xdr, res); | 6157 | status = decode_open(xdr, res); |
6163 | if (status) | 6158 | if (status) |
6164 | goto out; | 6159 | goto out; |
6165 | decode_getfattr(xdr, res->f_attr, res->server, | 6160 | decode_getfattr(xdr, res->f_attr, res->server); |
6166 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6167 | out: | 6161 | out: |
6168 | return status; | 6162 | return status; |
6169 | } | 6163 | } |
@@ -6190,8 +6184,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, | |||
6190 | status = decode_setattr(xdr); | 6184 | status = decode_setattr(xdr); |
6191 | if (status) | 6185 | if (status) |
6192 | goto out; | 6186 | goto out; |
6193 | decode_getfattr(xdr, res->fattr, res->server, | 6187 | decode_getfattr(xdr, res->fattr, res->server); |
6194 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6195 | out: | 6188 | out: |
6196 | return status; | 6189 | return status; |
6197 | } | 6190 | } |
@@ -6371,8 +6364,7 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6371 | if (status) | 6364 | if (status) |
6372 | goto out; | 6365 | goto out; |
6373 | if (res->fattr) | 6366 | if (res->fattr) |
6374 | decode_getfattr(xdr, res->fattr, res->server, | 6367 | decode_getfattr(xdr, res->fattr, res->server); |
6375 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6376 | if (!status) | 6368 | if (!status) |
6377 | status = res->count; | 6369 | status = res->count; |
6378 | out: | 6370 | out: |
@@ -6401,8 +6393,7 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6401 | if (status) | 6393 | if (status) |
6402 | goto out; | 6394 | goto out; |
6403 | if (res->fattr) | 6395 | if (res->fattr) |
6404 | decode_getfattr(xdr, res->fattr, res->server, | 6396 | decode_getfattr(xdr, res->fattr, res->server); |
6405 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6406 | out: | 6397 | out: |
6407 | return status; | 6398 | return status; |
6408 | } | 6399 | } |
@@ -6561,8 +6552,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, | |||
6561 | status = decode_delegreturn(xdr); | 6552 | status = decode_delegreturn(xdr); |
6562 | if (status != 0) | 6553 | if (status != 0) |
6563 | goto out; | 6554 | goto out; |
6564 | decode_getfattr(xdr, res->fattr, res->server, | 6555 | decode_getfattr(xdr, res->fattr, res->server); |
6565 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6566 | out: | 6556 | out: |
6567 | return status; | 6557 | return status; |
6568 | } | 6558 | } |
@@ -6591,8 +6581,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, | |||
6591 | goto out; | 6581 | goto out; |
6592 | xdr_enter_page(xdr, PAGE_SIZE); | 6582 | xdr_enter_page(xdr, PAGE_SIZE); |
6593 | status = decode_getfattr(xdr, &res->fs_locations->fattr, | 6583 | status = decode_getfattr(xdr, &res->fs_locations->fattr, |
6594 | res->fs_locations->server, | 6584 | res->fs_locations->server); |
6595 | !RPC_IS_ASYNC(req->rq_task)); | ||
6596 | out: | 6585 | out: |
6597 | return status; | 6586 | return status; |
6598 | } | 6587 | } |
@@ -6841,8 +6830,7 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | |||
6841 | status = decode_layoutcommit(xdr, rqstp, res); | 6830 | status = decode_layoutcommit(xdr, rqstp, res); |
6842 | if (status) | 6831 | if (status) |
6843 | goto out; | 6832 | goto out; |
6844 | decode_getfattr(xdr, res->fattr, res->server, | 6833 | decode_getfattr(xdr, res->fattr, res->server); |
6845 | !RPC_IS_ASYNC(rqstp->rq_task)); | ||
6846 | out: | 6834 | out: |
6847 | return status; | 6835 | return status; |
6848 | } | 6836 | } |
@@ -6973,7 +6961,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
6973 | goto out_overflow; | 6961 | goto out_overflow; |
6974 | 6962 | ||
6975 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, | 6963 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, |
6976 | entry->server, 1) < 0) | 6964 | entry->server) < 0) |
6977 | goto out_overflow; | 6965 | goto out_overflow; |
6978 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | 6966 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
6979 | entry->ino = entry->fattr->mounted_on_fileid; | 6967 | entry->ino = entry->fattr->mounted_on_fileid; |
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h index ae7d6a380dae..308c18877018 100644 --- a/include/linux/nfs_idmap.h +++ b/include/linux/nfs_idmap.h | |||
@@ -66,6 +66,8 @@ struct idmap_msg { | |||
66 | /* Forward declaration to make this header independent of others */ | 66 | /* Forward declaration to make this header independent of others */ |
67 | struct nfs_client; | 67 | struct nfs_client; |
68 | struct nfs_server; | 68 | struct nfs_server; |
69 | struct nfs_fattr; | ||
70 | struct nfs4_string; | ||
69 | 71 | ||
70 | #ifdef CONFIG_NFS_USE_NEW_IDMAPPER | 72 | #ifdef CONFIG_NFS_USE_NEW_IDMAPPER |
71 | 73 | ||
@@ -97,6 +99,12 @@ void nfs_idmap_delete(struct nfs_client *); | |||
97 | 99 | ||
98 | #endif /* CONFIG_NFS_USE_NEW_IDMAPPER */ | 100 | #endif /* CONFIG_NFS_USE_NEW_IDMAPPER */ |
99 | 101 | ||
102 | void nfs_fattr_init_names(struct nfs_fattr *fattr, | ||
103 | struct nfs4_string *owner_name, | ||
104 | struct nfs4_string *group_name); | ||
105 | void nfs_fattr_free_names(struct nfs_fattr *); | ||
106 | void nfs_fattr_map_and_free_names(struct nfs_server *, struct nfs_fattr *); | ||
107 | |||
100 | int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *); | 108 | int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *); |
101 | int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *); | 109 | int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *); |
102 | int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t); | 110 | int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t); |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 6c898afe6095..a764cef06b73 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -18,6 +18,11 @@ | |||
18 | /* Forward declaration for NFS v3 */ | 18 | /* Forward declaration for NFS v3 */ |
19 | struct nfs4_secinfo_flavors; | 19 | struct nfs4_secinfo_flavors; |
20 | 20 | ||
21 | struct nfs4_string { | ||
22 | unsigned int len; | ||
23 | char *data; | ||
24 | }; | ||
25 | |||
21 | struct nfs_fsid { | 26 | struct nfs_fsid { |
22 | uint64_t major; | 27 | uint64_t major; |
23 | uint64_t minor; | 28 | uint64_t minor; |
@@ -61,6 +66,8 @@ struct nfs_fattr { | |||
61 | struct timespec pre_ctime; /* pre_op_attr.ctime */ | 66 | struct timespec pre_ctime; /* pre_op_attr.ctime */ |
62 | unsigned long time_start; | 67 | unsigned long time_start; |
63 | unsigned long gencount; | 68 | unsigned long gencount; |
69 | struct nfs4_string *owner_name; | ||
70 | struct nfs4_string *group_name; | ||
64 | }; | 71 | }; |
65 | 72 | ||
66 | #define NFS_ATTR_FATTR_TYPE (1U << 0) | 73 | #define NFS_ATTR_FATTR_TYPE (1U << 0) |
@@ -85,6 +92,8 @@ struct nfs_fattr { | |||
85 | #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ | 92 | #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ |
86 | #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ | 93 | #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ |
87 | #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) | 94 | #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) |
95 | #define NFS_ATTR_FATTR_OWNER_NAME (1U << 22) | ||
96 | #define NFS_ATTR_FATTR_GROUP_NAME (1U << 23) | ||
88 | 97 | ||
89 | #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | 98 | #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ |
90 | | NFS_ATTR_FATTR_MODE \ | 99 | | NFS_ATTR_FATTR_MODE \ |
@@ -324,6 +333,7 @@ struct nfs_openargs { | |||
324 | const struct qstr * name; | 333 | const struct qstr * name; |
325 | const struct nfs_server *server; /* Needed for ID mapping */ | 334 | const struct nfs_server *server; /* Needed for ID mapping */ |
326 | const u32 * bitmask; | 335 | const u32 * bitmask; |
336 | const u32 * dir_bitmask; | ||
327 | __u32 claim; | 337 | __u32 claim; |
328 | struct nfs4_sequence_args seq_args; | 338 | struct nfs4_sequence_args seq_args; |
329 | }; | 339 | }; |
@@ -342,6 +352,8 @@ struct nfs_openres { | |||
342 | __u32 do_recall; | 352 | __u32 do_recall; |
343 | __u64 maxsize; | 353 | __u64 maxsize; |
344 | __u32 attrset[NFS4_BITMAP_SIZE]; | 354 | __u32 attrset[NFS4_BITMAP_SIZE]; |
355 | struct nfs4_string *owner; | ||
356 | struct nfs4_string *group_owner; | ||
345 | struct nfs4_sequence_res seq_res; | 357 | struct nfs4_sequence_res seq_res; |
346 | }; | 358 | }; |
347 | 359 | ||
@@ -778,11 +790,6 @@ struct nfs3_getaclres { | |||
778 | struct posix_acl * acl_default; | 790 | struct posix_acl * acl_default; |
779 | }; | 791 | }; |
780 | 792 | ||
781 | struct nfs4_string { | ||
782 | unsigned int len; | ||
783 | char *data; | ||
784 | }; | ||
785 | |||
786 | #ifdef CONFIG_NFS_V4 | 793 | #ifdef CONFIG_NFS_V4 |
787 | 794 | ||
788 | typedef u64 clientid4; | 795 | typedef u64 clientid4; |