Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'driver-core-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
"Here is the set of driver core / debugfs patches for 4.15-rc1.

Not many here, mostly all are debugfs fixes to resolve some
long-reported problems with files going away with references to them
in userspace. There's also some SPDX cleanups for the debugfs code, as
well as a few other minor driver core changes for issues reported by
people.

All of these have been in linux-next for a week or more with no
reported issues"

* tag 'driver-core-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
driver core: Fix device link deferred probe
debugfs: Remove redundant license text
debugfs: add SPDX identifiers to all debugfs files
debugfs: defer debugfs_fsdata allocation to first usage
debugfs: call debugfs_real_fops() only after debugfs_file_get()
debugfs: purge obsolete SRCU based removal protection
IB/hfi1: convert to debugfs_file_get() and -put()
debugfs: convert to debugfs_file_get() and -put()
debugfs: debugfs_real_fops(): drop __must_hold sparse annotation
debugfs: implement per-file removal protection
debugfs: add support for more elaborate ->d_fsdata
driver core: Move device_links_purge() after bus_remove_device()
arch_topology: Fix section miss match warning due to free_raw_capacity()
driver-core: pr_err() strings should end with newlines

+217 -166
+1 -1
drivers/base/arch_topology.c
··· 105 105 static u32 capacity_scale; 106 106 static u32 *raw_capacity; 107 107 108 - static int __init free_raw_capacity(void) 108 + static int free_raw_capacity(void) 109 109 { 110 110 kfree(raw_capacity); 111 111 raw_capacity = NULL;
+1 -1
drivers/base/core.c
··· 1958 1958 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1959 1959 BUS_NOTIFY_DEL_DEVICE, dev); 1960 1960 1961 - device_links_purge(dev); 1962 1961 dpm_sysfs_remove(dev); 1963 1962 if (parent) 1964 1963 klist_del(&dev->p->knode_parent); ··· 1985 1986 device_pm_remove(dev); 1986 1987 driver_deferred_probe_del(dev); 1987 1988 device_remove_properties(dev); 1989 + device_links_purge(dev); 1988 1990 1989 1991 /* Notify the platform of the removal, in case they 1990 1992 * need to do anything...
+12 -4
drivers/base/dd.c
··· 350 350 static atomic_t probe_count = ATOMIC_INIT(0); 351 351 static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); 352 352 353 + static void driver_deferred_probe_add_trigger(struct device *dev, 354 + int local_trigger_count) 355 + { 356 + driver_deferred_probe_add(dev); 357 + /* Did a trigger occur while probing? Need to re-trigger if yes */ 358 + if (local_trigger_count != atomic_read(&deferred_trigger_count)) 359 + driver_deferred_probe_trigger(); 360 + } 361 + 353 362 static int really_probe(struct device *dev, struct device_driver *drv) 354 363 { 355 364 int ret = -EPROBE_DEFER; ··· 378 369 } 379 370 380 371 ret = device_links_check_suppliers(dev); 372 + if (ret == -EPROBE_DEFER) 373 + driver_deferred_probe_add_trigger(dev, local_trigger_count); 381 374 if (ret) 382 375 return ret; 383 376 ··· 481 470 case -EPROBE_DEFER: 482 471 /* Driver requested deferred probing */ 483 472 dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name); 484 - driver_deferred_probe_add(dev); 485 - /* Did a trigger occur while probing? Need to re-trigger if yes */ 486 - if (local_trigger_count != atomic_read(&deferred_trigger_count)) 487 - driver_deferred_probe_trigger(); 473 + driver_deferred_probe_add_trigger(dev, local_trigger_count); 488 474 break; 489 475 case -ENODEV: 490 476 case -ENXIO:
+3 -3
drivers/base/test/test_async_driver_probe.c
··· 64 64 NULL, 0); 65 65 if (IS_ERR(async_dev_1)) { 66 66 error = PTR_ERR(async_dev_1); 67 - pr_err("failed to create async_dev_1: %d", error); 67 + pr_err("failed to create async_dev_1: %d\n", error); 68 68 return error; 69 69 } 70 70 ··· 91 91 NULL, 0); 92 92 if (IS_ERR(async_dev_2)) { 93 93 error = PTR_ERR(async_dev_2); 94 - pr_err("failed to create async_dev_2: %d", error); 94 + pr_err("failed to create async_dev_2: %d\n", error); 95 95 goto err_unregister_async_driver; 96 96 } 97 97 ··· 118 118 NULL, 0); 119 119 if (IS_ERR(sync_dev_1)) { 120 120 error = PTR_ERR(sync_dev_1); 121 - pr_err("failed to create sync_dev_1: %d", error); 121 + pr_err("failed to create sync_dev_1: %d\n", error); 122 122 goto err_unregister_sync_driver; 123 123 } 124 124
+10 -10
drivers/infiniband/hw/hfi1/debugfs.c
··· 71 71 loff_t *ppos) 72 72 { 73 73 struct dentry *d = file->f_path.dentry; 74 - int srcu_idx; 75 74 ssize_t r; 76 75 77 - r = debugfs_use_file_start(d, &srcu_idx); 78 - if (likely(!r)) 79 - r = seq_read(file, buf, size, ppos); 80 - debugfs_use_file_finish(srcu_idx); 76 + r = debugfs_file_get(d); 77 + if (unlikely(r)) 78 + return r; 79 + r = seq_read(file, buf, size, ppos); 80 + debugfs_file_put(d); 81 81 return r; 82 82 } 83 83 ··· 87 87 int whence) 88 88 { 89 89 struct dentry *d = file->f_path.dentry; 90 - int srcu_idx; 91 90 loff_t r; 92 91 93 - r = debugfs_use_file_start(d, &srcu_idx); 94 - if (likely(!r)) 95 - r = seq_lseek(file, offset, whence); 96 - debugfs_use_file_finish(srcu_idx); 92 + r = debugfs_file_get(d); 93 + if (unlikely(r)) 94 + return r; 95 + r = seq_lseek(file, offset, whence); 96 + debugfs_file_put(d); 97 97 return r; 98 98 } 99 99
+126 -90
fs/debugfs/file.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * file.c - part of debugfs, a tiny little debug file system 3 4 * 4 5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 5 6 * Copyright (C) 2004 IBM Inc. 6 7 * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License version 9 - * 2 as published by the Free Software Foundation. 10 - * 11 8 * debugfs is for people to use instead of /proc or /sys. 12 9 * See Documentation/filesystems/ for more details. 13 - * 14 10 */ 15 11 16 12 #include <linux/module.h> ··· 18 22 #include <linux/slab.h> 19 23 #include <linux/atomic.h> 20 24 #include <linux/device.h> 21 - #include <linux/srcu.h> 22 25 #include <asm/poll.h> 23 26 24 27 #include "internal.h" ··· 43 48 .llseek = noop_llseek, 44 49 }; 45 50 51 + #define F_DENTRY(filp) ((filp)->f_path.dentry) 52 + 53 + const struct file_operations *debugfs_real_fops(const struct file *filp) 54 + { 55 + struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata; 56 + 57 + if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) { 58 + /* 59 + * Urgh, we've been called w/o a protecting 60 + * debugfs_file_get(). 61 + */ 62 + WARN_ON(1); 63 + return NULL; 64 + } 65 + 66 + return fsd->real_fops; 67 + } 68 + EXPORT_SYMBOL_GPL(debugfs_real_fops); 69 + 46 70 /** 47 - * debugfs_use_file_start - mark the beginning of file data access 71 + * debugfs_file_get - mark the beginning of file data access 48 72 * @dentry: the dentry object whose data is being accessed. 49 - * @srcu_idx: a pointer to some memory to store a SRCU index in. 50 73 * 51 - * Up to a matching call to debugfs_use_file_finish(), any 52 - * successive call into the file removing functions debugfs_remove() 53 - * and debugfs_remove_recursive() will block. Since associated private 74 + * Up to a matching call to debugfs_file_put(), any successive call 75 + * into the file removing functions debugfs_remove() and 76 + * debugfs_remove_recursive() will block. Since associated private 54 77 * file data may only get freed after a successful return of any of 55 78 * the removal functions, you may safely access it after a successful 56 - * call to debugfs_use_file_start() without worrying about 57 - * lifetime issues. 79 + * call to debugfs_file_get() without worrying about lifetime issues. 58 80 * 59 81 * If -%EIO is returned, the file has already been removed and thus, 60 82 * it is not safe to access any of its data. If, on the other hand, 61 83 * it is allowed to access the file data, zero is returned. 62 - * 63 - * Regardless of the return code, any call to 64 - * debugfs_use_file_start() must be followed by a matching call 65 - * to debugfs_use_file_finish(). 66 84 */ 67 - int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx) 68 - __acquires(&debugfs_srcu) 85 + int debugfs_file_get(struct dentry *dentry) 69 86 { 70 - *srcu_idx = srcu_read_lock(&debugfs_srcu); 71 - barrier(); 87 + struct debugfs_fsdata *fsd; 88 + void *d_fsd; 89 + 90 + d_fsd = READ_ONCE(dentry->d_fsdata); 91 + if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) { 92 + fsd = d_fsd; 93 + } else { 94 + fsd = kmalloc(sizeof(*fsd), GFP_KERNEL); 95 + if (!fsd) 96 + return -ENOMEM; 97 + 98 + fsd->real_fops = (void *)((unsigned long)d_fsd & 99 + ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); 100 + refcount_set(&fsd->active_users, 1); 101 + init_completion(&fsd->active_users_drained); 102 + if (cmpxchg(&dentry->d_fsdata, d_fsd, fsd) != d_fsd) { 103 + kfree(fsd); 104 + fsd = READ_ONCE(dentry->d_fsdata); 105 + } 106 + } 107 + 108 + /* 109 + * In case of a successful cmpxchg() above, this check is 110 + * strictly necessary and must follow it, see the comment in 111 + * __debugfs_remove_file(). 112 + * OTOH, if the cmpxchg() hasn't been executed or wasn't 113 + * successful, this serves the purpose of not starving 114 + * removers. 115 + */ 72 116 if (d_unlinked(dentry)) 73 117 return -EIO; 118 + 119 + if (!refcount_inc_not_zero(&fsd->active_users)) 120 + return -EIO; 121 + 74 122 return 0; 75 123 } 76 - EXPORT_SYMBOL_GPL(debugfs_use_file_start); 124 + EXPORT_SYMBOL_GPL(debugfs_file_get); 77 125 78 126 /** 79 - * debugfs_use_file_finish - mark the end of file data access 80 - * @srcu_idx: the SRCU index "created" by a former call to 81 - * debugfs_use_file_start(). 127 + * debugfs_file_put - mark the end of file data access 128 + * @dentry: the dentry object formerly passed to 129 + * debugfs_file_get(). 82 130 * 83 131 * Allow any ongoing concurrent call into debugfs_remove() or 84 132 * debugfs_remove_recursive() blocked by a former call to 85 - * debugfs_use_file_start() to proceed and return to its caller. 133 + * debugfs_file_get() to proceed and return to its caller. 86 134 */ 87 - void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu) 135 + void debugfs_file_put(struct dentry *dentry) 88 136 { 89 - srcu_read_unlock(&debugfs_srcu, srcu_idx); 90 - } 91 - EXPORT_SYMBOL_GPL(debugfs_use_file_finish); 137 + struct debugfs_fsdata *fsd = READ_ONCE(dentry->d_fsdata); 92 138 93 - #define F_DENTRY(filp) ((filp)->f_path.dentry) 139 + if (refcount_dec_and_test(&fsd->active_users)) 140 + complete(&fsd->active_users_drained); 141 + } 142 + EXPORT_SYMBOL_GPL(debugfs_file_put); 94 143 95 144 static int open_proxy_open(struct inode *inode, struct file *filp) 96 145 { 97 - const struct dentry *dentry = F_DENTRY(filp); 146 + struct dentry *dentry = F_DENTRY(filp); 98 147 const struct file_operations *real_fops = NULL; 99 - int srcu_idx, r; 148 + int r; 100 149 101 - r = debugfs_use_file_start(dentry, &srcu_idx); 102 - if (r) { 103 - r = -ENOENT; 104 - goto out; 105 - } 150 + r = debugfs_file_get(dentry); 151 + if (r) 152 + return r == -EIO ? -ENOENT : r; 106 153 107 154 real_fops = debugfs_real_fops(filp); 108 155 real_fops = fops_get(real_fops); ··· 161 124 r = real_fops->open(inode, filp); 162 125 163 126 out: 164 - debugfs_use_file_finish(srcu_idx); 127 + debugfs_file_put(dentry); 165 128 return r; 166 129 } 167 130 ··· 175 138 #define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \ 176 139 static ret_type full_proxy_ ## name(proto) \ 177 140 { \ 178 - const struct dentry *dentry = F_DENTRY(filp); \ 179 - const struct file_operations *real_fops = \ 180 - debugfs_real_fops(filp); \ 181 - int srcu_idx; \ 141 + struct dentry *dentry = F_DENTRY(filp); \ 142 + const struct file_operations *real_fops; \ 182 143 ret_type r; \ 183 144 \ 184 - r = debugfs_use_file_start(dentry, &srcu_idx); \ 185 - if (likely(!r)) \ 186 - r = real_fops->name(args); \ 187 - debugfs_use_file_finish(srcu_idx); \ 145 + r = debugfs_file_get(dentry); \ 146 + if (unlikely(r)) \ 147 + return r; \ 148 + real_fops = debugfs_real_fops(filp); \ 149 + r = real_fops->name(args); \ 150 + debugfs_file_put(dentry); \ 188 151 return r; \ 189 152 } 190 153 ··· 209 172 static unsigned int full_proxy_poll(struct file *filp, 210 173 struct poll_table_struct *wait) 211 174 { 212 - const struct dentry *dentry = F_DENTRY(filp); 213 - const struct file_operations *real_fops = debugfs_real_fops(filp); 214 - int srcu_idx; 175 + struct dentry *dentry = F_DENTRY(filp); 215 176 unsigned int r = 0; 177 + const struct file_operations *real_fops; 216 178 217 - if (debugfs_use_file_start(dentry, &srcu_idx)) { 218 - debugfs_use_file_finish(srcu_idx); 179 + if (debugfs_file_get(dentry)) 219 180 return POLLHUP; 220 - } 221 181 182 + real_fops = debugfs_real_fops(filp); 222 183 r = real_fops->poll(filp, wait); 223 - debugfs_use_file_finish(srcu_idx); 184 + debugfs_file_put(dentry); 224 185 return r; 225 186 } 226 187 ··· 262 227 263 228 static int full_proxy_open(struct inode *inode, struct file *filp) 264 229 { 265 - const struct dentry *dentry = F_DENTRY(filp); 230 + struct dentry *dentry = F_DENTRY(filp); 266 231 const struct file_operations *real_fops = NULL; 267 232 struct file_operations *proxy_fops = NULL; 268 - int srcu_idx, r; 233 + int r; 269 234 270 - r = debugfs_use_file_start(dentry, &srcu_idx); 271 - if (r) { 272 - r = -ENOENT; 273 - goto out; 274 - } 235 + r = debugfs_file_get(dentry); 236 + if (r) 237 + return r == -EIO ? -ENOENT : r; 275 238 276 239 real_fops = debugfs_real_fops(filp); 277 240 real_fops = fops_get(real_fops); ··· 307 274 kfree(proxy_fops); 308 275 fops_put(real_fops); 309 276 out: 310 - debugfs_use_file_finish(srcu_idx); 277 + debugfs_file_put(dentry); 311 278 return r; 312 279 } 313 280 ··· 318 285 ssize_t debugfs_attr_read(struct file *file, char __user *buf, 319 286 size_t len, loff_t *ppos) 320 287 { 288 + struct dentry *dentry = F_DENTRY(file); 321 289 ssize_t ret; 322 - int srcu_idx; 323 290 324 - ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); 325 - if (likely(!ret)) 326 - ret = simple_attr_read(file, buf, len, ppos); 327 - debugfs_use_file_finish(srcu_idx); 291 + ret = debugfs_file_get(dentry); 292 + if (unlikely(ret)) 293 + return ret; 294 + ret = simple_attr_read(file, buf, len, ppos); 295 + debugfs_file_put(dentry); 328 296 return ret; 329 297 } 330 298 EXPORT_SYMBOL_GPL(debugfs_attr_read); ··· 333 299 ssize_t debugfs_attr_write(struct file *file, const char __user *buf, 334 300 size_t len, loff_t *ppos) 335 301 { 302 + struct dentry *dentry = F_DENTRY(file); 336 303 ssize_t ret; 337 - int srcu_idx; 338 304 339 - ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); 340 - if (likely(!ret)) 341 - ret = simple_attr_write(file, buf, len, ppos); 342 - debugfs_use_file_finish(srcu_idx); 305 + ret = debugfs_file_get(dentry); 306 + if (unlikely(ret)) 307 + return ret; 308 + ret = simple_attr_write(file, buf, len, ppos); 309 + debugfs_file_put(dentry); 343 310 return ret; 344 311 } 345 312 EXPORT_SYMBOL_GPL(debugfs_attr_write); ··· 774 739 { 775 740 char buf[3]; 776 741 bool val; 777 - int r, srcu_idx; 742 + int r; 743 + struct dentry *dentry = F_DENTRY(file); 778 744 779 - r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); 780 - if (likely(!r)) 781 - val = *(bool *)file->private_data; 782 - debugfs_use_file_finish(srcu_idx); 783 - if (r) 745 + r = debugfs_file_get(dentry); 746 + if (unlikely(r)) 784 747 return r; 748 + val = *(bool *)file->private_data; 749 + debugfs_file_put(dentry); 785 750 786 751 if (val) 787 752 buf[0] = 'Y'; ··· 799 764 char buf[32]; 800 765 size_t buf_size; 801 766 bool bv; 802 - int r, srcu_idx; 767 + int r; 803 768 bool *val = file->private_data; 769 + struct dentry *dentry = F_DENTRY(file); 804 770 805 771 buf_size = min(count, (sizeof(buf)-1)); 806 772 if (copy_from_user(buf, user_buf, buf_size)) ··· 809 773 810 774 buf[buf_size] = '\0'; 811 775 if (strtobool(buf, &bv) == 0) { 812 - r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); 813 - if (likely(!r)) 814 - *val = bv; 815 - debugfs_use_file_finish(srcu_idx); 816 - if (r) 776 + r = debugfs_file_get(dentry); 777 + if (unlikely(r)) 817 778 return r; 779 + *val = bv; 780 + debugfs_file_put(dentry); 818 781 } 819 782 820 783 return count; ··· 875 840 size_t count, loff_t *ppos) 876 841 { 877 842 struct debugfs_blob_wrapper *blob = file->private_data; 843 + struct dentry *dentry = F_DENTRY(file); 878 844 ssize_t r; 879 - int srcu_idx; 880 845 881 - r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); 882 - if (likely(!r)) 883 - r = simple_read_from_buffer(user_buf, count, ppos, blob->data, 884 - blob->size); 885 - debugfs_use_file_finish(srcu_idx); 846 + r = debugfs_file_get(dentry); 847 + if (unlikely(r)) 848 + return r; 849 + r = simple_read_from_buffer(user_buf, count, ppos, blob->data, 850 + blob->size); 851 + debugfs_file_put(dentry); 886 852 return r; 887 853 } 888 854
+43 -19
fs/debugfs/inode.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * inode.c - part of debugfs, a tiny little debug file system 3 4 * 4 5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 5 6 * Copyright (C) 2004 IBM Inc. 6 7 * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License version 9 - * 2 as published by the Free Software Foundation. 10 - * 11 8 * debugfs is for people to use instead of /proc or /sys. 12 9 * See ./Documentation/core-api/kernel-api.rst for more details. 13 - * 14 10 */ 15 11 16 12 #include <linux/module.h> ··· 23 27 #include <linux/parser.h> 24 28 #include <linux/magic.h> 25 29 #include <linux/slab.h> 26 - #include <linux/srcu.h> 27 30 28 31 #include "internal.h" 29 32 30 33 #define DEBUGFS_DEFAULT_MODE 0700 31 - 32 - DEFINE_SRCU(debugfs_srcu); 33 34 34 35 static struct vfsmount *debugfs_mount; 35 36 static int debugfs_mount_count; ··· 178 185 .evict_inode = debugfs_evict_inode, 179 186 }; 180 187 188 + static void debugfs_release_dentry(struct dentry *dentry) 189 + { 190 + void *fsd = dentry->d_fsdata; 191 + 192 + if (!((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) 193 + kfree(dentry->d_fsdata); 194 + } 195 + 181 196 static struct vfsmount *debugfs_automount(struct path *path) 182 197 { 183 198 debugfs_automount_t f; ··· 195 194 196 195 static const struct dentry_operations debugfs_dops = { 197 196 .d_delete = always_delete_dentry, 197 + .d_release = debugfs_release_dentry, 198 198 .d_automount = debugfs_automount, 199 199 }; 200 200 ··· 360 358 inode->i_private = data; 361 359 362 360 inode->i_fop = proxy_fops; 363 - dentry->d_fsdata = (void *)real_fops; 361 + dentry->d_fsdata = (void *)((unsigned long)real_fops | 362 + DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); 364 363 365 364 d_instantiate(dentry, inode); 366 365 fsnotify_create(d_inode(dentry->d_parent), dentry); ··· 618 615 } 619 616 EXPORT_SYMBOL_GPL(debugfs_create_symlink); 620 617 618 + static void __debugfs_remove_file(struct dentry *dentry, struct dentry *parent) 619 + { 620 + struct debugfs_fsdata *fsd; 621 + 622 + simple_unlink(d_inode(parent), dentry); 623 + d_delete(dentry); 624 + 625 + /* 626 + * Paired with the closing smp_mb() implied by a successful 627 + * cmpxchg() in debugfs_file_get(): either 628 + * debugfs_file_get() must see a dead dentry or we must see a 629 + * debugfs_fsdata instance at ->d_fsdata here (or both). 630 + */ 631 + smp_mb(); 632 + fsd = READ_ONCE(dentry->d_fsdata); 633 + if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) 634 + return; 635 + if (!refcount_dec_and_test(&fsd->active_users)) 636 + wait_for_completion(&fsd->active_users_drained); 637 + } 638 + 621 639 static int __debugfs_remove(struct dentry *dentry, struct dentry *parent) 622 640 { 623 641 int ret = 0; 624 642 625 643 if (simple_positive(dentry)) { 626 644 dget(dentry); 627 - if (d_is_dir(dentry)) 628 - ret = simple_rmdir(d_inode(parent), dentry); 629 - else 630 - simple_unlink(d_inode(parent), dentry); 631 - if (!ret) 632 - d_delete(dentry); 645 + if (!d_is_reg(dentry)) { 646 + if (d_is_dir(dentry)) 647 + ret = simple_rmdir(d_inode(parent), dentry); 648 + else 649 + simple_unlink(d_inode(parent), dentry); 650 + if (!ret) 651 + d_delete(dentry); 652 + } else { 653 + __debugfs_remove_file(dentry, parent); 654 + } 633 655 dput(dentry); 634 656 } 635 657 return ret; ··· 688 660 inode_unlock(d_inode(parent)); 689 661 if (!ret) 690 662 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 691 - 692 - synchronize_srcu(&debugfs_srcu); 693 663 } 694 664 EXPORT_SYMBOL_GPL(debugfs_remove); 695 665 ··· 761 735 if (!__debugfs_remove(child, parent)) 762 736 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 763 737 inode_unlock(d_inode(parent)); 764 - 765 - synchronize_srcu(&debugfs_srcu); 766 738 } 767 739 EXPORT_SYMBOL_GPL(debugfs_remove_recursive); 768 740
+15 -5
fs/debugfs/internal.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * internal.h - declarations internal to debugfs 3 4 * 4 5 * Copyright (C) 2016 Nicolai Stange <nicstange@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU General Public License version 8 - * 2 as published by the Free Software Foundation. 9 - * 10 6 */ 11 7 12 8 #ifndef _DEBUGFS_INTERNAL_H_ ··· 14 18 extern const struct file_operations debugfs_noop_file_operations; 15 19 extern const struct file_operations debugfs_open_proxy_file_operations; 16 20 extern const struct file_operations debugfs_full_proxy_file_operations; 21 + 22 + struct debugfs_fsdata { 23 + const struct file_operations *real_fops; 24 + refcount_t active_users; 25 + struct completion active_users_drained; 26 + }; 27 + 28 + /* 29 + * A dentry's ->d_fsdata either points to the real fops or to a 30 + * dynamically allocated debugfs_fsdata instance. 31 + * In order to distinguish between these two cases, a real fops 32 + * pointer gets its lowest bit set. 33 + */ 34 + #define DEBUGFS_FSDATA_IS_REAL_FOPS_BIT BIT(0) 17 35 18 36 #endif /* _DEBUGFS_INTERNAL_H_ */
+6 -32
include/linux/debugfs.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * debugfs.h - a tiny little debug file system 3 4 * 4 5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 5 6 * Copyright (C) 2004 IBM Inc. 6 - * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License version 9 - * 2 as published by the Free Software Foundation. 10 7 * 11 8 * debugfs is for people to use instead of /proc or /sys. 12 9 * See Documentation/filesystems/ for more details. ··· 20 23 21 24 struct device; 22 25 struct file_operations; 23 - struct srcu_struct; 24 26 25 27 struct debugfs_blob_wrapper { 26 28 void *data; ··· 38 42 }; 39 43 40 44 extern struct dentry *arch_debugfs_dir; 41 - 42 - extern struct srcu_struct debugfs_srcu; 43 - 44 - /** 45 - * debugfs_real_fops - getter for the real file operation 46 - * @filp: a pointer to a struct file 47 - * 48 - * Must only be called under the protection established by 49 - * debugfs_use_file_start(). 50 - */ 51 - static inline const struct file_operations *debugfs_real_fops(const struct file *filp) 52 - __must_hold(&debugfs_srcu) 53 - { 54 - /* 55 - * Neither the pointer to the struct file_operations, nor its 56 - * contents ever change -- srcu_dereference() is not needed here. 57 - */ 58 - return filp->f_path.dentry->d_fsdata; 59 - } 60 45 61 46 #define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ 62 47 static int __fops ## _open(struct inode *inode, struct file *file) \ ··· 84 107 void debugfs_remove(struct dentry *dentry); 85 108 void debugfs_remove_recursive(struct dentry *dentry); 86 109 87 - int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx) 88 - __acquires(&debugfs_srcu); 110 + const struct file_operations *debugfs_real_fops(const struct file *filp); 89 111 90 - void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu); 112 + int debugfs_file_get(struct dentry *dentry); 113 + void debugfs_file_put(struct dentry *dentry); 91 114 92 115 ssize_t debugfs_attr_read(struct file *file, char __user *buf, 93 116 size_t len, loff_t *ppos); ··· 216 239 static inline void debugfs_remove_recursive(struct dentry *dentry) 217 240 { } 218 241 219 - static inline int debugfs_use_file_start(const struct dentry *dentry, 220 - int *srcu_idx) 221 - __acquires(&debugfs_srcu) 242 + static inline int debugfs_file_get(struct dentry *dentry) 222 243 { 223 244 return 0; 224 245 } 225 246 226 - static inline void debugfs_use_file_finish(int srcu_idx) 227 - __releases(&debugfs_srcu) 247 + static inline void debugfs_file_put(struct dentry *dentry) 228 248 { } 229 249 230 250 static inline ssize_t debugfs_attr_read(struct file *file, char __user *buf,
-1
lib/Kconfig.debug
··· 280 280 281 281 config DEBUG_FS 282 282 bool "Debug Filesystem" 283 - select SRCU 284 283 help 285 284 debugfs is a virtual file system that kernel developers use to put 286 285 debugging files into. Enable this option to be able to read and