aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-09-29 11:48:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-06 22:17:38 -0400
commite72a1a8b3a5a2a0c034f9ad07ca34638fc3b0c33 (patch)
tree8e0f1c3833bf7b167b77ff1239fdab50a6f8e352
parentb8020eff7f827018ccd690a13e7da606302715a5 (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.c6
-rw-r--r--fs/kernfs/inode.c158
-rw-r--r--fs/kernfs/kernfs-internal.h7
-rw-r--r--fs/kernfs/mount.c1
-rw-r--r--fs/kernfs/symlink.c6
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
141static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, 141static 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
163int 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
203int 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
215ssize_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
228ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) 158ssize_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
310static 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
325static 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
341const struct xattr_handler kernfs_trusted_xattr_handler = {
342 .prefix = XATTR_TRUSTED_PREFIX,
343 .get = kernfs_xattr_get,
344 .set = kernfs_xattr_set,
345};
346
347static 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
378const 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
384const 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 */
79extern const struct xattr_handler *kernfs_xattr_handlers[];
79void kernfs_evict_inode(struct inode *inode); 80void kernfs_evict_inode(struct inode *inode);
80int kernfs_iop_permission(struct inode *inode, int mask); 81int kernfs_iop_permission(struct inode *inode, int mask);
81int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); 82int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr);
82int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, 83int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
83 struct kstat *stat); 84 struct kstat *stat);
84int kernfs_iop_setxattr(struct dentry *dentry, struct inode *inode,
85 const char *name, const void *value,
86 size_t size, int flags);
87int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
88ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
89 const char *name, void *buf, size_t size);
90ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); 85ssize_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
136const struct inode_operations kernfs_symlink_iops = { 136const 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,