From 1fbb09f4f83e90f32154e87630a89492ce07246a Mon Sep 17 00:00:00 2001 From: braam Date: Thu, 30 Dec 1999 06:12:59 +0000 Subject: [PATCH] Add flush.c with a rough flushing daemon and the figures subdirectory. More editing done in the OBDspec. --- lustre/include/linux/obdfs.h | 8 ++ lustre/obdfs/Makefile | 2 +- lustre/obdfs/flushd.c | 175 +++++++++++++++++++++++++++++++++++++++++++ lustre/obdfs/super.c | 8 ++ 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 lustre/obdfs/flushd.c diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index cfc9f85..3cc202c 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -17,6 +17,9 @@ /* super.c */ void obdfs_read_inode(struct inode *inode); +/* flush.c */ +int flushd_init(void); + /* rw.c */ int obdfs_init_wreqcache(void); @@ -44,6 +47,11 @@ int obdfs_check_dir_entry (const char * function, struct inode * dir, int obdfs_readlink (struct dentry *, char *, int); struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int); +struct obdfs_super_entry { + struct list_head sl_chain; + struct obdfs_sb_info *sbi; +}; + struct obdfs_wreq { struct list_head wb_list; /* linked list of req's */ struct inode *wb_inode; /* dentry referenced */ diff --git a/lustre/obdfs/Makefile b/lustre/obdfs/Makefile index dd72518..eb60ab1 100644 --- a/lustre/obdfs/Makefile +++ b/lustre/obdfs/Makefile @@ -5,6 +5,6 @@ include ../config.mk MODULE = obdfs.o -CFILES=file.c dir.c sysctl.c super.c rw.c namei.c symlink.c +CFILES= flush.c file.c dir.c sysctl.c super.c rw.c namei.c symlink.c include ../make.rules diff --git a/lustre/obdfs/flushd.c b/lustre/obdfs/flushd.c new file mode 100644 index 0000000..19c7437 --- /dev/null +++ b/lustre/obdfs/flushd.c @@ -0,0 +1,175 @@ +/* + * OBDFS Super operations - also used for Lustre file system + * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copryright (C) 1999 Stelias Computing Inc. + * Copryright (C) 1999 Seagate Technology Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + + +struct { + int nfract; /* Percentage of buffer cache dirty to + activate bdflush */ + int ndirty; /* Maximum number of dirty blocks to write out per + wake-cycle */ + int nrefill; /* Number of clean buffers to try to obtain + each time we call refill */ + int nref_dirt; /* Dirty buffer threshold for activating bdflush + when trying to refill buffers. */ + int interval; /* jiffies delay between kupdate flushes */ + int age_buffer; /* Time for normal buffer to age before we flush it */ + int age_super; /* Time for superblock to age before we flush it */ +} pupd_prm = {40, 500, 64, 256, 5*HZ, 30*HZ, 5*HZ }; + + +atatic void obdfs_flush_reqs(struct obdfs_super_info *sbi, int wait, + int check_time) +{ + struct list_head *wr; + struct pg_req *req; + + wr = &si.s_wr_head; + while ( (wr = wr->next) != &si.s_wr_head ) { + req = list_entry(wr, struct pg_req, rq_list); + + if (!check_time || + req->rq_jiffies <= (jiffies - pup_rpm.age_buffer)) { + /* write request out to disk */ + obdfs_write_page(req->inode, req->page); + } + + } + +} + + +static void obdfs_flush_dirty_pages(int check_time) +{ + struct list_head *sl; + + sl = &obdfs_super_list; + while ( (sl = sl->next) != &obdfs_super_listhead ) { + struct obdfs_super_entry *entry = + list_entry(sl, struct obdfs_super_entry, sl_chain); + struct obdfs_sb_info *sbi = sl->sl_sbi; + + /* walk write requests here */ + obdfs_flush_reqs(sbi, 0); + } + + /* again, but now we wait for completion */ + sl = &obdfs_super_listhead; + while ( (sl = sl->next) != &obdfs_super_listhead ) { + struct obdfs_super_list *entry = + list_entry(sl, struct obdfs_super_list, sl_chain); + struct super_block *sb = sl->sl_sb; + + /* walk write requests here */ + si = &sb->u.generic; + obdfs_flush_reqs(si, 1); + } +} + +static struct task_struct *pupdatd; + +static int pupdate(void) +{ + struct task_struct * tsk = current; + int interval; + + pupdated = current; + tsk->session = 1; + tsk->pgrp = 1; + strcpy(tsk->comm, "pupdate"); + + /* sigstop and sigcont will stop and wakeup kupdate */ + spin_lock_irq(&tsk->sigmask_lock); + sigfillset(&tsk->blocked); + siginitsetinv(¤t->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + + for (;;) { + /* update interval */ + interval = pupd_prm.interval; + if (interval) + { + tsk->state = TASK_INTERRUPTIBLE; + schedule_timeout(interval); + } + else + { + stop_pupdate: + tsk->state = TASK_STOPPED; + schedule(); /* wait for SIGCONT */ + } + /* check for sigstop */ + if (signal_pending(tsk)) + { + int stopped = 0; + spin_lock_irq(&tsk->sigmask_lock); + if (sigismember(&tsk->signal, SIGSTOP)) + { + sigdelset(&tsk->signal, SIGSTOP); + stopped = 1; + } + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + if (stopped) + goto stop_pupdate; + } + printk("pupdate() activated...\n"); + /* flush_inodes(); */ + obdfs_flush_dirty_pages(1); + } +} + + +int flushd_init(void) +{ + /* kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); */ + kernel_thread(pupdate, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + return 0; +} + +int flushd_cleanup(void) +{ + /* this should deliver a signal to */ + + + /* XXX Andreas, we will do this later, for now, you must kill + pupdated with a SIGSTOP from userland, before unloading obdfs.o + */ + if (pupdated) { + /* send updated a STOP signal */ + /* then let it run at least once, before continuing */ + 1; + } + +} diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index 498e2f4..293f265 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -55,6 +55,8 @@ struct super_operations obdfs_super_operations = NULL /* remount_fs */ }; +struct list_head obdfs_super_list; + static char *obdfs_read_opt(const char *opt, char *data) { char *value; @@ -120,6 +122,8 @@ static int obdfs_getdev(char *devpath, int *dev) return 0; } + +/* XXX allocate a super_entry, and add the super to the obdfs_super_list */ static struct super_block * obdfs_read_super(struct super_block *sb, void *data, int silent) { @@ -265,6 +269,7 @@ static struct super_block * obdfs_read_super(struct super_block *sb, return NULL; } +/* XXX remove the super to the obdfs_super_list */ static void obdfs_put_super(struct super_block *sb) { struct obdfs_sb_info *sbi; @@ -394,10 +399,13 @@ int init_obdfs(void) obdfs_sysctl_init(); + INIT_LIST_HEAD(&obdfs_super_list); err = obdfs_init_wreqcache(); if (err) return err; + flushd_init(); + return register_filesystem(&obdfs_fs_type); } -- 1.8.3.1