1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * fs/kernfs/mount.c - kernfs mount implementation
4 *
5 * Copyright (c) 2001-3 Patrick Mochel
6 * Copyright (c) 2007 SUSE Linux Products GmbH
7 * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
8 */
9
10#include <linux/fs.h>
11#include <linux/mount.h>
12#include <linux/init.h>
13#include <linux/magic.h>
14#include <linux/slab.h>
15#include <linux/pagemap.h>
16#include <linux/namei.h>
17#include <linux/seq_file.h>
18#include <linux/exportfs.h>
19#include <linux/uuid.h>
20#include <linux/statfs.h>
21
22#include "kernfs-internal.h"
23
24struct kmem_cache *kernfs_node_cache __ro_after_init;
25struct kmem_cache *kernfs_iattrs_cache __ro_after_init;
26struct kernfs_global_locks *kernfs_locks __ro_after_init;
27
28static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry)
29{
30 struct kernfs_root *root = kernfs_root(kn: kernfs_dentry_node(dentry));
31 struct kernfs_syscall_ops *scops = root->syscall_ops;
32
33 if (scops && scops->show_options)
34 return scops->show_options(sf, root);
35 return 0;
36}
37
38static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)
39{
40 struct kernfs_node *node = kernfs_dentry_node(dentry);
41 struct kernfs_root *root = kernfs_root(kn: node);
42 struct kernfs_syscall_ops *scops = root->syscall_ops;
43
44 if (scops && scops->show_path)
45 return scops->show_path(sf, node, root);
46
47 seq_dentry(sf, dentry, " \t\n\\");
48 return 0;
49}
50
51static int kernfs_statfs(struct dentry *dentry, struct kstatfs *buf)
52{
53 simple_statfs(dentry, buf);
54 buf->f_fsid = uuid_to_fsid(uuid: dentry->d_sb->s_uuid.b);
55 return 0;
56}
57
58const struct super_operations kernfs_sops = {
59 .statfs = kernfs_statfs,
60 .drop_inode = generic_delete_inode,
61 .evict_inode = kernfs_evict_inode,
62
63 .show_options = kernfs_sop_show_options,
64 .show_path = kernfs_sop_show_path,
65
66 /*
67 * sysfs is built on top of kernfs and sysfs provides the power
68 * management infrastructure to support suspend/hibernate by
69 * writing to various files in /sys/power/. As filesystems may
70 * be automatically frozen during suspend/hibernate implementing
71 * freeze/thaw support for kernfs generically will cause
72 * deadlocks as the suspending/hibernation initiating task will
73 * hold a VFS lock that it will then wait upon to be released.
74 * If freeze/thaw for kernfs is needed talk to the VFS.
75 */
76 .freeze_fs = NULL,
77 .unfreeze_fs = NULL,
78 .freeze_super = NULL,
79 .thaw_super = NULL,
80};
81
82static int kernfs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
83 struct inode *parent)
84{
85 struct kernfs_node *kn = inode->i_private;
86
87 if (*max_len < 2) {
88 *max_len = 2;
89 return FILEID_INVALID;
90 }
91
92 *max_len = 2;
93 *(u64 *)fh = kn->id;
94 return FILEID_KERNFS;
95}
96
97static struct dentry *__kernfs_fh_to_dentry(struct super_block *sb,
98 struct fid *fid, int fh_len,
99 int fh_type, bool get_parent)
100{
101 struct kernfs_super_info *info = kernfs_info(sb);
102 struct kernfs_node *kn;
103 struct inode *inode;
104 u64 id;
105
106 if (fh_len < 2)
107 return NULL;
108
109 switch (fh_type) {
110 case FILEID_KERNFS:
111 id = *(u64 *)fid;
112 break;
113 case FILEID_INO32_GEN:
114 case FILEID_INO32_GEN_PARENT:
115 /*
116 * blk_log_action() exposes "LOW32,HIGH32" pair without
117 * type and userland can call us with generic fid
118 * constructed from them. Combine it back to ID. See
119 * blk_log_action().
120 */
121 id = ((u64)fid->i32.gen << 32) | fid->i32.ino;
122 break;
123 default:
124 return NULL;
125 }
126
127 kn = kernfs_find_and_get_node_by_id(root: info->root, id);
128 if (!kn)
129 return ERR_PTR(error: -ESTALE);
130
131 if (get_parent) {
132 struct kernfs_node *parent;
133
134 parent = kernfs_get_parent(kn);
135 kernfs_put(kn);
136 kn = parent;
137 if (!kn)
138 return ERR_PTR(error: -ESTALE);
139 }
140
141 inode = kernfs_get_inode(sb, kn);
142 kernfs_put(kn);
143 return d_obtain_alias(inode);
144}
145
146static struct dentry *kernfs_fh_to_dentry(struct super_block *sb,
147 struct fid *fid, int fh_len,
148 int fh_type)
149{
150 return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, get_parent: false);
151}
152
153static struct dentry *kernfs_fh_to_parent(struct super_block *sb,
154 struct fid *fid, int fh_len,
155 int fh_type)
156{
157 return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, get_parent: true);
158}
159
160static struct dentry *kernfs_get_parent_dentry(struct dentry *child)
161{
162 struct kernfs_node *kn = kernfs_dentry_node(dentry: child);
163 struct kernfs_root *root = kernfs_root(kn);
164
165 guard(rwsem_read)(T: &root->kernfs_rwsem);
166 return d_obtain_alias(kernfs_get_inode(sb: child->d_sb, kn: kernfs_parent(kn)));
167}
168
169static const struct export_operations kernfs_export_ops = {
170 .encode_fh = kernfs_encode_fh,
171 .fh_to_dentry = kernfs_fh_to_dentry,
172 .fh_to_parent = kernfs_fh_to_parent,
173 .get_parent = kernfs_get_parent_dentry,
174};
175
176/**
177 * kernfs_root_from_sb - determine kernfs_root associated with a super_block
178 * @sb: the super_block in question
179 *
180 * Return: the kernfs_root associated with @sb. If @sb is not a kernfs one,
181 * %NULL is returned.
182 */
183struct kernfs_root *kernfs_root_from_sb(struct super_block *sb)
184{
185 if (sb->s_op == &kernfs_sops)
186 return kernfs_info(sb)->root;
187 return NULL;
188}
189
190/*
191 * find the next ancestor in the path down to @child, where @parent was the
192 * ancestor whose descendant we want to find.
193 *
194 * Say the path is /a/b/c/d. @child is d, @parent is %NULL. We return the root
195 * node. If @parent is b, then we return the node for c.
196 * Passing in d as @parent is not ok.
197 */
198static struct kernfs_node *find_next_ancestor(struct kernfs_node *child,
199 struct kernfs_node *parent)
200{
201 if (child == parent) {
202 pr_crit_once("BUG in find_next_ancestor: called with parent == child");
203 return NULL;
204 }
205
206 while (kernfs_parent(kn: child) != parent) {
207 child = kernfs_parent(kn: child);
208 if (!child)
209 return NULL;
210 }
211
212 return child;
213}
214
215/**
216 * kernfs_node_dentry - get a dentry for the given kernfs_node
217 * @kn: kernfs_node for which a dentry is needed
218 * @sb: the kernfs super_block
219 *
220 * Return: the dentry pointer
221 */
222struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
223 struct super_block *sb)
224{
225 struct dentry *dentry;
226 struct kernfs_node *knparent;
227 struct kernfs_root *root;
228
229 BUG_ON(sb->s_op != &kernfs_sops);
230
231 dentry = dget(dentry: sb->s_root);
232
233 /* Check if this is the root kernfs_node */
234 if (!rcu_access_pointer(kn->__parent))
235 return dentry;
236
237 root = kernfs_root(kn);
238 /*
239 * As long as kn is valid, its parent can not vanish. This is cgroup's
240 * kn so it can't have its parent replaced. Therefore it is safe to use
241 * the ancestor node outside of the RCU or locked section.
242 */
243 if (WARN_ON_ONCE(!(root->flags & KERNFS_ROOT_INVARIANT_PARENT)))
244 return ERR_PTR(error: -EINVAL);
245 scoped_guard(rcu) {
246 knparent = find_next_ancestor(child: kn, NULL);
247 }
248 if (WARN_ON(!knparent)) {
249 dput(dentry);
250 return ERR_PTR(error: -EINVAL);
251 }
252
253 do {
254 struct dentry *dtmp;
255 struct kernfs_node *kntmp;
256 const char *name;
257
258 if (kn == knparent)
259 return dentry;
260
261 scoped_guard(rwsem_read, &root->kernfs_rwsem) {
262 kntmp = find_next_ancestor(child: kn, parent: knparent);
263 if (WARN_ON(!kntmp)) {
264 dput(dentry);
265 return ERR_PTR(error: -EINVAL);
266 }
267 name = kstrdup(s: kernfs_rcu_name(kn: kntmp), GFP_KERNEL);
268 }
269 if (!name) {
270 dput(dentry);
271 return ERR_PTR(error: -ENOMEM);
272 }
273 dtmp = lookup_noperm_positive_unlocked(&QSTR(name), dentry);
274 dput(dentry);
275 kfree(objp: name);
276 if (IS_ERR(ptr: dtmp))
277 return dtmp;
278 knparent = kntmp;
279 dentry = dtmp;
280 } while (true);
281}
282
283static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
284{
285 struct kernfs_super_info *info = kernfs_info(sb);
286 struct kernfs_root *kf_root = kfc->root;
287 struct inode *inode;
288 struct dentry *root;
289
290 info->sb = sb;
291 /* Userspace would break if executables or devices appear on sysfs */
292 sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
293 sb->s_blocksize = PAGE_SIZE;
294 sb->s_blocksize_bits = PAGE_SHIFT;
295 sb->s_magic = kfc->magic;
296 sb->s_op = &kernfs_sops;
297 sb->s_xattr = kernfs_xattr_handlers;
298 if (info->root->flags & KERNFS_ROOT_SUPPORT_EXPORTOP)
299 sb->s_export_op = &kernfs_export_ops;
300 sb->s_time_gran = 1;
301
302 /* sysfs dentries and inodes don't require IO to create */
303 sb->s_shrink->seeks = 0;
304
305 /* get root inode, initialize and unlock it */
306 down_read(sem: &kf_root->kernfs_rwsem);
307 inode = kernfs_get_inode(sb, kn: info->root->kn);
308 up_read(sem: &kf_root->kernfs_rwsem);
309 if (!inode) {
310 pr_debug("kernfs: could not get root inode\n");
311 return -ENOMEM;
312 }
313
314 /* instantiate and link root dentry */
315 root = d_make_root(inode);
316 if (!root) {
317 pr_debug("%s: could not get root dentry!\n", __func__);
318 return -ENOMEM;
319 }
320 sb->s_root = root;
321 sb->s_d_op = &kernfs_dops;
322 return 0;
323}
324
325static int kernfs_test_super(struct super_block *sb, struct fs_context *fc)
326{
327 struct kernfs_super_info *sb_info = kernfs_info(sb);
328 struct kernfs_super_info *info = fc->s_fs_info;
329
330 return sb_info->root == info->root && sb_info->ns == info->ns;
331}
332
333static int kernfs_set_super(struct super_block *sb, struct fs_context *fc)
334{
335 struct kernfs_fs_context *kfc = fc->fs_private;
336
337 kfc->ns_tag = NULL;
338 return set_anon_super_fc(s: sb, fc);
339}
340
341/**
342 * kernfs_super_ns - determine the namespace tag of a kernfs super_block
343 * @sb: super_block of interest
344 *
345 * Return: the namespace tag associated with kernfs super_block @sb.
346 */
347const void *kernfs_super_ns(struct super_block *sb)
348{
349 struct kernfs_super_info *info = kernfs_info(sb);
350
351 return info->ns;
352}
353
354/**
355 * kernfs_get_tree - kernfs filesystem access/retrieval helper
356 * @fc: The filesystem context.
357 *
358 * This is to be called from each kernfs user's fs_context->ops->get_tree()
359 * implementation, which should set the specified ->@fs_type and ->@flags, and
360 * specify the hierarchy and namespace tag to mount via ->@root and ->@ns,
361 * respectively.
362 *
363 * Return: %0 on success, -errno on failure.
364 */
365int kernfs_get_tree(struct fs_context *fc)
366{
367 struct kernfs_fs_context *kfc = fc->fs_private;
368 struct super_block *sb;
369 struct kernfs_super_info *info;
370 int error;
371
372 info = kzalloc(sizeof(*info), GFP_KERNEL);
373 if (!info)
374 return -ENOMEM;
375
376 info->root = kfc->root;
377 info->ns = kfc->ns_tag;
378 INIT_LIST_HEAD(list: &info->node);
379
380 fc->s_fs_info = info;
381 sb = sget_fc(fc, test: kernfs_test_super, set: kernfs_set_super);
382 if (IS_ERR(ptr: sb))
383 return PTR_ERR(ptr: sb);
384
385 if (!sb->s_root) {
386 struct kernfs_super_info *info = kernfs_info(sb);
387 struct kernfs_root *root = kfc->root;
388
389 kfc->new_sb_created = true;
390
391 error = kernfs_fill_super(sb, kfc);
392 if (error) {
393 deactivate_locked_super(sb);
394 return error;
395 }
396 sb->s_flags |= SB_ACTIVE;
397
398 uuid_t uuid;
399 uuid_gen(u: &uuid);
400 super_set_uuid(sb, uuid: uuid.b, len: sizeof(uuid));
401
402 down_write(sem: &root->kernfs_supers_rwsem);
403 list_add(new: &info->node, head: &info->root->supers);
404 up_write(sem: &root->kernfs_supers_rwsem);
405 }
406
407 fc->root = dget(dentry: sb->s_root);
408 return 0;
409}
410
411void kernfs_free_fs_context(struct fs_context *fc)
412{
413 /* Note that we don't deal with kfc->ns_tag here. */
414 kfree(objp: fc->s_fs_info);
415 fc->s_fs_info = NULL;
416}
417
418/**
419 * kernfs_kill_sb - kill_sb for kernfs
420 * @sb: super_block being killed
421 *
422 * This can be used directly for file_system_type->kill_sb(). If a kernfs
423 * user needs extra cleanup, it can implement its own kill_sb() and call
424 * this function at the end.
425 */
426void kernfs_kill_sb(struct super_block *sb)
427{
428 struct kernfs_super_info *info = kernfs_info(sb);
429 struct kernfs_root *root = info->root;
430
431 down_write(sem: &root->kernfs_supers_rwsem);
432 list_del(entry: &info->node);
433 up_write(sem: &root->kernfs_supers_rwsem);
434
435 /*
436 * Remove the superblock from fs_supers/s_instances
437 * so we can't find it, before freeing kernfs_super_info.
438 */
439 kill_anon_super(sb);
440 kfree(objp: info);
441}
442
443static void __init kernfs_mutex_init(void)
444{
445 int count;
446
447 for (count = 0; count < NR_KERNFS_LOCKS; count++)
448 mutex_init(&kernfs_locks->open_file_mutex[count]);
449}
450
451static void __init kernfs_lock_init(void)
452{
453 kernfs_locks = kmalloc(sizeof(struct kernfs_global_locks), GFP_KERNEL);
454 WARN_ON(!kernfs_locks);
455
456 kernfs_mutex_init();
457}
458
459void __init kernfs_init(void)
460{
461 kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
462 sizeof(struct kernfs_node),
463 0, SLAB_PANIC, NULL);
464
465 /* Creates slab cache for kernfs inode attributes */
466 kernfs_iattrs_cache = kmem_cache_create("kernfs_iattrs_cache",
467 sizeof(struct kernfs_iattrs),
468 0, SLAB_PANIC, NULL);
469
470 kernfs_lock_init();
471}
472

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/fs/kernfs/mount.c