2002-08-05 17:30:06

by Chris Mason

[permalink] [raw]
Subject: [PATCH] write_super is not for syncing (take 3)

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);


2002-08-05 17:33:33

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] write_super is not for syncing (take 3)

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?

2002-08-05 17:43:58

by Chris Mason

[permalink] [raw]
Subject: Re: [PATCH] write_super is not for syncing (take 3)

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


2002-08-05 19:10:53

by Alan

[permalink] [raw]
Subject: Re: [PATCH] write_super is not for syncing (take 3)

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

2002-08-09 12:28:52

by Daniel Phillips

[permalink] [raw]
Subject: Re: [PATCH] write_super is not for syncing (take 3)

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