Hello everyone,
This patch has been floating around for some time, and I've been
building other reiserfs speedups on top of it. It does two things:
1) allows the FS write_super function to leave the super dirty without
looping endlessly in sync_supers(). This is based on code sent to me by
Hugh Dickins, and it helps all the filesystems avoid looping in
sync_supers() under load.
2) adds a commit_super() call to struct super_operations(). This allows
the journaled filesystems to differentiate between calls from sync() and
calls from kupdated.
Below are just the hunks that change VFS code, against 2.4.19-final.
The reiserfs bits will come once this gets accepted. Please review and
throw something blunt at me if you don't want this in the kernel.
-chris
diff -urN --exclude *.orig --exclude *.rej parent/fs/buffer.c comp/fs/buffer.c
--- parent/fs/buffer.c Sun Jun 2 23:14:55 2002
+++ comp/fs/buffer.c Sun Jun 2 23:14:47 2002
@@ -328,6 +328,8 @@
lock_super(sb);
if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
sb->s_op->write_super(sb);
+ if (sb->s_op && sb->s_op->commit_super)
+ sb->s_op->commit_super(sb);
unlock_super(sb);
unlock_kernel();
@@ -347,7 +349,7 @@
lock_kernel();
sync_inodes(dev);
DQUOT_SYNC(dev);
- sync_supers(dev);
+ commit_supers(dev);
unlock_kernel();
return sync_buffers(dev, 1);
diff -urN --exclude *.orig --exclude *.rej parent/fs/super.c comp/fs/super.c
--- parent/fs/super.c Sun Jun 2 23:14:54 2002
+++ comp/fs/super.c Sun Jun 2 23:14:47 2002
@@ -396,6 +396,7 @@
struct file_system_type *fs = s->s_type;
spin_lock(&sb_lock);
+ s->s_type = NULL;
list_del(&s->s_list);
list_del(&s->s_instances);
spin_unlock(&sb_lock);
@@ -440,12 +441,23 @@
unlock_super(sb);
}
+static inline void commit_super(struct super_block *sb)
+{
+ lock_super(sb);
+ if (sb->s_root && sb->s_dirt)
+ if (sb->s_op && sb->s_op->write_super)
+ sb->s_op->write_super(sb);
+ if (sb->s_op && sb->s_op->commit_super)
+ sb->s_op->commit_super(sb);
+ unlock_super(sb);
+}
+
/*
* Note: check the dirty flag before waiting, so we don't
* hold up the sync while mounting a device. (The newly
* mounted device won't need syncing.)
*/
-void sync_supers(kdev_t dev)
+static void dirty_super_op(kdev_t dev, void (*func)(struct super_block *))
{
struct super_block * sb;
@@ -453,25 +465,41 @@
sb = get_super(dev);
if (sb) {
if (sb->s_dirt)
- write_super(sb);
+ func(sb);
drop_super(sb);
}
return;
}
-restart:
spin_lock(&sb_lock);
+restart:
sb = sb_entry(super_blocks.next);
- while (sb != sb_entry(&super_blocks))
+ while (sb != sb_entry(&super_blocks)) {
if (sb->s_dirt) {
sb->s_count++;
spin_unlock(&sb_lock);
down_read(&sb->s_umount);
- write_super(sb);
- drop_super(sb);
- goto restart;
- } else
- sb = sb_entry(sb->s_list.next);
+ func(sb);
+ up_read(&sb->s_umount);
+ spin_lock(&sb_lock);
+ if (!--sb->s_count) {
+ destroy_super(sb);
+ goto restart;
+ } else if (!sb->s_type)
+ goto restart;
+ }
+ sb = sb_entry(sb->s_list.next);
+ }
spin_unlock(&sb_lock);
+}
+
+void sync_supers(kdev_t dev)
+{
+ dirty_super_op(dev, write_super);
+}
+
+void commit_supers(kdev_t dev)
+{
+ dirty_super_op(dev, commit_super);
}
/**
diff -urN --exclude *.orig --exclude *.rej parent/include/linux/fs.h comp/include/linux/fs.h
--- parent/include/linux/fs.h Sun Jun 2 23:14:55 2002
+++ comp/include/linux/fs.h Sun Jun 2 23:14:47 2002
@@ -920,6 +920,7 @@
struct dentry * (*fh_to_dentry)(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
int (*dentry_to_fh)(struct dentry *, __u32 *fh, int *lenp, int need_parent);
int (*show_options)(struct seq_file *, struct vfsmount *);
+ void (*commit_super) (struct super_block *);
};
/* Inode state bits.. */
@@ -1236,6 +1237,7 @@
extern int filemap_fdatasync(struct address_space *);
extern int filemap_fdatawait(struct address_space *);
extern void sync_supers(kdev_t);
+extern void commit_supers(kdev_t);
extern int bmap(struct inode *, int);
extern int notify_change(struct dentry *, struct iattr *);
extern int permission(struct inode *, int);
On Mon, Aug 05, 2002 at 01:34:53PM -0400, Chris Mason wrote:
> Below are just the hunks that change VFS code, against 2.4.19-final.
> The reiserfs bits will come once this gets accepted. Please review and
> throw something blunt at me if you don't want this in the kernel.
Could you please get that tested in 2.5 or -ac first?
On Mon, 2002-08-05 at 13:37, Christoph Hellwig wrote:
> On Mon, Aug 05, 2002 at 01:34:53PM -0400, Chris Mason wrote:
> > Below are just the hunks that change VFS code, against 2.4.19-final.
> > The reiserfs bits will come once this gets accepted. Please review and
> > throw something blunt at me if you don't want this in the kernel.
>
> Could you please get that tested in 2.5 or -ac first?
It is being tested in the suse kernel now. Alan, if you want it, I'll
rediff against 2.4.19-ac.
-chris
On Mon, 2002-08-05 at 18:48, Chris Mason wrote:
> On Mon, 2002-08-05 at 13:37, Christoph Hellwig wrote:
> > On Mon, Aug 05, 2002 at 01:34:53PM -0400, Chris Mason wrote:
> > > Below are just the hunks that change VFS code, against 2.4.19-final.
> > > The reiserfs bits will come once this gets accepted. Please review and
> > > throw something blunt at me if you don't want this in the kernel.
> >
> > Could you please get that tested in 2.5 or -ac first?
>
> It is being tested in the suse kernel now. Alan, if you want it, I'll
> rediff against 2.4.19-ac.
I'm chasing IDE stuff, now is the wrong moment for file system stuff
On Monday 05 August 2002 19:34, Chris Mason wrote:
> 2) adds a commit_super() call to struct super_operations(). This allows
> the journaled filesystems to differentiate between calls from sync() and
> calls from kupdated.
Thankyou.
--
Daniel