Branch data Line data Source code
1 : : /*
2 : : * fs/kernfs/dir.c - kernfs directory implementation
3 : : *
4 : : * Copyright (c) 2001-3 Patrick Mochel
5 : : * Copyright (c) 2007 SUSE Linux Products GmbH
6 : : * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
7 : : *
8 : : * This file is released under the GPLv2.
9 : : */
10 : :
11 : : #include <linux/fs.h>
12 : : #include <linux/namei.h>
13 : : #include <linux/idr.h>
14 : : #include <linux/slab.h>
15 : : #include <linux/security.h>
16 : : #include <linux/hash.h>
17 : :
18 : : #include "kernfs-internal.h"
19 : :
20 : : DEFINE_MUTEX(kernfs_mutex);
21 : :
22 : : #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
23 : :
24 : : /**
25 : : * kernfs_name_hash
26 : : * @name: Null terminated string to hash
27 : : * @ns: Namespace tag to hash
28 : : *
29 : : * Returns 31 bit hash of ns + name (so it fits in an off_t )
30 : : */
31 : 0 : static unsigned int kernfs_name_hash(const char *name, const void *ns)
32 : : {
33 : : unsigned long hash = init_name_hash();
34 : 12093 : unsigned int len = strlen(name);
35 [ + + ]: 106901 : while (len--)
36 : 94808 : hash = partial_name_hash(*name++, hash);
37 : 12093 : hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
38 : 12093 : hash &= 0x7fffffffU;
39 : : /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
40 [ - + ]: 12093 : if (hash < 1)
41 : 0 : hash += 2;
42 [ - - ]: 12093 : if (hash >= INT_MAX)
43 : : hash = INT_MAX - 1;
44 : 0 : return hash;
45 : : }
46 : :
47 : 0 : static int kernfs_name_compare(unsigned int hash, const char *name,
48 : : const void *ns, const struct kernfs_node *kn)
49 : : {
50 [ + + ]: 36393 : if (hash != kn->hash)
51 : 34844 : return hash - kn->hash;
52 [ - + ]: 1549 : if (ns != kn->ns)
53 : 0 : return ns - kn->ns;
54 : 1549 : return strcmp(name, kn->name);
55 : : }
56 : :
57 : : static int kernfs_sd_compare(const struct kernfs_node *left,
58 : : const struct kernfs_node *right)
59 : : {
60 : 6326 : return kernfs_name_compare(left->hash, left->name, left->ns, right);
61 : : }
62 : :
63 : : /**
64 : : * kernfs_link_sibling - link kernfs_node into sibling rbtree
65 : : * @kn: kernfs_node of interest
66 : : *
67 : : * Link @kn into its sibling rbtree which starts from
68 : : * @kn->parent->dir.children.
69 : : *
70 : : * Locking:
71 : : * mutex_lock(kernfs_mutex)
72 : : *
73 : : * RETURNS:
74 : : * 0 on susccess -EEXIST on failure.
75 : : */
76 : 0 : static int kernfs_link_sibling(struct kernfs_node *kn)
77 : : {
78 : 1816 : struct rb_node **node = &kn->parent->dir.children.rb_node;
79 : : struct rb_node *parent = NULL;
80 : :
81 [ + + ]: 1816 : if (kernfs_type(kn) == KERNFS_DIR)
82 : 1816 : kn->parent->dir.subdirs++;
83 : :
84 [ + + ]: 8142 : while (*node) {
85 : : struct kernfs_node *pos;
86 : : int result;
87 : :
88 : 6326 : pos = rb_to_kn(*node);
89 : : parent = *node;
90 : : result = kernfs_sd_compare(kn, pos);
91 [ + + ]: 8142 : if (result < 0)
92 : 2582 : node = &pos->rb.rb_left;
93 [ + - ]: 3744 : else if (result > 0)
94 : 6326 : node = &pos->rb.rb_right;
95 : : else
96 : : return -EEXIST;
97 : : }
98 : : /* add new node and rebalance the tree */
99 : 1816 : rb_link_node(&kn->rb, parent, node);
100 : 1816 : rb_insert_color(&kn->rb, &kn->parent->dir.children);
101 : 1816 : return 0;
102 : : }
103 : :
104 : : /**
105 : : * kernfs_unlink_sibling - unlink kernfs_node from sibling rbtree
106 : : * @kn: kernfs_node of interest
107 : : *
108 : : * Unlink @kn from its sibling rbtree which starts from
109 : : * kn->parent->dir.children.
110 : : *
111 : : * Locking:
112 : : * mutex_lock(kernfs_mutex)
113 : : */
114 : 0 : static void kernfs_unlink_sibling(struct kernfs_node *kn)
115 : : {
116 [ + + ]: 1016 : if (kernfs_type(kn) == KERNFS_DIR)
117 : 156 : kn->parent->dir.subdirs--;
118 : :
119 : 1016 : rb_erase(&kn->rb, &kn->parent->dir.children);
120 : 1016 : }
121 : :
122 : : /**
123 : : * kernfs_get_active - get an active reference to kernfs_node
124 : : * @kn: kernfs_node to get an active reference to
125 : : *
126 : : * Get an active reference of @kn. This function is noop if @kn
127 : : * is NULL.
128 : : *
129 : : * RETURNS:
130 : : * Pointer to @kn on success, NULL on failure.
131 : : */
132 : 0 : struct kernfs_node *kernfs_get_active(struct kernfs_node *kn)
133 : : {
134 [ + ]: 4199 : if (unlikely(!kn))
135 : : return NULL;
136 : :
137 [ + ]: 8397 : if (!atomic_inc_unless_negative(&kn->active))
138 : : return NULL;
139 : :
140 : : if (kn->flags & KERNFS_LOCKDEP)
141 : : rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_);
142 : 4200 : return kn;
143 : : }
144 : :
145 : : /**
146 : : * kernfs_put_active - put an active reference to kernfs_node
147 : : * @kn: kernfs_node to put an active reference to
148 : : *
149 : : * Put an active reference to @kn. This function is noop if @kn
150 : : * is NULL.
151 : : */
152 : 0 : void kernfs_put_active(struct kernfs_node *kn)
153 : : {
154 : : int v;
155 : :
156 [ + - ]: 4200 : if (unlikely(!kn))
157 : : return;
158 : :
159 : : if (kn->flags & KERNFS_LOCKDEP)
160 : : rwsem_release(&kn->dep_map, 1, _RET_IP_);
161 : 4200 : v = atomic_dec_return(&kn->active);
162 [ - + ]: 4197 : if (likely(v != KN_DEACTIVATED_BIAS))
163 : : return;
164 : :
165 : : /*
166 : : * atomic_dec_return() is a mb(), we'll always see the updated
167 : : * kn->u.completion.
168 : : */
169 : 0 : complete(kn->u.completion);
170 : : }
171 : :
172 : : /**
173 : : * kernfs_deactivate - deactivate kernfs_node
174 : : * @kn: kernfs_node to deactivate
175 : : *
176 : : * Deny new active references and drain existing ones.
177 : : */
178 : 0 : static void kernfs_deactivate(struct kernfs_node *kn)
179 : : {
180 : 987 : DECLARE_COMPLETION_ONSTACK(wait);
181 : : int v;
182 : :
183 [ - + ]: 987 : BUG_ON(!(kn->flags & KERNFS_REMOVED));
184 : :
185 [ + + ]: 987 : if (!(kernfs_type(kn) & KERNFS_ACTIVE_REF))
186 : 256 : return;
187 : :
188 : 731 : kn->u.completion = (void *)&wait;
189 : :
190 : : if (kn->flags & KERNFS_LOCKDEP)
191 : : rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_);
192 : : /* atomic_add_return() is a mb(), put_active() will always see
193 : : * the updated kn->u.completion.
194 : : */
195 : 731 : v = atomic_add_return(KN_DEACTIVATED_BIAS, &kn->active);
196 : :
197 [ - + ]: 731 : if (v != KN_DEACTIVATED_BIAS) {
198 : : if (kn->flags & KERNFS_LOCKDEP)
199 : : lock_contended(&kn->dep_map, _RET_IP_);
200 : 731 : wait_for_completion(&wait);
201 : : }
202 : :
203 : : if (kn->flags & KERNFS_LOCKDEP) {
204 : : lock_acquired(&kn->dep_map, _RET_IP_);
205 : : rwsem_release(&kn->dep_map, 1, _RET_IP_);
206 : : }
207 : : }
208 : :
209 : : /**
210 : : * kernfs_get - get a reference count on a kernfs_node
211 : : * @kn: the target kernfs_node
212 : : */
213 : 0 : void kernfs_get(struct kernfs_node *kn)
214 : : {
215 [ + - ]: 4745 : if (kn) {
216 [ - + ]: 4745 : WARN_ON(!atomic_read(&kn->count));
217 : 4745 : atomic_inc(&kn->count);
218 : : }
219 : 4745 : }
220 : : EXPORT_SYMBOL_GPL(kernfs_get);
221 : :
222 : : /**
223 : : * kernfs_put - put a reference count on a kernfs_node
224 : : * @kn: the target kernfs_node
225 : : *
226 : : * Put a reference count of @kn and destroy it if it reached zero.
227 : : */
228 : 0 : void kernfs_put(struct kernfs_node *kn)
229 : : {
230 : : struct kernfs_node *parent;
231 : : struct kernfs_root *root;
232 : :
233 [ + + + + ]: 29820 : if (!kn || !atomic_dec_and_test(&kn->count))
234 : 19210 : return;
235 : : root = kernfs_root(kn);
236 : : repeat:
237 : : /* Moving/renaming is always done while holding reference.
238 : : * kn->parent won't change beneath us.
239 : : */
240 : 987 : parent = kn->parent;
241 : :
242 [ - + ][ # # ]: 987 : WARN(!(kn->flags & KERNFS_REMOVED), "kernfs: free using entry: %s/%s\n",
243 : : parent ? parent->name : "", kn->name);
244 : :
245 [ + + ]: 20197 : if (kernfs_type(kn) == KERNFS_LINK)
246 : 129 : kernfs_put(kn->symlink.target_kn);
247 [ + + ]: 987 : if (!(kn->flags & KERNFS_STATIC_NAME))
248 : 256 : kfree(kn->name);
249 [ + + ]: 987 : if (kn->iattr) {
250 [ - + ]: 2 : if (kn->iattr->ia_secdata)
251 : 0 : security_release_secctx(kn->iattr->ia_secdata,
252 : : kn->iattr->ia_secdata_len);
253 : 2 : simple_xattrs_free(&kn->iattr->xattrs);
254 : : }
255 : 987 : kfree(kn->iattr);
256 : 987 : ida_simple_remove(&root->ino_ida, kn->ino);
257 : 987 : kmem_cache_free(kernfs_node_cache, kn);
258 : :
259 : : kn = parent;
260 [ + - ]: 987 : if (kn) {
261 [ + + ]: 987 : if (atomic_dec_and_test(&kn->count))
262 : : goto repeat;
263 : : } else {
264 : : /* just released the root kn, free @root too */
265 : 0 : ida_destroy(&root->ino_ida);
266 : 0 : kfree(root);
267 : : }
268 : : }
269 : : EXPORT_SYMBOL_GPL(kernfs_put);
270 : :
271 : 0 : static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
272 : : {
273 : : struct kernfs_node *kn;
274 : :
275 [ + ]: 53452 : if (flags & LOOKUP_RCU)
276 : : return -ECHILD;
277 : :
278 : : /* Always perform fresh lookup for negatives */
279 [ + - ]: 53453 : if (!dentry->d_inode)
280 : : goto out_bad_unlocked;
281 : :
282 : 53453 : kn = dentry->d_fsdata;
283 : 53453 : mutex_lock(&kernfs_mutex);
284 : :
285 : : /* The kernfs node has been deleted */
286 [ + + ]: 53453 : if (kn->flags & KERNFS_REMOVED)
287 : : goto out_bad;
288 : :
289 : : /* The kernfs node has been moved? */
290 [ + - ]: 53436 : if (dentry->d_parent->d_fsdata != kn->parent)
291 : : goto out_bad;
292 : :
293 : : /* The kernfs node has been renamed */
294 [ + - ]: 53436 : if (strcmp(dentry->d_name.name, kn->name) != 0)
295 : : goto out_bad;
296 : :
297 : : /* The kernfs node has been moved to a different namespace */
298 [ + - ][ - + ]: 53436 : if (kn->parent && kernfs_ns_enabled(kn->parent) &&
[ # # ]
299 : 0 : kernfs_info(dentry->d_sb)->ns != kn->ns)
300 : : goto out_bad;
301 : :
302 : 53436 : mutex_unlock(&kernfs_mutex);
303 : : out_valid:
304 : : return 1;
305 : : out_bad:
306 : 17 : mutex_unlock(&kernfs_mutex);
307 : : out_bad_unlocked:
308 : : /*
309 : : * @dentry doesn't match the underlying kernfs node, drop the
310 : : * dentry and force lookup. If we have submounts we must allow the
311 : : * vfs caches to lie about the state of the filesystem to prevent
312 : : * leaks and other nasty things, so use check_submounts_and_drop()
313 : : * instead of d_drop().
314 : : */
315 [ - + ]: 17 : if (check_submounts_and_drop(dentry) != 0)
316 : : goto out_valid;
317 : :
318 : : return 0;
319 : : }
320 : :
321 : 0 : static void kernfs_dop_release(struct dentry *dentry)
322 : : {
323 : 12654 : kernfs_put(dentry->d_fsdata);
324 : 12654 : }
325 : :
326 : : const struct dentry_operations kernfs_dops = {
327 : : .d_revalidate = kernfs_dop_revalidate,
328 : : .d_release = kernfs_dop_release,
329 : : };
330 : :
331 : 0 : static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
332 : : const char *name, umode_t mode,
333 : : unsigned flags)
334 : : {
335 : : char *dup_name = NULL;
336 : : struct kernfs_node *kn;
337 : : int ret;
338 : :
339 [ + + ]: 1787 : if (!(flags & KERNFS_STATIC_NAME)) {
340 : 821 : name = dup_name = kstrdup(name, GFP_KERNEL);
341 [ + - ]: 821 : if (!name)
342 : : return NULL;
343 : : }
344 : :
345 : 1787 : kn = kmem_cache_zalloc(kernfs_node_cache, GFP_KERNEL);
346 [ + - ]: 1787 : if (!kn)
347 : : goto err_out1;
348 : :
349 : 1787 : ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL);
350 [ + - ]: 3574 : if (ret < 0)
351 : : goto err_out2;
352 : 1787 : kn->ino = ret;
353 : :
354 : 1787 : atomic_set(&kn->count, 1);
355 : 1787 : atomic_set(&kn->active, 0);
356 : :
357 : 1787 : kn->name = name;
358 : 1787 : kn->mode = mode;
359 : 1787 : kn->flags = flags | KERNFS_REMOVED;
360 : :
361 : 1787 : return kn;
362 : :
363 : : err_out2:
364 : 0 : kmem_cache_free(kernfs_node_cache, kn);
365 : : err_out1:
366 : 0 : kfree(dup_name);
367 : 0 : return NULL;
368 : : }
369 : :
370 : 0 : struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
371 : : const char *name, umode_t mode,
372 : : unsigned flags)
373 : : {
374 : : struct kernfs_node *kn;
375 : :
376 : 1787 : kn = __kernfs_new_node(kernfs_root(parent), name, mode, flags);
377 [ + - ]: 1787 : if (kn) {
378 : 1787 : kernfs_get(parent);
379 : 1787 : kn->parent = parent;
380 : : }
381 : 1787 : return kn;
382 : : }
383 : :
384 : : /**
385 : : * kernfs_addrm_start - prepare for kernfs_node add/remove
386 : : * @acxt: pointer to kernfs_addrm_cxt to be used
387 : : *
388 : : * This function is called when the caller is about to add or remove
389 : : * kernfs_node. This function acquires kernfs_mutex. @acxt is used
390 : : * to keep and pass context to other addrm functions.
391 : : *
392 : : * LOCKING:
393 : : * Kernel thread context (may sleep). kernfs_mutex is locked on
394 : : * return.
395 : : */
396 : 0 : void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt)
397 : : __acquires(kernfs_mutex)
398 : : {
399 : 2890 : memset(acxt, 0, sizeof(*acxt));
400 : :
401 : 2890 : mutex_lock(&kernfs_mutex);
402 : 1434 : }
403 : :
404 : : /**
405 : : * kernfs_add_one - add kernfs_node to parent without warning
406 : : * @acxt: addrm context to use
407 : : * @kn: kernfs_node to be added
408 : : *
409 : : * The caller must already have initialized @kn->parent. This
410 : : * function increments nlink of the parent's inode if @kn is a
411 : : * directory and link into the children list of the parent.
412 : : *
413 : : * This function should be called between calls to
414 : : * kernfs_addrm_start() and kernfs_addrm_finish() and should be passed
415 : : * the same @acxt as passed to kernfs_addrm_start().
416 : : *
417 : : * LOCKING:
418 : : * Determined by kernfs_addrm_start().
419 : : *
420 : : * RETURNS:
421 : : * 0 on success, -EEXIST if entry with the given name already
422 : : * exists.
423 : : */
424 : 0 : int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn)
425 : : {
426 : 1787 : struct kernfs_node *parent = kn->parent;
427 : : bool has_ns = kernfs_ns_enabled(parent);
428 : : struct kernfs_iattrs *ps_iattr;
429 : : int ret;
430 : :
431 [ - + ]: 1787 : if (has_ns != (bool)kn->ns) {
432 [ # # ]: 0 : WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n",
433 : : has_ns ? "required" : "invalid", parent->name, kn->name);
434 : 0 : return -EINVAL;
435 : : }
436 : :
437 [ + - ]: 1787 : if (kernfs_type(parent) != KERNFS_DIR)
438 : : return -EINVAL;
439 : :
440 [ + - ]: 1787 : if (parent->flags & KERNFS_REMOVED)
441 : : return -ENOENT;
442 : :
443 : 1787 : kn->hash = kernfs_name_hash(kn->name, kn->ns);
444 : :
445 : 1787 : ret = kernfs_link_sibling(kn);
446 [ + - ]: 1787 : if (ret)
447 : : return ret;
448 : :
449 : : /* Update timestamps on the parent */
450 : 1787 : ps_iattr = parent->iattr;
451 [ - + ]: 1787 : if (ps_iattr) {
452 : 0 : struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
453 : 0 : ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
454 : : }
455 : :
456 : : /* Mark the entry added into directory tree */
457 : 1787 : kn->flags &= ~KERNFS_REMOVED;
458 : :
459 : 1787 : return 0;
460 : : }
461 : :
462 : : /**
463 : : * kernfs_remove_one - remove kernfs_node from parent
464 : : * @acxt: addrm context to use
465 : : * @kn: kernfs_node to be removed
466 : : *
467 : : * Mark @kn removed and drop nlink of parent inode if @kn is a
468 : : * directory. @kn is unlinked from the children list.
469 : : *
470 : : * This function should be called between calls to
471 : : * kernfs_addrm_start() and kernfs_addrm_finish() and should be
472 : : * passed the same @acxt as passed to kernfs_addrm_start().
473 : : *
474 : : * LOCKING:
475 : : * Determined by kernfs_addrm_start().
476 : : */
477 : 0 : static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt,
478 : : struct kernfs_node *kn)
479 : : {
480 : : struct kernfs_iattrs *ps_iattr;
481 : :
482 : : /*
483 : : * Removal can be called multiple times on the same node. Only the
484 : : * first invocation is effective and puts the base ref.
485 : : */
486 [ + - ]: 987 : if (kn->flags & KERNFS_REMOVED)
487 : 0 : return;
488 : :
489 [ + - ]: 987 : if (kn->parent) {
490 : 987 : kernfs_unlink_sibling(kn);
491 : :
492 : : /* Update timestamps on the parent */
493 : 987 : ps_iattr = kn->parent->iattr;
494 [ - + ]: 987 : if (ps_iattr) {
495 : 0 : ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME;
496 : 0 : ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME;
497 : : }
498 : : }
499 : :
500 : 987 : kn->flags |= KERNFS_REMOVED;
501 : 987 : kn->u.removed_list = acxt->removed;
502 : 987 : acxt->removed = kn;
503 : : }
504 : :
505 : : /**
506 : : * kernfs_addrm_finish - finish up kernfs_node add/remove
507 : : * @acxt: addrm context to finish up
508 : : *
509 : : * Finish up kernfs_node add/remove. Resources acquired by
510 : : * kernfs_addrm_start() are released and removed kernfs_nodes are
511 : : * cleaned up.
512 : : *
513 : : * LOCKING:
514 : : * kernfs_mutex is released.
515 : : */
516 : 0 : void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt)
517 : : __releases(kernfs_mutex)
518 : : {
519 : : /* release resources acquired by kernfs_addrm_start() */
520 : 2890 : mutex_unlock(&kernfs_mutex);
521 : :
522 : : /* kill removed kernfs_nodes */
523 [ + + ]: 3877 : while (acxt->removed) {
524 : : struct kernfs_node *kn = acxt->removed;
525 : :
526 : 987 : acxt->removed = kn->u.removed_list;
527 : :
528 : 987 : kernfs_deactivate(kn);
529 : 987 : kernfs_unmap_bin_file(kn);
530 : 987 : kernfs_put(kn);
531 : : }
532 : 2890 : }
533 : :
534 : : /**
535 : : * kernfs_find_ns - find kernfs_node with the given name
536 : : * @parent: kernfs_node to search under
537 : : * @name: name to look for
538 : : * @ns: the namespace tag to use
539 : : *
540 : : * Look for kernfs_node with name @name under @parent. Returns pointer to
541 : : * the found kernfs_node on success, %NULL on failure.
542 : : */
543 : 0 : static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent,
544 : : const unsigned char *name,
545 : : const void *ns)
546 : : {
547 : 10277 : struct rb_node *node = parent->dir.children.rb_node;
548 : : bool has_ns = kernfs_ns_enabled(parent);
549 : : unsigned int hash;
550 : :
551 : : lockdep_assert_held(&kernfs_mutex);
552 : :
553 [ - + ]: 10277 : if (has_ns != (bool)ns) {
554 [ # # ]: 0 : WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n",
555 : : has_ns ? "required" : "invalid", parent->name, name);
556 : 0 : return NULL;
557 : : }
558 : :
559 : 10277 : hash = kernfs_name_hash(name, ns);
560 [ + + ]: 38795 : while (node) {
561 : : struct kernfs_node *kn;
562 : : int result;
563 : :
564 : 30067 : kn = rb_to_kn(node);
565 : 30067 : result = kernfs_name_compare(hash, name, ns, kn);
566 [ + + ]: 40344 : if (result < 0)
567 : 9938 : node = node->rb_left;
568 [ + + ]: 20129 : else if (result > 0)
569 : 28518 : node = node->rb_right;
570 : : else
571 : : return kn;
572 : : }
573 : : return NULL;
574 : : }
575 : :
576 : : /**
577 : : * kernfs_find_and_get_ns - find and get kernfs_node with the given name
578 : : * @parent: kernfs_node to search under
579 : : * @name: name to look for
580 : : * @ns: the namespace tag to use
581 : : *
582 : : * Look for kernfs_node with name @name under @parent and get a reference
583 : : * if found. This function may sleep and returns pointer to the found
584 : : * kernfs_node on success, %NULL on failure.
585 : : */
586 : 0 : struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
587 : : const char *name, const void *ns)
588 : : {
589 : : struct kernfs_node *kn;
590 : :
591 : 176 : mutex_lock(&kernfs_mutex);
592 : 176 : kn = kernfs_find_ns(parent, name, ns);
593 : 176 : kernfs_get(kn);
594 : 176 : mutex_unlock(&kernfs_mutex);
595 : :
596 : 176 : return kn;
597 : : }
598 : : EXPORT_SYMBOL_GPL(kernfs_find_and_get_ns);
599 : :
600 : : /**
601 : : * kernfs_create_root - create a new kernfs hierarchy
602 : : * @kdops: optional directory syscall operations for the hierarchy
603 : : * @priv: opaque data associated with the new directory
604 : : *
605 : : * Returns the root of the new hierarchy on success, ERR_PTR() value on
606 : : * failure.
607 : : */
608 : 0 : struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv)
609 : : {
610 : : struct kernfs_root *root;
611 : : struct kernfs_node *kn;
612 : :
613 : : root = kzalloc(sizeof(*root), GFP_KERNEL);
614 [ # # ]: 0 : if (!root)
615 : : return ERR_PTR(-ENOMEM);
616 : :
617 : 0 : ida_init(&root->ino_ida);
618 : :
619 : 0 : kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO,
620 : : KERNFS_DIR);
621 [ # # ]: 0 : if (!kn) {
622 : 0 : ida_destroy(&root->ino_ida);
623 : 0 : kfree(root);
624 : 0 : return ERR_PTR(-ENOMEM);
625 : : }
626 : :
627 : 0 : kn->flags &= ~KERNFS_REMOVED;
628 : 0 : kn->priv = priv;
629 : 0 : kn->dir.root = root;
630 : :
631 : 0 : root->dir_ops = kdops;
632 : 0 : root->kn = kn;
633 : :
634 : 0 : return root;
635 : : }
636 : :
637 : : /**
638 : : * kernfs_destroy_root - destroy a kernfs hierarchy
639 : : * @root: root of the hierarchy to destroy
640 : : *
641 : : * Destroy the hierarchy anchored at @root by removing all existing
642 : : * directories and destroying @root.
643 : : */
644 : 0 : void kernfs_destroy_root(struct kernfs_root *root)
645 : : {
646 : 0 : kernfs_remove(root->kn); /* will also free @root */
647 : 0 : }
648 : :
649 : : /**
650 : : * kernfs_create_dir_ns - create a directory
651 : : * @parent: parent in which to create a new directory
652 : : * @name: name of the new directory
653 : : * @mode: mode of the new directory
654 : : * @priv: opaque data associated with the new directory
655 : : * @ns: optional namespace tag of the directory
656 : : *
657 : : * Returns the created node on success, ERR_PTR() value on failure.
658 : : */
659 : 0 : struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
660 : : const char *name, umode_t mode,
661 : : void *priv, const void *ns)
662 : : {
663 : : struct kernfs_addrm_cxt acxt;
664 : : struct kernfs_node *kn;
665 : : int rc;
666 : :
667 : : /* allocate */
668 : 353 : kn = kernfs_new_node(parent, name, mode | S_IFDIR, KERNFS_DIR);
669 [ + - ]: 353 : if (!kn)
670 : : return ERR_PTR(-ENOMEM);
671 : :
672 : 353 : kn->dir.root = parent->dir.root;
673 : 353 : kn->ns = ns;
674 : 353 : kn->priv = priv;
675 : :
676 : : /* link in */
677 : : kernfs_addrm_start(&acxt);
678 : 353 : rc = kernfs_add_one(&acxt, kn);
679 : 353 : kernfs_addrm_finish(&acxt);
680 : :
681 [ - + ]: 353 : if (!rc)
682 : : return kn;
683 : :
684 : 0 : kernfs_put(kn);
685 : 0 : return ERR_PTR(rc);
686 : : }
687 : :
688 : 0 : static struct dentry *kernfs_iop_lookup(struct inode *dir,
689 : : struct dentry *dentry,
690 : : unsigned int flags)
691 : : {
692 : : struct dentry *ret;
693 : 18192 : struct kernfs_node *parent = dentry->d_parent->d_fsdata;
694 : : struct kernfs_node *kn;
695 : : struct inode *inode;
696 : : const void *ns = NULL;
697 : :
698 : 9096 : mutex_lock(&kernfs_mutex);
699 : :
700 [ - + ]: 9096 : if (kernfs_ns_enabled(parent))
701 : 0 : ns = kernfs_info(dir->i_sb)->ns;
702 : :
703 : 9096 : kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
704 : :
705 : : /* no such entry */
706 [ + + ]: 9096 : if (!kn) {
707 : : ret = NULL;
708 : : goto out_unlock;
709 : : }
710 : 555 : kernfs_get(kn);
711 : 555 : dentry->d_fsdata = kn;
712 : :
713 : : /* attach dentry and inode */
714 : 555 : inode = kernfs_get_inode(dir->i_sb, kn);
715 [ + - ]: 555 : if (!inode) {
716 : : ret = ERR_PTR(-ENOMEM);
717 : : goto out_unlock;
718 : : }
719 : :
720 : : /* instantiate and hash dentry */
721 : 555 : ret = d_materialise_unique(dentry, inode);
722 : : out_unlock:
723 : 9096 : mutex_unlock(&kernfs_mutex);
724 : 9096 : return ret;
725 : : }
726 : :
727 : 0 : static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry,
728 : : umode_t mode)
729 : : {
730 : 0 : struct kernfs_node *parent = dir->i_private;
731 : 0 : struct kernfs_dir_ops *kdops = kernfs_root(parent)->dir_ops;
732 : :
733 [ # # ][ # # ]: 0 : if (!kdops || !kdops->mkdir)
734 : : return -EPERM;
735 : :
736 : 0 : return kdops->mkdir(parent, dentry->d_name.name, mode);
737 : : }
738 : :
739 : 0 : static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry)
740 : : {
741 : 0 : struct kernfs_node *kn = dentry->d_fsdata;
742 : 0 : struct kernfs_dir_ops *kdops = kernfs_root(kn)->dir_ops;
743 : :
744 [ # # ][ # # ]: 0 : if (!kdops || !kdops->rmdir)
745 : : return -EPERM;
746 : :
747 : 0 : return kdops->rmdir(kn);
748 : : }
749 : :
750 : 0 : static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry,
751 : : struct inode *new_dir, struct dentry *new_dentry)
752 : : {
753 : 0 : struct kernfs_node *kn = old_dentry->d_fsdata;
754 : 0 : struct kernfs_node *new_parent = new_dir->i_private;
755 : 0 : struct kernfs_dir_ops *kdops = kernfs_root(kn)->dir_ops;
756 : :
757 [ # # ][ # # ]: 0 : if (!kdops || !kdops->rename)
758 : : return -EPERM;
759 : :
760 : 0 : return kdops->rename(kn, new_parent, new_dentry->d_name.name);
761 : : }
762 : :
763 : : const struct inode_operations kernfs_dir_iops = {
764 : : .lookup = kernfs_iop_lookup,
765 : : .permission = kernfs_iop_permission,
766 : : .setattr = kernfs_iop_setattr,
767 : : .getattr = kernfs_iop_getattr,
768 : : .setxattr = kernfs_iop_setxattr,
769 : : .removexattr = kernfs_iop_removexattr,
770 : : .getxattr = kernfs_iop_getxattr,
771 : : .listxattr = kernfs_iop_listxattr,
772 : :
773 : : .mkdir = kernfs_iop_mkdir,
774 : : .rmdir = kernfs_iop_rmdir,
775 : : .rename = kernfs_iop_rename,
776 : : };
777 : :
778 : 984 : static struct kernfs_node *kernfs_leftmost_descendant(struct kernfs_node *pos)
779 : : {
780 : : struct kernfs_node *last;
781 : :
782 : : while (true) {
783 : : struct rb_node *rbn;
784 : :
785 : : last = pos;
786 : :
787 [ + + ]: 987 : if (kernfs_type(pos) != KERNFS_DIR)
788 : : break;
789 : :
790 : 127 : rbn = rb_first(&pos->dir.children);
791 [ + + ]: 127 : if (!rbn)
792 : : break;
793 : :
794 : 3 : pos = rb_to_kn(rbn);
795 : 3 : }
796 : :
797 : 0 : return last;
798 : : }
799 : :
800 : : /**
801 : : * kernfs_next_descendant_post - find the next descendant for post-order walk
802 : : * @pos: the current position (%NULL to initiate traversal)
803 : : * @root: kernfs_node whose descendants to walk
804 : : *
805 : : * Find the next descendant to visit for post-order traversal of @root's
806 : : * descendants. @root is included in the iteration and the last node to be
807 : : * visited.
808 : : */
809 : 0 : static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos,
810 : : struct kernfs_node *root)
811 : : {
812 : : struct rb_node *rbn;
813 : :
814 : : lockdep_assert_held(&kernfs_mutex);
815 : :
816 : : /* if first iteration, visit leftmost descendant which may be root */
817 [ + + ]: 1932 : if (!pos)
818 : 945 : return kernfs_leftmost_descendant(root);
819 : :
820 : : /* if we visited @root, we're done */
821 [ + + ]: 987 : if (pos == root)
822 : : return NULL;
823 : :
824 : : /* if there's an unvisited sibling, visit its leftmost descendant */
825 : 42 : rbn = rb_next(&pos->rb);
826 [ + + ]: 1974 : if (rbn)
827 : 39 : return kernfs_leftmost_descendant(rb_to_kn(rbn));
828 : :
829 : : /* no sibling left, visit parent */
830 : 3 : return pos->parent;
831 : : }
832 : :
833 : 0 : static void __kernfs_remove(struct kernfs_addrm_cxt *acxt,
834 : : struct kernfs_node *kn)
835 : : {
836 : : struct kernfs_node *pos, *next;
837 : :
838 [ + - ]: 945 : if (!kn)
839 : 945 : return;
840 : :
841 : : pr_debug("kernfs %s: removing\n", kn->name);
842 : :
843 : : next = NULL;
844 : : do {
845 : : pos = next;
846 : 1932 : next = kernfs_next_descendant_post(pos, kn);
847 [ + + ]: 1932 : if (pos)
848 : 987 : kernfs_remove_one(acxt, pos);
849 [ + + ]: 2877 : } while (next);
850 : : }
851 : :
852 : : /**
853 : : * kernfs_remove - remove a kernfs_node recursively
854 : : * @kn: the kernfs_node to remove
855 : : *
856 : : * Remove @kn along with all its subdirectories and files.
857 : : */
858 : 0 : void kernfs_remove(struct kernfs_node *kn)
859 : : {
860 : : struct kernfs_addrm_cxt acxt;
861 : :
862 : : kernfs_addrm_start(&acxt);
863 : 127 : __kernfs_remove(&acxt, kn);
864 : 127 : kernfs_addrm_finish(&acxt);
865 : 127 : }
866 : :
867 : : /**
868 : : * kernfs_remove_by_name_ns - find a kernfs_node by name and remove it
869 : : * @parent: parent of the target
870 : : * @name: name of the kernfs_node to remove
871 : : * @ns: namespace tag of the kernfs_node to remove
872 : : *
873 : : * Look for the kernfs_node with @name and @ns under @parent and remove it.
874 : : * Returns 0 on success, -ENOENT if such entry doesn't exist.
875 : : */
876 : 0 : int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
877 : : const void *ns)
878 : : {
879 : : struct kernfs_addrm_cxt acxt;
880 : : struct kernfs_node *kn;
881 : :
882 [ - + ]: 976 : if (!parent) {
883 : 0 : WARN(1, KERN_WARNING "kernfs: can not remove '%s', no directory\n",
884 : : name);
885 : 0 : return -ENOENT;
886 : : }
887 : :
888 : : kernfs_addrm_start(&acxt);
889 : :
890 : 976 : kn = kernfs_find_ns(parent, name, ns);
891 [ + + ]: 976 : if (kn)
892 : 818 : __kernfs_remove(&acxt, kn);
893 : :
894 : 976 : kernfs_addrm_finish(&acxt);
895 : :
896 [ + + ]: 976 : if (kn)
897 : : return 0;
898 : : else
899 : 158 : return -ENOENT;
900 : : }
901 : :
902 : : /**
903 : : * kernfs_rename_ns - move and rename a kernfs_node
904 : : * @kn: target node
905 : : * @new_parent: new parent to put @sd under
906 : : * @new_name: new name
907 : : * @new_ns: new namespace tag
908 : : */
909 : 0 : int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
910 : : const char *new_name, const void *new_ns)
911 : : {
912 : : int error;
913 : :
914 : 29 : mutex_lock(&kernfs_mutex);
915 : :
916 : : error = -ENOENT;
917 [ + - ]: 29 : if ((kn->flags | new_parent->flags) & KERNFS_REMOVED)
918 : : goto out;
919 : :
920 : : error = 0;
921 [ - + ][ # # ]: 29 : if ((kn->parent == new_parent) && (kn->ns == new_ns) &&
[ # # ]
922 : 0 : (strcmp(kn->name, new_name) == 0))
923 : : goto out; /* nothing to rename */
924 : :
925 : : error = -EEXIST;
926 [ + - ]: 29 : if (kernfs_find_ns(new_parent, new_name, new_ns))
927 : : goto out;
928 : :
929 : : /* rename kernfs_node */
930 [ - + ]: 29 : if (strcmp(kn->name, new_name) != 0) {
931 : : error = -ENOMEM;
932 : 0 : new_name = kstrdup(new_name, GFP_KERNEL);
933 [ # # ]: 0 : if (!new_name)
934 : : goto out;
935 : :
936 [ # # ]: 0 : if (kn->flags & KERNFS_STATIC_NAME)
937 : 0 : kn->flags &= ~KERNFS_STATIC_NAME;
938 : : else
939 : 0 : kfree(kn->name);
940 : :
941 : 0 : kn->name = new_name;
942 : : }
943 : :
944 : : /*
945 : : * Move to the appropriate place in the appropriate directories rbtree.
946 : : */
947 : 29 : kernfs_unlink_sibling(kn);
948 : 29 : kernfs_get(new_parent);
949 : 29 : kernfs_put(kn->parent);
950 : 29 : kn->ns = new_ns;
951 : 29 : kn->hash = kernfs_name_hash(kn->name, kn->ns);
952 : 29 : kn->parent = new_parent;
953 : 29 : kernfs_link_sibling(kn);
954 : :
955 : : error = 0;
956 : : out:
957 : 29 : mutex_unlock(&kernfs_mutex);
958 : 29 : return error;
959 : : }
960 : :
961 : : /* Relationship between s_mode and the DT_xxx types */
962 : : static inline unsigned char dt_type(struct kernfs_node *kn)
963 : : {
964 : 322 : return (kn->mode >> 12) & 15;
965 : : }
966 : :
967 : 0 : static int kernfs_dir_fop_release(struct inode *inode, struct file *filp)
968 : : {
969 : 59 : kernfs_put(filp->private_data);
970 : 59 : return 0;
971 : : }
972 : :
973 : 0 : static struct kernfs_node *kernfs_dir_pos(const void *ns,
974 : : struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos)
975 : : {
976 [ + + ]: 382 : if (pos) {
977 [ + - ]: 322 : int valid = !(pos->flags & KERNFS_REMOVED) &&
978 [ + - ][ - + ]: 644 : pos->parent == parent && hash == pos->hash;
979 : 322 : kernfs_put(pos);
980 [ - + ]: 322 : if (!valid)
981 : : pos = NULL;
982 : : }
983 [ + + ][ + + ]: 412 : if (!pos && (hash > 1) && (hash < INT_MAX)) {
984 : 30 : struct rb_node *node = parent->dir.children.rb_node;
985 [ + + ]: 134 : while (node) {
986 : 104 : pos = rb_to_kn(node);
987 : :
988 [ + - ]: 104 : if (hash < pos->hash)
989 : 104 : node = node->rb_left;
990 [ # # ]: 0 : else if (hash > pos->hash)
991 : 104 : node = node->rb_right;
992 : : else
993 : : break;
994 : : }
995 : : }
996 : : /* Skip over entries in the wrong namespace */
997 [ + + ][ - + ]: 382 : while (pos && pos->ns != ns) {
998 : 0 : struct rb_node *node = rb_next(&pos->rb);
999 [ # # ]: 0 : if (!node)
1000 : : pos = NULL;
1001 : : else
1002 : 0 : pos = rb_to_kn(node);
1003 : : }
1004 : 382 : return pos;
1005 : : }
1006 : :
1007 : 0 : static struct kernfs_node *kernfs_dir_next_pos(const void *ns,
1008 : : struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos)
1009 : : {
1010 : 322 : pos = kernfs_dir_pos(ns, parent, ino, pos);
1011 [ + - ]: 322 : if (pos)
1012 : : do {
1013 : 322 : struct rb_node *node = rb_next(&pos->rb);
1014 [ + + ]: 322 : if (!node)
1015 : : pos = NULL;
1016 : : else
1017 : 292 : pos = rb_to_kn(node);
1018 [ + ][ - + ]: 322 : } while (pos && pos->ns != ns);
1019 : 0 : return pos;
1020 : : }
1021 : :
1022 : 0 : static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
1023 : : {
1024 : 60 : struct dentry *dentry = file->f_path.dentry;
1025 : 120 : struct kernfs_node *parent = dentry->d_fsdata;
1026 : 382 : struct kernfs_node *pos = file->private_data;
1027 : : const void *ns = NULL;
1028 : :
1029 [ + - ]: 60 : if (!dir_emit_dots(file, ctx))
1030 : : return 0;
1031 : 60 : mutex_lock(&kernfs_mutex);
1032 : :
1033 [ - + ]: 60 : if (kernfs_ns_enabled(parent))
1034 : 0 : ns = kernfs_info(dentry->d_sb)->ns;
1035 : :
1036 [ + + ]: 382 : for (pos = kernfs_dir_pos(ns, parent, ctx->pos, pos);
1037 : : pos;
1038 : 322 : pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) {
1039 : 322 : const char *name = pos->name;
1040 : 322 : unsigned int type = dt_type(pos);
1041 : 322 : int len = strlen(name);
1042 : 322 : ino_t ino = pos->ino;
1043 : :
1044 : 322 : ctx->pos = pos->hash;
1045 : 322 : file->private_data = pos;
1046 : 322 : kernfs_get(pos);
1047 : :
1048 : 322 : mutex_unlock(&kernfs_mutex);
1049 [ + - ]: 322 : if (!dir_emit(ctx, name, len, ino, type))
1050 : : return 0;
1051 : 322 : mutex_lock(&kernfs_mutex);
1052 : : }
1053 : 60 : mutex_unlock(&kernfs_mutex);
1054 : 60 : file->private_data = NULL;
1055 : 60 : ctx->pos = INT_MAX;
1056 : 60 : return 0;
1057 : : }
1058 : :
1059 : 0 : static loff_t kernfs_dir_fop_llseek(struct file *file, loff_t offset,
1060 : : int whence)
1061 : : {
1062 : : struct inode *inode = file_inode(file);
1063 : : loff_t ret;
1064 : :
1065 : 0 : mutex_lock(&inode->i_mutex);
1066 : 0 : ret = generic_file_llseek(file, offset, whence);
1067 : 0 : mutex_unlock(&inode->i_mutex);
1068 : :
1069 : 0 : return ret;
1070 : : }
1071 : :
1072 : : const struct file_operations kernfs_dir_fops = {
1073 : : .read = generic_read_dir,
1074 : : .iterate = kernfs_fop_readdir,
1075 : : .release = kernfs_dir_fop_release,
1076 : : .llseek = kernfs_dir_fop_llseek,
1077 : : };
|