From: Jan Blunck <j.blunck@tu-harburg.de>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Andrew Morton <akpm@osdl.org>,
Linux-Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] ramfs: pretend dirent sizes
Date: Tue, 19 Jul 2005 11:46:37 +0200 [thread overview]
Message-ID: <42DCCBFD.6070504@tu-harburg.de> (raw)
In-Reply-To: <Pine.LNX.4.58.0507151151360.19183@g5.osdl.org>
[-- Attachment #1: Type: text/plain, Size: 638 bytes --]
Linus Torvalds wrote:
>
> I really think you should update the "simple_xxx()" functions instead, and
> thus make this happen for _any_ filesystem that uses the simple fs helper
> functions.
>
Ok, I revised the patch. This is just the first step with changes to
libfs and ramfs.
To move the directory i_size handling completely to libfs it is
necessary to allocate the inodes in libfs. Therefore, simple_get_inode()
and simple_mknod_init() (honestly, I don't like that name) are
introduced. simple_mknod_init() uses a callback mechanism to initialize
the file system specific stuff of the inodes.
What do you think of it?
Jan
[-- Attachment #2: libfs_bogo_dirent_size.diff --]
[-- Type: text/x-patch, Size: 4223 bytes --]
fs/libfs.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/fs.h | 7 +++++
2 files changed, 72 insertions(+), 1 deletion(-)
Index: linux-2.6/fs/libfs.c
===================================================================
--- linux-2.6.orig/fs/libfs.c
+++ linux-2.6/fs/libfs.c
@@ -238,13 +238,72 @@ Enomem:
return ERR_PTR(-ENOMEM);
}
+struct inode *simple_get_inode(struct super_block *sb, int mode,
+ int (*init)(struct inode *, void *), void *arg)
+{
+ struct inode * inode = new_inode(sb);
+
+ if (!inode)
+ return ERR_PTR(-ENOSPC);
+
+ inode->i_mode = mode;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_blksize = sb->s_blocksize;
+ inode->i_blocks = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+ if (S_ISDIR(mode)) {
+ /* directory inodes start with i_nlink == 2 (for "." entry) */
+ inode->i_nlink++;
+ /* i_size for "." and ".." */
+ inode->i_size = 2 * SIMPLE_BOGO_DIRENT_SIZE;
+ }
+
+ if (init) {
+ int error = init(inode, arg);
+ if (error) {
+ iput(inode);
+ inode = ERR_PTR(error);
+ }
+ }
+
+ return inode;
+}
+
+int simple_mknod_init(struct inode *dir, struct dentry *dentry, int mode,
+ int (*init)(struct inode *, void *), void *arg)
+{
+ struct inode * inode;
+
+ inode = simple_get_inode(dir->i_sb, mode, init, arg);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ if (dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
+ if (S_ISDIR(mode))
+ inode->i_mode |= S_ISGID;
+ }
+
+ if (S_ISDIR(mode))
+ dir->i_nlink++;
+
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ dir->i_size += SIMPLE_BOGO_DIRENT_SIZE;
+ d_instantiate(dentry, inode);
+ dget(dentry); /* pin the dentry in core */
+ return 0;
+}
+
int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
struct inode *inode = old_dentry->d_inode;
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME;
inode->i_nlink++;
atomic_inc(&inode->i_count);
+ dir->i_size += SIMPLE_BOGO_DIRENT_SIZE;
dget(dentry);
d_instantiate(dentry, inode);
return 0;
@@ -276,6 +335,7 @@ int simple_unlink(struct inode *dir, str
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
inode->i_nlink--;
+ dir->i_size -= SIMPLE_BOGO_DIRENT_SIZE;
dput(dentry);
return 0;
}
@@ -311,6 +371,8 @@ int simple_rename(struct inode *old_dir,
old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
new_dir->i_mtime = inode->i_ctime = CURRENT_TIME;
+ old_dir->i_size -= SIMPLE_BOGO_DIRENT_SIZE;
+ new_dir->i_size += SIMPLE_BOGO_DIRENT_SIZE;
return 0;
}
@@ -629,6 +691,8 @@ EXPORT_SYMBOL(simple_empty);
EXPORT_SYMBOL(d_alloc_name);
EXPORT_SYMBOL(simple_fill_super);
EXPORT_SYMBOL(simple_getattr);
+EXPORT_SYMBOL(simple_get_inode);
+EXPORT_SYMBOL(simple_mknod_init);
EXPORT_SYMBOL(simple_link);
EXPORT_SYMBOL(simple_lookup);
EXPORT_SYMBOL(simple_pin_fs);
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h
+++ linux-2.6/include/linux/fs.h
@@ -1624,6 +1624,11 @@ extern loff_t dcache_dir_lseek(struct fi
extern int dcache_readdir(struct file *, void *, filldir_t);
extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int simple_statfs(struct super_block *, struct kstatfs *);
+extern struct inode *simple_get_inode(struct super_block *, int ,
+ int (*init)(struct inode *, void *),
+ void *);
+extern int simple_mknod_init(struct inode *, struct dentry *, int ,
+ int (*init)(struct inode *, void *), void *);
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
@@ -1744,6 +1749,8 @@ ssize_t simple_attr_read(struct file *fi
ssize_t simple_attr_write(struct file *file, const char __user *buf,
size_t len, loff_t *ppos);
+/* Pretend that each dirent is of this size in simple directories */
+#define SIMPLE_BOGO_DIRENT_SIZE 20
#ifdef CONFIG_SECURITY
static inline char *alloc_secdata(void)
[-- Attachment #3: ramfs_bogo_dirent_size.diff --]
[-- Type: text/x-patch, Size: 4622 bytes --]
fs/ramfs/inode.c | 118 ++++++++++++++++++++++---------------------------------
1 files changed, 48 insertions(+), 70 deletions(-)
Index: linux-2.6/fs/ramfs/inode.c
===================================================================
--- linux-2.6.orig/fs/ramfs/inode.c
+++ linux-2.6/fs/ramfs/inode.c
@@ -50,40 +50,40 @@ static struct backing_dev_info ramfs_bac
BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
};
-struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
-{
- struct inode * inode = new_inode(sb);
-
- if (inode) {
- inode->i_mode = mode;
- inode->i_uid = current->fsuid;
- inode->i_gid = current->fsgid;
- inode->i_blksize = PAGE_CACHE_SIZE;
- inode->i_blocks = 0;
- inode->i_mapping->a_ops = &ramfs_aops;
- inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- switch (mode & S_IFMT) {
- default:
- init_special_inode(inode, mode, dev);
- break;
- case S_IFREG:
- inode->i_op = &ramfs_file_inode_operations;
- inode->i_fop = &ramfs_file_operations;
- break;
- case S_IFDIR:
- inode->i_op = &ramfs_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
-
- /* directory inodes start off with i_nlink == 2 (for "." entry) */
- inode->i_nlink++;
- break;
- case S_IFLNK:
- inode->i_op = &page_symlink_inode_operations;
- break;
- }
+struct ramfs_init_args {
+ dev_t dev;
+ const char *name;
+};
+
+static int ramfs_inode_init(struct inode *inode, void *__arg)
+{
+ struct ramfs_init_args *arg = (struct ramfs_init_args *)__arg;
+ int len;
+ int err = 0;
+
+ inode->i_mapping->a_ops = &ramfs_aops;
+ inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFREG:
+ inode->i_op = &ramfs_file_inode_operations;
+ inode->i_fop = &ramfs_file_operations;
+ break;
+ case S_IFDIR:
+ inode->i_op = &ramfs_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+ break;
+ case S_IFLNK:
+ inode->i_op = &page_symlink_inode_operations;
+ len = strlen(arg->symname)+1;
+ err = page_symlink(inode, arg->symname, len);
+ break;
+ default:
+ init_special_inode(inode, inode->i_mode, arg->dev);
+ break;
}
- return inode;
+
+ return err;
}
/*
@@ -93,53 +93,31 @@ struct inode *ramfs_get_inode(struct sup
static int
ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
{
- struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev);
- int error = -ENOSPC;
+ struct ramfs_init_args args = { .dev = dev };
- if (inode) {
- if (dir->i_mode & S_ISGID) {
- inode->i_gid = dir->i_gid;
- if (S_ISDIR(mode))
- inode->i_mode |= S_ISGID;
- }
- d_instantiate(dentry, inode);
- dget(dentry); /* Extra count - pin the dentry in core */
- error = 0;
- }
- return error;
+ return simple_mknod_init(dir, dentry, mode,
+ ramfs_inode_init, (void *) &args);
}
static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
- int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);
- if (!retval)
- dir->i_nlink++;
- return retval;
+ return simple_mknod_init(dir, dentry, mode|S_IFDIR,
+ ramfs_inode_init, NULL);
}
static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
{
- return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);
+ return simple_mknod_init(dir, dentry, mode|S_IFREG,
+ ramfs_inode_init, NULL);
}
-static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+static int ramfs_symlink(struct inode *dir, struct dentry *dentry,
+ const char *name)
{
- struct inode *inode;
- int error = -ENOSPC;
+ struct ramfs_init_args args = { .name = name };
- inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
- if (inode) {
- int l = strlen(symname)+1;
- error = page_symlink(inode, symname, l);
- if (!error) {
- if (dir->i_mode & S_ISGID)
- inode->i_gid = dir->i_gid;
- d_instantiate(dentry, inode);
- dget(dentry);
- } else
- iput(inode);
- }
- return error;
+ return simple_mknod_init(dir, dentry, S_IFLNK|S_IRWXUGO,
+ ramfs_inode_init, (void *) &args);
}
static struct address_space_operations ramfs_aops = {
@@ -189,9 +167,9 @@ static int ramfs_fill_super(struct super
sb->s_magic = RAMFS_MAGIC;
sb->s_op = &ramfs_ops;
sb->s_time_gran = 1;
- inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
- if (!inode)
- return -ENOMEM;
+ inode = simple_get_inode(sb, S_IFDIR|0755, ramfs_inode_init, NULL);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode); // -ENOMEM
root = d_alloc_root(inode);
if (!root) {
next prev parent reply other threads:[~2005-07-19 9:44 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-15 3:01 [PATCH] ramfs: pretend dirent sizes Jan Blunck
2005-07-15 3:11 ` Andrew Morton
2005-07-15 10:16 ` Jan Blunck
2005-07-15 18:52 ` Linus Torvalds
2005-07-16 0:39 ` Chris Wedgwood
2005-07-19 9:28 ` Jan Blunck
2005-07-19 16:16 ` Chris Wedgwood
2005-07-19 18:22 ` Jan Blunck
2005-07-19 18:32 ` Chris Wedgwood
2005-07-19 19:14 ` Jan Blunck
2005-07-19 19:16 ` Chris Wedgwood
2005-07-20 11:21 ` Jörn Engel
2005-07-20 18:11 ` Chris Wedgwood
2005-07-20 18:48 ` Jan Blunck
2005-07-20 18:52 ` Peter Staubach
2005-07-21 7:26 ` Jörn Engel
2005-07-21 7:20 ` Jörn Engel
2005-07-21 7:25 ` Chris Wedgwood
2005-07-21 7:27 ` Jörn Engel
2005-07-20 18:24 ` Jan Blunck
2005-07-20 18:50 ` Peter Staubach
2005-07-19 9:46 ` Jan Blunck [this message]
[not found] <4qoKs-6yv-13@gated-at.bofh.it>
[not found] ` <4qoU5-6CQ-3@gated-at.bofh.it>
[not found] ` <4qvsI-32Y-17@gated-at.bofh.it>
2005-07-15 13:12 ` Bodo Eggert
2005-07-19 9:13 ` Jan Blunck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42DCCBFD.6070504@tu-harburg.de \
--to=j.blunck@tu-harburg.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.