diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-09-29 11:48:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-06 22:17:38 -0400 |
commit | e72a1a8b3a5a2a0c034f9ad07ca34638fc3b0c33 (patch) | |
tree | 8e0f1c3833bf7b167b77ff1239fdab50a6f8e352 | |
parent | b8020eff7f827018ccd690a13e7da606302715a5 (diff) |
kernfs: Switch to generic xattr handlers
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/kernfs/dir.c | 6 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 158 | ||||
-rw-r--r-- | fs/kernfs/kernfs-internal.h | 7 | ||||
-rw-r--r-- | fs/kernfs/mount.c | 1 | ||||
-rw-r--r-- | fs/kernfs/symlink.c | 6 |
5 files changed, 92 insertions, 86 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index e57174d43683..a6e430adf67d 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -1126,9 +1126,9 @@ const struct inode_operations kernfs_dir_iops = { | |||
1126 | .permission = kernfs_iop_permission, | 1126 | .permission = kernfs_iop_permission, |
1127 | .setattr = kernfs_iop_setattr, | 1127 | .setattr = kernfs_iop_setattr, |
1128 | .getattr = kernfs_iop_getattr, | 1128 | .getattr = kernfs_iop_getattr, |
1129 | .setxattr = kernfs_iop_setxattr, | 1129 | .setxattr = generic_setxattr, |
1130 | .removexattr = kernfs_iop_removexattr, | 1130 | .removexattr = generic_removexattr, |
1131 | .getxattr = kernfs_iop_getxattr, | 1131 | .getxattr = generic_getxattr, |
1132 | .listxattr = kernfs_iop_listxattr, | 1132 | .listxattr = kernfs_iop_listxattr, |
1133 | 1133 | ||
1134 | .mkdir = kernfs_iop_mkdir, | 1134 | .mkdir = kernfs_iop_mkdir, |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 63b925d5ba1e..6bc87547dede 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -28,9 +28,9 @@ static const struct inode_operations kernfs_iops = { | |||
28 | .permission = kernfs_iop_permission, | 28 | .permission = kernfs_iop_permission, |
29 | .setattr = kernfs_iop_setattr, | 29 | .setattr = kernfs_iop_setattr, |
30 | .getattr = kernfs_iop_getattr, | 30 | .getattr = kernfs_iop_getattr, |
31 | .setxattr = kernfs_iop_setxattr, | 31 | .setxattr = generic_setxattr, |
32 | .removexattr = kernfs_iop_removexattr, | 32 | .removexattr = generic_removexattr, |
33 | .getxattr = kernfs_iop_getxattr, | 33 | .getxattr = generic_getxattr, |
34 | .listxattr = kernfs_iop_listxattr, | 34 | .listxattr = kernfs_iop_listxattr, |
35 | }; | 35 | }; |
36 | 36 | ||
@@ -138,17 +138,12 @@ out: | |||
138 | return error; | 138 | return error; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, | 141 | static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, |
142 | u32 *secdata_len) | 142 | u32 *secdata_len) |
143 | { | 143 | { |
144 | struct kernfs_iattrs *attrs; | ||
145 | void *old_secdata; | 144 | void *old_secdata; |
146 | size_t old_secdata_len; | 145 | size_t old_secdata_len; |
147 | 146 | ||
148 | attrs = kernfs_iattrs(kn); | ||
149 | if (!attrs) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | old_secdata = attrs->ia_secdata; | 147 | old_secdata = attrs->ia_secdata; |
153 | old_secdata_len = attrs->ia_secdata_len; | 148 | old_secdata_len = attrs->ia_secdata_len; |
154 | 149 | ||
@@ -160,71 +155,6 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, | |||
160 | return 0; | 155 | return 0; |
161 | } | 156 | } |
162 | 157 | ||
163 | int kernfs_iop_setxattr(struct dentry *unused, struct inode *inode, | ||
164 | const char *name, const void *value, | ||
165 | size_t size, int flags) | ||
166 | { | ||
167 | struct kernfs_node *kn = inode->i_private; | ||
168 | struct kernfs_iattrs *attrs; | ||
169 | void *secdata; | ||
170 | int error; | ||
171 | u32 secdata_len = 0; | ||
172 | |||
173 | attrs = kernfs_iattrs(kn); | ||
174 | if (!attrs) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) { | ||
178 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | ||
179 | error = security_inode_setsecurity(inode, suffix, | ||
180 | value, size, flags); | ||
181 | if (error) | ||
182 | return error; | ||
183 | error = security_inode_getsecctx(inode, | ||
184 | &secdata, &secdata_len); | ||
185 | if (error) | ||
186 | return error; | ||
187 | |||
188 | mutex_lock(&kernfs_mutex); | ||
189 | error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); | ||
190 | mutex_unlock(&kernfs_mutex); | ||
191 | |||
192 | if (secdata) | ||
193 | security_release_secctx(secdata, secdata_len); | ||
194 | return error; | ||
195 | } else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { | ||
196 | return simple_xattr_set(&attrs->xattrs, name, value, size, | ||
197 | flags); | ||
198 | } | ||
199 | |||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | int kernfs_iop_removexattr(struct dentry *dentry, const char *name) | ||
204 | { | ||
205 | struct kernfs_node *kn = dentry->d_fsdata; | ||
206 | struct kernfs_iattrs *attrs; | ||
207 | |||
208 | attrs = kernfs_iattrs(kn); | ||
209 | if (!attrs) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE); | ||
213 | } | ||
214 | |||
215 | ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode, | ||
216 | const char *name, void *buf, size_t size) | ||
217 | { | ||
218 | struct kernfs_node *kn = inode->i_private; | ||
219 | struct kernfs_iattrs *attrs; | ||
220 | |||
221 | attrs = kernfs_iattrs(kn); | ||
222 | if (!attrs) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | return simple_xattr_get(&attrs->xattrs, name, buf, size); | ||
226 | } | ||
227 | |||
228 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) | 158 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) |
229 | { | 159 | { |
230 | struct kernfs_node *kn = dentry->d_fsdata; | 160 | struct kernfs_node *kn = dentry->d_fsdata; |
@@ -376,3 +306,83 @@ int kernfs_iop_permission(struct inode *inode, int mask) | |||
376 | 306 | ||
377 | return generic_permission(inode, mask); | 307 | return generic_permission(inode, mask); |
378 | } | 308 | } |
309 | |||
310 | static int kernfs_xattr_get(const struct xattr_handler *handler, | ||
311 | struct dentry *unused, struct inode *inode, | ||
312 | const char *suffix, void *value, size_t size) | ||
313 | { | ||
314 | const char *name = xattr_full_name(handler, suffix); | ||
315 | struct kernfs_node *kn = inode->i_private; | ||
316 | struct kernfs_iattrs *attrs; | ||
317 | |||
318 | attrs = kernfs_iattrs(kn); | ||
319 | if (!attrs) | ||
320 | return -ENOMEM; | ||
321 | |||
322 | return simple_xattr_get(&attrs->xattrs, name, value, size); | ||
323 | } | ||
324 | |||
325 | static int kernfs_xattr_set(const struct xattr_handler *handler, | ||
326 | struct dentry *unused, struct inode *inode, | ||
327 | const char *suffix, const void *value, | ||
328 | size_t size, int flags) | ||
329 | { | ||
330 | const char *name = xattr_full_name(handler, suffix); | ||
331 | struct kernfs_node *kn = inode->i_private; | ||
332 | struct kernfs_iattrs *attrs; | ||
333 | |||
334 | attrs = kernfs_iattrs(kn); | ||
335 | if (!attrs) | ||
336 | return -ENOMEM; | ||
337 | |||
338 | return simple_xattr_set(&attrs->xattrs, name, value, size, flags); | ||
339 | } | ||
340 | |||
341 | const struct xattr_handler kernfs_trusted_xattr_handler = { | ||
342 | .prefix = XATTR_TRUSTED_PREFIX, | ||
343 | .get = kernfs_xattr_get, | ||
344 | .set = kernfs_xattr_set, | ||
345 | }; | ||
346 | |||
347 | static int kernfs_security_xattr_set(const struct xattr_handler *handler, | ||
348 | struct dentry *unused, struct inode *inode, | ||
349 | const char *suffix, const void *value, | ||
350 | size_t size, int flags) | ||
351 | { | ||
352 | struct kernfs_node *kn = inode->i_private; | ||
353 | struct kernfs_iattrs *attrs; | ||
354 | void *secdata; | ||
355 | u32 secdata_len = 0; | ||
356 | int error; | ||
357 | |||
358 | attrs = kernfs_iattrs(kn); | ||
359 | if (!attrs) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | error = security_inode_setsecurity(inode, suffix, value, size, flags); | ||
363 | if (error) | ||
364 | return error; | ||
365 | error = security_inode_getsecctx(inode, &secdata, &secdata_len); | ||
366 | if (error) | ||
367 | return error; | ||
368 | |||
369 | mutex_lock(&kernfs_mutex); | ||
370 | error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); | ||
371 | mutex_unlock(&kernfs_mutex); | ||
372 | |||
373 | if (secdata) | ||
374 | security_release_secctx(secdata, secdata_len); | ||
375 | return error; | ||
376 | } | ||
377 | |||
378 | const struct xattr_handler kernfs_security_xattr_handler = { | ||
379 | .prefix = XATTR_SECURITY_PREFIX, | ||
380 | .get = kernfs_xattr_get, | ||
381 | .set = kernfs_security_xattr_set, | ||
382 | }; | ||
383 | |||
384 | const struct xattr_handler *kernfs_xattr_handlers[] = { | ||
385 | &kernfs_trusted_xattr_handler, | ||
386 | &kernfs_security_xattr_handler, | ||
387 | NULL | ||
388 | }; | ||
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 37159235ac10..bfd551bbf231 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h | |||
@@ -76,17 +76,12 @@ extern struct kmem_cache *kernfs_node_cache; | |||
76 | /* | 76 | /* |
77 | * inode.c | 77 | * inode.c |
78 | */ | 78 | */ |
79 | extern const struct xattr_handler *kernfs_xattr_handlers[]; | ||
79 | void kernfs_evict_inode(struct inode *inode); | 80 | void kernfs_evict_inode(struct inode *inode); |
80 | int kernfs_iop_permission(struct inode *inode, int mask); | 81 | int kernfs_iop_permission(struct inode *inode, int mask); |
81 | int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); | 82 | int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); |
82 | int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, | 83 | int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, |
83 | struct kstat *stat); | 84 | struct kstat *stat); |
84 | int kernfs_iop_setxattr(struct dentry *dentry, struct inode *inode, | ||
85 | const char *name, const void *value, | ||
86 | size_t size, int flags); | ||
87 | int kernfs_iop_removexattr(struct dentry *dentry, const char *name); | ||
88 | ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode, | ||
89 | const char *name, void *buf, size_t size); | ||
90 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); | 85 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); |
91 | 86 | ||
92 | /* | 87 | /* |
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index b3d73ad52b22..d5b149a45be1 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c | |||
@@ -158,6 +158,7 @@ static int kernfs_fill_super(struct super_block *sb, unsigned long magic) | |||
158 | sb->s_blocksize_bits = PAGE_SHIFT; | 158 | sb->s_blocksize_bits = PAGE_SHIFT; |
159 | sb->s_magic = magic; | 159 | sb->s_magic = magic; |
160 | sb->s_op = &kernfs_sops; | 160 | sb->s_op = &kernfs_sops; |
161 | sb->s_xattr = kernfs_xattr_handlers; | ||
161 | sb->s_time_gran = 1; | 162 | sb->s_time_gran = 1; |
162 | 163 | ||
163 | /* get root inode, initialize and unlock it */ | 164 | /* get root inode, initialize and unlock it */ |
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 117b8b3416f9..549a14c7c50a 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c | |||
@@ -134,9 +134,9 @@ static const char *kernfs_iop_get_link(struct dentry *dentry, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | const struct inode_operations kernfs_symlink_iops = { | 136 | const struct inode_operations kernfs_symlink_iops = { |
137 | .setxattr = kernfs_iop_setxattr, | 137 | .setxattr = generic_setxattr, |
138 | .removexattr = kernfs_iop_removexattr, | 138 | .removexattr = generic_removexattr, |
139 | .getxattr = kernfs_iop_getxattr, | 139 | .getxattr = generic_getxattr, |
140 | .listxattr = kernfs_iop_listxattr, | 140 | .listxattr = kernfs_iop_listxattr, |
141 | .readlink = generic_readlink, | 141 | .readlink = generic_readlink, |
142 | .get_link = kernfs_iop_get_link, | 142 | .get_link = kernfs_iop_get_link, |