Skip to content

Commit 40f48f8

Browse files
committed
Merge tag 'configfs-6.13-2024-11-19' of git://git.infradead.org/users/hch/configfs
Pull configfs updates from Christoph Hellwig: - remove unused code (Dr. David Alan Gilbert) - improve item creation performance (Seamus Connor) * tag 'configfs-6.13-2024-11-19' of git://git.infradead.org/users/hch/configfs: configfs: improve item creation performance configfs: remove unused configfs_hash_and_remove
2 parents fc39fb5 + 84147f4 commit 40f48f8

File tree

3 files changed

+34
-37
lines changed

3 files changed

+34
-37
lines changed

fs/configfs/configfs_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ struct configfs_dirent {
5555
#define CONFIGFS_USET_IN_MKDIR 0x0200
5656
#define CONFIGFS_USET_CREATING 0x0400
5757
#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)
58+
#define CONFIGFS_PINNED \
59+
(CONFIGFS_ROOT | CONFIGFS_DIR | CONFIGFS_ITEM_LINK)
5860

5961
extern struct mutex configfs_symlink_mutex;
6062
extern spinlock_t configfs_dirent_lock;
@@ -73,8 +75,6 @@ extern int configfs_make_dirent(struct configfs_dirent *, struct dentry *,
7375
void *, umode_t, int, struct configfs_fragment *);
7476
extern int configfs_dirent_is_ready(struct configfs_dirent *);
7577

76-
extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
77-
7878
extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
7979
extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
8080
extern int configfs_setattr(struct mnt_idmap *idmap,

fs/configfs/dir.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,17 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
207207
return ERR_PTR(-ENOENT);
208208
}
209209
sd->s_frag = get_fragment(frag);
210-
list_add(&sd->s_sibling, &parent_sd->s_children);
210+
211+
/*
212+
* configfs_lookup scans only for unpinned items. s_children is
213+
* partitioned so that configfs_lookup can bail out early.
214+
* CONFIGFS_PINNED and CONFIGFS_NOT_PINNED are not symmetrical. readdir
215+
* cursors still need to be inserted at the front of the list.
216+
*/
217+
if (sd->s_type & CONFIGFS_PINNED)
218+
list_add_tail(&sd->s_sibling, &parent_sd->s_children);
219+
else
220+
list_add(&sd->s_sibling, &parent_sd->s_children);
211221
spin_unlock(&configfs_dirent_lock);
212222

213223
return sd;
@@ -220,10 +230,11 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
220230
*
221231
* called with parent inode's i_mutex held
222232
*/
223-
static int configfs_dirent_exists(struct configfs_dirent *parent_sd,
224-
const unsigned char *new)
233+
static int configfs_dirent_exists(struct dentry *dentry)
225234
{
226-
struct configfs_dirent * sd;
235+
struct configfs_dirent *parent_sd = dentry->d_parent->d_fsdata;
236+
const unsigned char *new = dentry->d_name.name;
237+
struct configfs_dirent *sd;
227238

228239
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
229240
if (sd->s_element) {
@@ -289,10 +300,6 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
289300

290301
BUG_ON(!item);
291302

292-
error = configfs_dirent_exists(p->d_fsdata, dentry->d_name.name);
293-
if (unlikely(error))
294-
return error;
295-
296303
error = configfs_make_dirent(p->d_fsdata, dentry, item, mode,
297304
CONFIGFS_DIR | CONFIGFS_USET_CREATING,
298305
frag);
@@ -451,6 +458,18 @@ static struct dentry * configfs_lookup(struct inode *dir,
451458

452459
spin_lock(&configfs_dirent_lock);
453460
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
461+
462+
/*
463+
* s_children is partitioned, see configfs_new_dirent. The first
464+
* pinned item indicates we can stop scanning.
465+
*/
466+
if (sd->s_type & CONFIGFS_PINNED)
467+
break;
468+
469+
/*
470+
* Note: CONFIGFS_PINNED and CONFIGFS_NOT_PINNED are asymmetric.
471+
* there may be a readdir cursor in this list
472+
*/
454473
if ((sd->s_type & CONFIGFS_NOT_PINNED) &&
455474
!strcmp(configfs_get_name(sd), dentry->d_name.name)) {
456475
struct configfs_attribute *attr = sd->s_element;
@@ -1885,8 +1904,11 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
18851904
if (dentry) {
18861905
d_add(dentry, NULL);
18871906

1888-
err = configfs_attach_group(sd->s_element, &group->cg_item,
1889-
dentry, frag);
1907+
err = configfs_dirent_exists(dentry);
1908+
if (!err)
1909+
err = configfs_attach_group(sd->s_element,
1910+
&group->cg_item,
1911+
dentry, frag);
18901912
if (err) {
18911913
BUG_ON(d_inode(dentry));
18921914
d_drop(dentry);

fs/configfs/inode.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -216,28 +216,3 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
216216
spin_unlock(&dentry->d_lock);
217217
}
218218
}
219-
220-
void configfs_hash_and_remove(struct dentry * dir, const char * name)
221-
{
222-
struct configfs_dirent * sd;
223-
struct configfs_dirent * parent_sd = dir->d_fsdata;
224-
225-
if (d_really_is_negative(dir))
226-
/* no inode means this hasn't been made visible yet */
227-
return;
228-
229-
inode_lock(d_inode(dir));
230-
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
231-
if (!sd->s_element)
232-
continue;
233-
if (!strcmp(configfs_get_name(sd), name)) {
234-
spin_lock(&configfs_dirent_lock);
235-
list_del_init(&sd->s_sibling);
236-
spin_unlock(&configfs_dirent_lock);
237-
configfs_drop_dentry(sd, dir);
238-
configfs_put(sd);
239-
break;
240-
}
241-
}
242-
inode_unlock(d_inode(dir));
243-
}

0 commit comments

Comments
 (0)