Skip to content

Commit 4b93688

Browse files
author
Nick Piggin
committed
fs: improve scalability of pseudo filesystems
Regardless of how much we possibly try to scale dcache, there is likely always going to be some fundamental contention when adding or removing children under the same parent. Pseudo filesystems do not seem need to have connected dentries because by definition they are disconnected. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
1 parent 873feea commit 4b93688

File tree

5 files changed

+16
-3
lines changed

5 files changed

+16
-3
lines changed

fs/anon_inodes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct file *anon_inode_getfile(const char *name,
102102
this.name = name;
103103
this.len = strlen(name);
104104
this.hash = 0;
105-
path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
105+
path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
106106
if (!path.dentry)
107107
goto err_module;
108108

fs/dcache.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,18 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
13301330
}
13311331
EXPORT_SYMBOL(d_alloc);
13321332

1333+
struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
1334+
{
1335+
struct dentry *dentry = d_alloc(NULL, name);
1336+
if (dentry) {
1337+
dentry->d_sb = sb;
1338+
dentry->d_parent = dentry;
1339+
dentry->d_flags |= DCACHE_DISCONNECTED;
1340+
}
1341+
return dentry;
1342+
}
1343+
EXPORT_SYMBOL(d_alloc_pseudo);
1344+
13331345
struct dentry *d_alloc_name(struct dentry *parent, const char *name)
13341346
{
13351347
struct qstr q;

fs/pipe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ struct file *create_write_pipe(int flags)
999999
goto err;
10001000

10011001
err = -ENOMEM;
1002-
path.dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
1002+
path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
10031003
if (!path.dentry)
10041004
goto err_inode;
10051005
path.mnt = mntget(pipe_mnt);

include/linux/dcache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op
211211

212212
/* allocate/de-allocate */
213213
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
214+
extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
214215
extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
215216
extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
216217
extern struct dentry * d_obtain_alias(struct inode *);

net/socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
361361
if (unlikely(fd < 0))
362362
return fd;
363363

364-
path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
364+
path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
365365
if (unlikely(!path.dentry)) {
366366
put_unused_fd(fd);
367367
return -ENOMEM;

0 commit comments

Comments
 (0)