Merge: CNB101: saner replacement for debugfs_rename()

MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/773

JIRA: https://issues.redhat.com/browse/RHEL-86507

saner replacement for debugfs_rename()

Rest of debugfs series and fix are included in https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/864:
Omitted-fix: 268b36116f2f debugfs: separate cache for debugfs inodes
Omitted-fix: bacaaf833e96 debugfs: move ->automount into debugfs_inode_info
Omitted-fix: 41a0ecc0997c debugfs: get rid of dynamically allocation proxy_ops
Omitted-fix: 95688800eefe debugfs: don't mess with bits in ->d_fsdata
Omitted-fix: 12c92098932b debugfs: allow to store an additional opaque pointer at file creation
Omitted-fix: d1433c7ba289 debugfs: take debugfs_short_fops definition out of ifdef
Omitted-fix: 57b314752ec0 debugfs: Fix the missing initializations in __debugfs_file_get()

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>

Approved-by: Michal Schmidt <mschmidt@redhat.com>
Approved-by: Waiman Long <longman@redhat.com>
Approved-by: Ivan Vecera <ivecera@redhat.com>
Approved-by: Rafael Aquini <raquini@redhat.com>
Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com>

Merged-by: Julio Faracco <jfaracco@redhat.com>
This commit is contained in:
Julio Faracco 2025-06-17 00:08:41 -03:00
commit 0675a19c9c
13 changed files with 74 additions and 142 deletions

View File

@ -211,18 +211,16 @@ seq_file content.
There are a couple of other directory-oriented helper functions:: There are a couple of other directory-oriented helper functions::
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *debugfs_change_name(struct dentry *dentry,
struct dentry *old_dentry, const char *fmt, ...);
struct dentry *new_dir,
const char *new_name);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *debugfs_create_symlink(const char *name,
struct dentry *parent, struct dentry *parent,
const char *target); const char *target);
A call to debugfs_rename() will give a new name to an existing debugfs A call to debugfs_change_name() will give a new name to an existing debugfs
file, possibly in a different directory. The new_name must not exist prior file, always in the same directory. The new_name must not exist prior
to the call; the return value is old_dentry with updated information. to the call; the return value is 0 on success and -E... on failuer.
Symbolic links can be created with debugfs_create_symlink(). Symbolic links can be created with debugfs_create_symlink().
There is one important thing that all debugfs users must take into account: There is one important thing that all debugfs users must take into account:

View File

@ -63,13 +63,8 @@ void bond_debug_unregister(struct bonding *bond)
void bond_debug_reregister(struct bonding *bond) void bond_debug_reregister(struct bonding *bond)
{ {
struct dentry *d; int err = debugfs_change_name(bond->debug_dir, "%s", bond->dev->name);
if (err) {
d = debugfs_rename(bonding_debug_root, bond->debug_dir,
bonding_debug_root, bond->dev->name);
if (!IS_ERR(d)) {
bond->debug_dir = d;
} else {
netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n"); netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n");
bond_debug_unregister(bond); bond_debug_unregister(bond);
} }

View File

@ -505,21 +505,6 @@ void xgbe_debugfs_exit(struct xgbe_prv_data *pdata)
void xgbe_debugfs_rename(struct xgbe_prv_data *pdata) void xgbe_debugfs_rename(struct xgbe_prv_data *pdata)
{ {
char *buf; debugfs_change_name(pdata->xgbe_debugfs,
"amd-xgbe-%s", pdata->netdev->name);
if (!pdata->xgbe_debugfs)
return;
buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
if (!buf)
return;
if (!strcmp(pdata->xgbe_debugfs->d_name.name, buf))
goto out;
debugfs_rename(pdata->xgbe_debugfs->d_parent, pdata->xgbe_debugfs,
pdata->xgbe_debugfs->d_parent, buf);
out:
kfree(buf);
} }

View File

@ -3743,10 +3743,7 @@ static int skge_device_event(struct notifier_block *unused,
skge = netdev_priv(dev); skge = netdev_priv(dev);
switch (event) { switch (event) {
case NETDEV_CHANGENAME: case NETDEV_CHANGENAME:
if (skge->debugfs) debugfs_change_name(skge->debugfs, "%s", dev->name);
skge->debugfs = debugfs_rename(skge_debug,
skge->debugfs,
skge_debug, dev->name);
break; break;
case NETDEV_GOING_DOWN: case NETDEV_GOING_DOWN:

View File

@ -4494,10 +4494,7 @@ static int sky2_device_event(struct notifier_block *unused,
switch (event) { switch (event) {
case NETDEV_CHANGENAME: case NETDEV_CHANGENAME:
if (sky2->debugfs) { debugfs_change_name(sky2->debugfs, "%s", dev->name);
sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs,
sky2_debug, dev->name);
}
break; break;
case NETDEV_GOING_DOWN: case NETDEV_GOING_DOWN:

View File

@ -6546,11 +6546,7 @@ static int stmmac_device_event(struct notifier_block *unused,
switch (event) { switch (event) {
case NETDEV_CHANGENAME: case NETDEV_CHANGENAME:
if (priv->dbgfs_dir) debugfs_change_name(priv->dbgfs_dir, "%s", dev->name);
priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir,
priv->dbgfs_dir,
stmmac_fs_dir,
dev->name);
break; break;
} }
done: done:

View File

@ -217,7 +217,7 @@ static void opp_migrate_dentry(struct opp_device *opp_dev,
{ {
struct opp_device *new_dev = NULL, *iter; struct opp_device *new_dev = NULL, *iter;
const struct device *dev; const struct device *dev;
struct dentry *dentry; int err;
/* Look for next opp-dev */ /* Look for next opp-dev */
list_for_each_entry(iter, &opp_table->dev_list, node) list_for_each_entry(iter, &opp_table->dev_list, node)
@ -234,16 +234,14 @@ static void opp_migrate_dentry(struct opp_device *opp_dev,
opp_set_dev_name(dev, opp_table->dentry_name); opp_set_dev_name(dev, opp_table->dentry_name);
dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir, err = debugfs_change_name(opp_dev->dentry, "%s", opp_table->dentry_name);
opp_table->dentry_name); if (err) {
if (IS_ERR(dentry)) {
dev_err(dev, "%s: Failed to rename link from: %s to %s\n", dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
__func__, dev_name(opp_dev->dev), dev_name(dev)); __func__, dev_name(opp_dev->dev), dev_name(dev));
return; return;
} }
new_dev->dentry = dentry; new_dev->dentry = opp_table->dentry = opp_dev->dentry;
opp_table->dentry = dentry;
} }
/** /**

View File

@ -830,76 +830,70 @@ void debugfs_lookup_and_remove(const char *name, struct dentry *parent)
EXPORT_SYMBOL_GPL(debugfs_lookup_and_remove); EXPORT_SYMBOL_GPL(debugfs_lookup_and_remove);
/** /**
* debugfs_rename - rename a file/directory in the debugfs filesystem * debugfs_change_name - rename a file/directory in the debugfs filesystem
* @old_dir: a pointer to the parent dentry for the renamed object. This * @dentry: dentry of an object to be renamed.
* should be a directory dentry. * @fmt: format for new name
* @old_dentry: dentry of an object to be renamed.
* @new_dir: a pointer to the parent dentry where the object should be
* moved. This should be a directory dentry.
* @new_name: a pointer to a string containing the target name.
* *
* This function renames a file/directory in debugfs. The target must not * This function renames a file/directory in debugfs. The target must not
* exist for rename to succeed. * exist for rename to succeed.
* *
* This function will return a pointer to old_dentry (which is updated to * This function will return 0 on success and -E... on failure.
* reflect renaming) if it succeeds. If an error occurs, ERR_PTR(-ERROR)
* will be returned.
* *
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * If debugfs is not enabled in the kernel, the value -%ENODEV will be
* returned. * returned.
*/ */
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, int __printf(2, 3) debugfs_change_name(struct dentry *dentry, const char *fmt, ...)
struct dentry *new_dir, const char *new_name)
{ {
int error; int error = 0;
struct dentry *dentry = NULL, *trap; const char *new_name;
struct name_snapshot old_name; struct name_snapshot old_name;
struct dentry *parent, *target;
struct inode *dir;
va_list ap;
if (IS_ERR(old_dir)) if (IS_ERR_OR_NULL(dentry))
return old_dir; return 0;
if (IS_ERR(new_dir))
return new_dir;
if (IS_ERR_OR_NULL(old_dentry))
return old_dentry;
trap = lock_rename(new_dir, old_dir); va_start(ap, fmt);
/* Source or destination directories don't exist? */ new_name = kvasprintf_const(GFP_KERNEL, fmt, ap);
if (d_really_is_negative(old_dir) || d_really_is_negative(new_dir)) va_end(ap);
goto exit; if (!new_name)
/* Source does not exist, cyclic rename, or mountpoint? */ return -ENOMEM;
if (d_really_is_negative(old_dentry) || old_dentry == trap ||
d_mountpoint(old_dentry))
goto exit;
dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
/* Lookup failed, cyclic rename or target exists? */
if (IS_ERR(dentry) || dentry == trap || d_really_is_positive(dentry))
goto exit;
take_dentry_name_snapshot(&old_name, old_dentry); parent = dget_parent(dentry);
dir = d_inode(parent);
inode_lock(dir);
error = simple_rename(&nop_mnt_idmap, d_inode(old_dir), old_dentry, take_dentry_name_snapshot(&old_name, dentry);
d_inode(new_dir), dentry, 0);
if (error) { if (WARN_ON_ONCE(dentry->d_parent != parent)) {
release_dentry_name_snapshot(&old_name); error = -EINVAL;
goto exit; goto out;
} }
d_move(old_dentry, dentry); if (strcmp(old_name.name.name, new_name) == 0)
fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name, goto out;
d_is_dir(old_dentry), target = lookup_one_len(new_name, parent, strlen(new_name));
NULL, old_dentry); if (IS_ERR(target)) {
error = PTR_ERR(target);
goto out;
}
if (d_really_is_positive(target)) {
dput(target);
error = -EINVAL;
goto out;
}
simple_rename_timestamp(dir, dentry, dir, target);
d_move(dentry, target);
dput(target);
fsnotify_move(dir, dir, &old_name.name, d_is_dir(dentry), NULL, dentry);
out:
release_dentry_name_snapshot(&old_name); release_dentry_name_snapshot(&old_name);
unlock_rename(new_dir, old_dir); inode_unlock(dir);
dput(dentry); dput(parent);
return old_dentry; kfree_const(new_name);
exit: return error;
if (dentry && !IS_ERR(dentry))
dput(dentry);
unlock_rename(new_dir, old_dir);
if (IS_ERR(dentry))
return dentry;
return ERR_PTR(-EINVAL);
} }
EXPORT_SYMBOL_GPL(debugfs_rename); EXPORT_SYMBOL_GPL(debugfs_change_name);
/** /**
* debugfs_initialized - Tells whether debugfs has been registered * debugfs_initialized - Tells whether debugfs has been registered

View File

@ -175,8 +175,7 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf, ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
size_t len, loff_t *ppos); size_t len, loff_t *ppos);
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, int debugfs_change_name(struct dentry *dentry, const char *fmt, ...) __printf(2, 3);
struct dentry *new_dir, const char *new_name);
void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
u8 *value); u8 *value);
@ -361,10 +360,10 @@ static inline ssize_t debugfs_attr_write_signed(struct file *file,
return -ENODEV; return -ENODEV;
} }
static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, static inline int __printf(2, 3) debugfs_change_name(struct dentry *dentry,
struct dentry *new_dir, char *new_name) const char *fmt, ...)
{ {
return ERR_PTR(-ENODEV); return -ENODEV;
} }
static inline void debugfs_create_u8(const char *name, umode_t mode, static inline void debugfs_create_u8(const char *name, umode_t mode,

View File

@ -195,8 +195,6 @@ int shrinker_debugfs_add(struct shrinker *shrinker)
int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...) int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
{ {
struct dentry *entry;
char buf[128];
const char *new, *old; const char *new, *old;
va_list ap; va_list ap;
int ret = 0; int ret = 0;
@ -213,18 +211,8 @@ int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
old = shrinker->name; old = shrinker->name;
shrinker->name = new; shrinker->name = new;
if (shrinker->debugfs_entry) { ret = debugfs_change_name(shrinker->debugfs_entry, "%s-%d",
snprintf(buf, sizeof(buf), "%s-%d", shrinker->name, shrinker->name, shrinker->debugfs_id);
shrinker->debugfs_id);
entry = debugfs_rename(shrinker_debugfs_root,
shrinker->debugfs_entry,
shrinker_debugfs_root, buf);
if (IS_ERR(entry))
ret = PTR_ERR(entry);
else
shrinker->debugfs_entry = entry;
}
mutex_unlock(&shrinker_mutex); mutex_unlock(&shrinker_mutex);

View File

@ -57,14 +57,11 @@ DEFINE_SHOW_ATTRIBUTE(hsr_node_table);
void hsr_debugfs_rename(struct net_device *dev) void hsr_debugfs_rename(struct net_device *dev)
{ {
struct hsr_priv *priv = netdev_priv(dev); struct hsr_priv *priv = netdev_priv(dev);
struct dentry *d; int err;
d = debugfs_rename(hsr_debugfs_root_dir, priv->node_tbl_root, err = debugfs_change_name(priv->node_tbl_root, "%s", dev->name);
hsr_debugfs_root_dir, dev->name); if (err)
if (IS_ERR(d))
netdev_warn(dev, "failed to rename\n"); netdev_warn(dev, "failed to rename\n");
else
priv->node_tbl_root = d;
} }
/* hsr_debugfs_init - create hsr node_table file for dumping /* hsr_debugfs_init - create hsr node_table file for dumping

View File

@ -1025,16 +1025,7 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
{ {
struct dentry *dir; debugfs_change_name(sdata->vif.debugfs_dir, "netdev:%s", sdata->name);
char buf[10 + IFNAMSIZ];
dir = sdata->vif.debugfs_dir;
if (IS_ERR_OR_NULL(dir))
return;
sprintf(buf, "netdev:%s", sdata->name);
debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
} }
void ieee80211_debugfs_recreate_netdev(struct ieee80211_sub_if_data *sdata, void ieee80211_debugfs_recreate_netdev(struct ieee80211_sub_if_data *sdata,

View File

@ -143,10 +143,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
if (result) if (result)
return result; return result;
if (!IS_ERR_OR_NULL(rdev->wiphy.debugfsdir)) debugfs_change_name(rdev->wiphy.debugfsdir, "%s", newname);
debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent, newname);
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);