Whamcloud - gitweb
Changes for the flushdaemon.
authorbraam <braam>
Mon, 10 Jan 2000 14:50:06 +0000 (14:50 +0000)
committerbraam <braam>
Mon, 10 Jan 2000 14:50:06 +0000 (14:50 +0000)
Page cache now per inode.  Other changes to follow.

lustre/include/linux/obdfs.h
lustre/obdclass/class_obd.c
lustre/obdclass/genops.c
lustre/obdfs/Makefile
lustre/obdfs/flushd.c
lustre/obdfs/namei.c
lustre/obdfs/rw.c
lustre/obdfs/super.c

index 04c0f5f..cad8f07 100644 (file)
@@ -23,8 +23,8 @@ int flushd_init(void);
 
 /* rw.c */
 int obdfs_do_writepage(struct inode *, struct page *, int sync);
-int obdfs_init_wreqcache(void);
-void obdfs_cleanup_wreqcache(void);
+int obdfs_init_pgrqcache(void);
+void obdfs_cleanup_pgrqcache(void);
 int obdfs_readpage(struct dentry *dentry, struct page *page);
 int obdfs_writepage(struct dentry *dentry, struct page *page);
 struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create, int locked);
@@ -49,15 +49,24 @@ 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_info {
+       struct list_head s_wr_head;
+};
+
+
+/* list of all OBDFS super blocks  */
+struct list_head obdfs_super_list;
 struct obdfs_super_entry {
        struct list_head sl_chain;
-       struct obdfs_sb_info *sbi;
+       struct obdfs_super_info *sl_sbi;
 };
 
-struct obdfs_wreq {
-       struct list_head         wb_list;       /* linked list of req's */
-       struct inode            *wb_inode;      /* dentry referenced */
-       struct page             *wb_page;       /* page to be written */
+struct obdfs_pgrq {
+       struct list_head         rq_list;       /* linked list of req's */
+       unsigned long          rq_jiffies;
+       struct inode            *rq_inode;      /* dentry referenced */
+       struct page             *rq_page;       /* page to be written */
 };
 
 struct obdfs_sb_info {
@@ -72,18 +81,14 @@ struct obdfs_sb_info {
 
 struct obdfs_inode_info {
        int              oi_flags;
-       struct list_head oi_list;
+       struct list_head oi_pages;
        char            *oi_inline;
 };
 
-#define OBD_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip))
 
-/* this was used when the list was in the superblock
-#define OBD_LIST(inode)        (((struct obdfs_sb_info *)(&(inode)->i_sb->u.generic_sbp))->osi_list)
-*/
-#define OBD_LIST(inode)        (OBD_INFO(inode)->oi_list)
-#define WB_NEXT(req)   ((struct obdfs_wreq *) ((req)->wb_list.next))
-#define WREQ(entry)    (list_entry(entry, struct obdfs_wreq, wb_list))
+#define OBD_LIST(inode)        (((struct obdfs_inode_info *)(&(inode)->u.generic_ip))->oi_pages)
+#define WREQ(entry)    (list_entry(entry, struct obdfs_pgrq, rq_list))
+#define OBD_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip))
 
 void obdfs_sysctl_init(void);
 void obdfs_sysctl_clean(void);
index 45d2fcf..f32917a 100644 (file)
@@ -95,7 +95,7 @@ static int obd_class_release(struct inode * inode, struct file * file)
                return -ENODEV;
        fsync_dev(inode->i_rdev);
        if (obd_dev[dev].obd_refcnt <= 0)
-               printk(KERN_ALERT "obd_class_release: refcount(%d) <= 0\n",
+               printk(KERN_ALERT "presto_psdev_release: refcount(%d) <= 0\n",
                       obd_dev[dev].obd_refcnt);
        obd_dev[dev].obd_refcnt--;
 
index 3f9801b..10a69dc 100644 (file)
@@ -260,20 +260,21 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
        lck_page(page);
        
        while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
+               obd_size count = PAGE_SIZE;
                
                page->index = index;
                rc = OBP(src_conn->oc_dev, brw)
                        (READ, src_conn, src, (char *)page_address(page), 
-                        PAGE_SIZE, (page->index) << PAGE_SHIFT, 0);
+                        &count, (page->index) << PAGE_SHIFT, 0);
 
-               if ( rc != PAGE_SIZE ) 
+               if ( rc !=  ) 
                        break;
                CDEBUG(D_INODE, "Read page %ld ...\n", page->index);
 
                rc = OBP(dst_conn->oc_dev, brw)
                        (WRITE, dst_conn, dst, (char *)page_address(page), 
-                        PAGE_SIZE, (page->index) << PAGE_SHIFT, 1);
-               if ( rc != PAGE_SIZE)
+                        &count, (page->index) << PAGE_SHIFT, 1);
+               if ( rc != 0)
                        break;
 
                CDEBUG(D_INODE, "Wrote page %ld ...\n", page->index);
index f0a7390..f83021e 100644 (file)
@@ -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 #flushd.c
+CFILES=  flushd.c rw.c file.c dir.c sysctl.c super.c namei.c symlink.c
 
 include ../make.rules
index 19c7437..e94b6bf 100644 (file)
@@ -7,25 +7,28 @@
  * Copryright (C) 1999 Seagate Technology Inc.
  *
  */
-#include <linux/config.h>
+#define __NO_VERSION__
 #include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/malloc.h>
 #include <linux/locks.h>
-#include <linux/unistd.h>
+#include <linux/errno.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/vmalloc.h>
+#include <linux/blkdev.h>
+#include <linux/sysrq.h>
+#include <linux/file.h>
+#include <linux/init.h>
+#include <linux/quotaops.h>
+#include <linux/iobuf.h>
+#include <linux/highmem.h>
 
-#include <asm/system.h>
 #include <asm/uaccess.h>
-
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-#include <asm/segment.h>
-#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
@@ -45,23 +48,24 @@ struct {
        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 };
-
+} 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) 
+/* static void obdfs_flush_reqs(struct obdfs_super_info *sbi, int wait, 
+                            
+*/
+static void obdfs_flush_reqs(struct obdfs_super_info *sbi, int check_time) 
 {
        struct list_head *wr;
-       struct pg_req *req;
+       struct obdfs_pgrq *req;
        
-       wr = &si.s_wr_head;
-       while ( (wr = wr->next) != &si.s_wr_head ) {
-               req = list_entry(wr, struct pg_req, rq_list);
+       wr = &sbi->s_wr_head;
+       while ( (wr = wr->next) != &sbi->s_wr_head ) {
+               req = list_entry(wr, struct obdfs_pgrq, rq_list);
 
                if (!check_time || 
-                   req->rq_jiffies <= (jiffies - pup_rpm.age_buffer)) {
+                   req->rq_jiffies <= (jiffies - pupd_prm.age_buffer)) {
                        /* write request out to disk */
-                       obdfs_write_page(req->inode, req->page);
+                       obdfs_do_writepage(req->rq_inode, req->rq_page, 1);
                }
 
        }
@@ -72,33 +76,33 @@ atatic void obdfs_flush_reqs(struct obdfs_super_info *sbi, int wait,
 static void obdfs_flush_dirty_pages(int check_time)
 {
        struct list_head *sl;
+       struct obdfs_super_info *sbi;
 
        sl = &obdfs_super_list;
-       while ( (sl = sl->next) != &obdfs_super_listhead ) {
+       while ( (sl = sl->next) != &obdfs_super_list ) {
                struct obdfs_super_entry *entry = 
                        list_entry(sl, struct obdfs_super_entry, sl_chain);
-               struct obdfs_sb_info *sbi = sl->sl_sbi;
+               struct obdfs_super_info *sbi = entry->sl_sbi;
 
                /* walk write requests here */
-               obdfs_flush_reqs(sbi, 0);
+               obdfs_flush_reqs(sbi, jiffies);
        }
 
        /* 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;
+       sl = &obdfs_super_list;
+       while ( (sl = sl->next) != &obdfs_super_list ) {
+               struct obdfs_super_entry *entry = 
+                       list_entry(sl, struct obdfs_super_entry, sl_chain);
+               sbi = entry->sl_sbi;
 
                /* walk write requests here */
-               si = &sb->u.generic;
-               obdfs_flush_reqs(si, 1);
+               obdfs_flush_reqs(sbi, jiffies);
        }
 }
 
-static struct task_struct *pupdatd;
+static struct task_struct *pupdated;
 
-static int pupdate(void) 
+static int pupdate(void *unused
 {
        struct task_struct * tsk = current;
        int interval;
@@ -127,6 +131,7 @@ static int pupdate(void)
                {
                stop_pupdate:
                        tsk->state = TASK_STOPPED;
+                       MOD_DEC_USE_COUNT;
                        schedule(); /* wait for SIGCONT */
                }
                /* check for sigstop */
@@ -154,6 +159,7 @@ static int pupdate(void)
 int flushd_init(void)
 {
        /*      kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); */
+       MOD_INC_USE_COUNT;
        kernel_thread(pupdate, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
        return 0;
 }
@@ -169,7 +175,11 @@ int flushd_cleanup(void)
        if (pupdated) {
                /* send updated a STOP signal */
                /* then let it run at least once, before continuing */
+
                1;
        }
 
+       /* not reached */
+       return 0;
+
 }
index 7a811c8..22fdde1 100644 (file)
@@ -485,8 +485,7 @@ struct inode *obdfs_new_inode(struct inode *dir)
                return ERR_PTR(-EIO);
        }
 
-       INIT_LIST_HEAD(&OBD_LIST(inode));
-
+       obdo_free(oa);
        EXIT;
        return inode;
 } /* obdfs_new_inode */
index 3e9825f..f58704b 100644 (file)
@@ -79,35 +79,29 @@ int obdfs_readpage(struct dentry *dentry, struct page *page)
        return rc;
 } /* obdfs_readpage */
 
-static kmem_cache_t *obdfs_wreq_cachep = NULL;
+static kmem_cache_t *obdfs_pgrq_cachep;
 
-int obdfs_init_wreqcache(void)
+int obdfs_init_pgrqcache(void)
 {
        ENTRY;
-
-       if (obdfs_wreq_cachep == NULL) {
-               obdfs_wreq_cachep = kmem_cache_create("obdfs_wreq",
-                                                     sizeof(struct obdfs_wreq),
-                                                     0, SLAB_HWCACHE_ALIGN,
-                                                     NULL, NULL);
-               if (obdfs_wreq_cachep == NULL) {
-                       EXIT;
-                       return -ENOMEM;
-               }
+       obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
+                                             sizeof(struct obdfs_pgrq),
+                                             0, SLAB_HWCACHE_ALIGN,
+                                             NULL, NULL);
+       if (obdfs_pgrq_cachep == NULL) {
+               EXIT;
+               return -ENOMEM;
        }
+
        EXIT;
        return 0;
 } /* obdfs_init_wreqcache */
 
-void obdfs_cleanup_wreqcache(void)
+void obdfs_cleanup_pgrqcache(void)
 {
-       ENTRY;
-       if (obdfs_wreq_cachep != NULL) {
-               if (kmem_cache_shrink(obdfs_wreq_cachep))
-                       printk(KERN_INFO "obdfs_cleanup_wreqcache: unable to free all of cache\n");
-       } else
-               printk(KERN_ERR "obdfs_cleanup_wreqcache: called with NULL cache pointer\n");
-       
+       if (obdfs_pgrq_cachep != NULL)
+               kmem_cache_destroy(obdfs_pgrq_cachep);
+       obdfs_pgrq_cachep = NULL;
        EXIT;
 } /* obdfs_cleanup_wreqcache */
 
@@ -116,28 +110,30 @@ void obdfs_cleanup_wreqcache(void)
  * Find a specific page in the page cache.  If it is found, we return
  * the write request struct associated with it, if not found return NULL.
  */
-static struct obdfs_wreq *obdfs_find_in_page_cache(struct inode *inode,
-                                                  struct page *page)
+static struct obdfs_pgrq *
+obdfs_find_in_page_cache(struct inode *inode, struct page *page)
 {
-       struct list_head *list_head = &OBD_LIST(inode);
-       struct obdfs_wreq *head, *wreq;
+       struct list_head *page_list = &OBD_LIST(inode);
+       struct list_head *tmp;
+       struct obdfs_pgrq *pgrq;
 
        ENTRY;
        CDEBUG(D_INODE, "looking for inode %ld page %p\n", inode->i_ino, page);
-       if (list_empty(list_head)) {
+       if (list_empty(page_list)) {
                CDEBUG(D_INODE, "empty list\n");
                EXIT;
                return NULL;
        }
-       wreq = head = WREQ(list_head->next);
-       do {
-               CDEBUG(D_INODE, "checking page %p\n", wreq->wb_page);
-               if (wreq->wb_page == page) {
+       tmp = page_list;
+       while ( (tmp = tmp->next) != page_list ) {
+               pgrq = list_entry(tmp, struct obdfs_pgrq, rq_list);
+               CDEBUG(D_INODE, "checking page %p\n", pgrq->rq_page);
+               if (pgrq->rq_page == page) {
                        CDEBUG(D_INODE, "found page %p in list\n", page);
                        EXIT;
-                       return wreq;
+                       return pgrq;
                }
-       } while ((wreq = WB_NEXT(wreq)) != head);
+       } 
 
        EXIT;
        return NULL;
@@ -147,23 +143,23 @@ static struct obdfs_wreq *obdfs_find_in_page_cache(struct inode *inode,
 /*
  * Remove a writeback request from a list
  */
-static inline int obdfs_remove_from_page_cache(struct obdfs_wreq *wreq)
+static inline int
+obdfs_remove_from_page_cache(struct obdfs_pgrq *pgrq)
 {
-       struct inode *inode = wreq->wb_inode;
-       struct page *page = wreq->wb_page;
+       struct inode *inode = pgrq->rq_inode;
+       struct page *page = pgrq->rq_page;
        int rc;
 
        ENTRY;
-       CDEBUG(D_INODE, "removing inode %ld, wreq: %p\n",
-              inode->i_ino, wreq);
-       PDEBUG(page, "REM_CACHE");
+       CDEBUG(D_INODE, "removing inode %ld page %p, pgrq: %p\n",
+              inode->i_ino, page, pgrq);
        rc = obdfs_brw(WRITE, inode, page, 1);
        /* XXX probably should handle error here somehow.  I think that
         *     ext2 also does the same thing - discard write even if error?
         */
        put_page(page);
-       list_del(&wreq->wb_list);
-       kmem_cache_free(obdfs_wreq_cachep, wreq);
+        list_del(&pgrq->rq_list);
+       kmem_cache_free(obdfs_pgrq_cachep, pgrq);
 
        EXIT;
        return rc;
@@ -174,38 +170,36 @@ static inline int obdfs_remove_from_page_cache(struct obdfs_wreq *wreq)
  */
 static int obdfs_add_to_page_cache(struct inode *inode, struct page *page)
 {
-       struct obdfs_wreq *wreq;
+       struct obdfs_pgrq *pgrq;
 
        ENTRY;
-       wreq = kmem_cache_alloc(obdfs_wreq_cachep, SLAB_KERNEL);
-       CDEBUG(D_INODE, "adding inode %ld page %p, wreq: %p\n",
-              inode->i_ino, page, wreq);
-       if (!wreq) {
+       pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
+       CDEBUG(D_INODE, "adding inode %ld page %p, pgrq: %p\n",
+              inode->i_ino, page, pgrq);
+       if (!pgrq) {
                EXIT;
                return -ENOMEM;
        }
-       memset(wreq, 0, sizeof(*wreq)); 
+       memset(pgrq, 0, sizeof(*pgrq)); 
 
-       wreq->wb_page = page;
-       wreq->wb_inode = inode;
+       pgrq->rq_page = page;
+       pgrq->rq_inode = inode;
 
-       get_page(wreq->wb_page);
-       list_add(&wreq->wb_list, &OBD_LIST(inode));
+       get_page(pgrq->rq_page);
+       list_add(&pgrq->rq_list, &OBD_LIST(inode));
 
        /* For testing purposes, we write out the page here.
         * In the future, a flush daemon will write out the page.
        return 0;
         */
-       printk(KERN_INFO "finding page in cache for write\n");
-       wreq = obdfs_find_in_page_cache(inode, page);
-       if (!wreq) {
+       pgrq = obdfs_find_in_page_cache(inode, page);
+       if (!pgrq) {
                CDEBUG(D_INODE, "XXXX Can't find page after adding it!!!\n");
                EXIT;
                return -EINVAL;
-       }
-
-       EXIT;
-       return obdfs_remove_from_page_cache(wreq);
+       } 
+               
+       return obdfs_remove_from_page_cache(pgrq);
 } /* obdfs_add_to_page_cache */
 
 
index f417d77..daaf8cb 100644 (file)
@@ -326,6 +326,7 @@ void obdfs_read_inode(struct inode *inode)
 {
        struct obdo *oa;
        int err;
+       struct obdfs_inode_info *ii;
 
        ENTRY;
        oa = obdo_alloc();
@@ -336,6 +337,10 @@ void obdfs_read_inode(struct inode *inode)
        }
        oa->o_valid = ~OBD_MD_FLOBDMD;
        oa->o_id = inode->i_ino;
+       ii = (struct obdfs_inode_info *)(&inode->u.generic_ip);
+       INIT_LIST_HEAD(&ii->oi_pages);
+
+       
        err = IOPS(inode, getattr)(IID(inode), oa);
        if (err) {
                printk("obdfs_read_inode: obd_getattr fails (%d)\n", err);
@@ -473,14 +478,11 @@ int init_obdfs(void)
        obdfs_sysctl_init();
 
        INIT_LIST_HEAD(&obdfs_super_list);
-       err = obdfs_init_wreqcache();
+       err = obdfs_init_pgrqcache();
        if (err)
                return err;
 
-       /* XXX
        flushd_init();
-       */
-
        return register_filesystem(&obdfs_fs_type);
 }
 
@@ -495,8 +497,8 @@ void cleanup_module(void)
 {
         ENTRY;
 
-       obdfs_cleanup_wreqcache();
        obdfs_sysctl_clean();
+       obdfs_cleanup_pgrqcache();
        unregister_filesystem(&obdfs_fs_type);
 
        EXIT;