Whamcloud - gitweb
Several bugfixes. Most notably ext2obd_brw is still totally broken,
authorbraam <braam>
Sun, 23 Jan 2000 16:12:32 +0000 (16:12 +0000)
committerbraam <braam>
Sun, 23 Jan 2000 16:12:32 +0000 (16:12 +0000)
fix that first.

lustre/include/linux/obdfs.h
lustre/obdfs/flushd.c
lustre/obdfs/rw.c
lustre/obdfs/super.c

index 6949f42..67a0ed1 100644 (file)
@@ -29,6 +29,7 @@ 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);
 int obdfs_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf);
+void obdfs_dequeue_reqs(struct inode *inode);
 
 /* namei.c */
 struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry);
index d12c63f..7d6f798 100644 (file)
@@ -51,6 +51,13 @@ struct {
 /* } pupd_prm = {40, 500, 64, 256, 5*HZ, 30*HZ, 5*HZ };  */
 } pupd_prm = {40, 500, 64, 256, 10*HZ, 30*HZ, 5*HZ }; 
 
+#if 0
+static void obdfs_lock_page(struct page *page)
+{
+        while (TryLockPage(page))
+                ___wait_on_page(page);
+}
+#endif
 
 static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
                               int nr_slots, struct page **pages, char **bufs,
@@ -74,13 +81,14 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
        *flag = OBD_BRW_CREATE;
 
        tmp = page_list;
-       while ( (tmp = tmp->next) != page_list && (num < nr_slots) ) {
+       while ( ((tmp = tmp->next) != page_list) && (num < nr_slots) ) {
                struct obdfs_pgrq *req;
                struct page *page;
                
                req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
                page = req->rq_page;
 
+               
                if (check_time && 
                    (jiffies - req->rq_jiffies) < pupd_prm.age_buffer)
                        continue;
@@ -89,17 +97,20 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
                 * Note that obdfs_pgrq_del() also deletes the request.
                 */
                obdfs_pgrq_del(req);
-               
+               /* 
+               obdfs_lock_page(page);
+               */
                if ( !page ) {
                        CDEBUG(D_INODE, "no page \n");
                        continue;
                }
 
-               CDEBUG(D_INODE, "adding page %p to vector\n", page);
                bufs[num] = (char *)page_address(page);
                pages[num] = page;
                counts[num] = PAGE_SIZE;
                offsets[num] = ((obd_off)page->index) << PAGE_SHIFT;
+               CDEBUG(D_INODE, "ENQ inode %ld, page %p addr %p to vector\n", 
+                      inode->i_ino, page, (char *)page_address(page));
                num++;
        }
 
@@ -111,10 +122,40 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
        return num;  
 }
 
+/* dequeue requests for a dying inode */
+void obdfs_dequeue_reqs(struct inode *inode)
+{
+
+       struct list_head *tmp;
+
+       tmp = obdfs_islist(inode);
+       if ( list_empty(tmp) ) {
+               EXIT;
+               return;
+       }
+
+       /* take it out of the super list */
+       list_del(tmp);
+       INIT_LIST_HEAD(obdfs_islist(inode));
+
+       tmp = obdfs_iplist(inode);
+       while ( (tmp = tmp->next) != obdfs_iplist(inode) ) {
+               struct obdfs_pgrq *req;
+               struct page *page;
+               
+               req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+               page = req->rq_page;
+               /* take it out of the list and free */
+               obdfs_pgrq_del(req);
+               /* now put the page away */
+               put_page(page);
+       }
+
+}
+
 
 /* Remove writeback requests for the superblock */
-int obdfs_flush_reqs(struct list_head *inode_list, int flush_inode,
-                    int check_time)
+int obdfs_flush_reqs(struct list_head *inode_list, int check_time)
 {
        struct list_head *tmp = inode_list;
        int               total_io = 0;
@@ -169,6 +210,8 @@ int obdfs_flush_reqs(struct list_head *inode_list, int flush_inode,
                                                  &counts[num_io],
                                                  &offsets[num_io],
                                                  &flags[num_obdos],1);
+                       CDEBUG(D_INODE, "FLUSHED inode %ld, pages flushed: %d\n", 
+                              inode->i_ino, res);
                        if ( res < 0 ) {
                                err = res;
                                goto ERR;
@@ -220,7 +263,7 @@ ERR:
 } /* obdfs_remove_pages_from_cache */
 
 
-static void obdfs_flush_dirty_pages(int check_time)
+void obdfs_flush_dirty_pages(int check_time)
 {
        struct list_head *sl;
 
@@ -230,20 +273,9 @@ static void obdfs_flush_dirty_pages(int check_time)
                        list_entry(sl, struct obdfs_sb_info, osi_list);
 
                /* walk write requests here, use the sb, check the time */
-               obdfs_flush_reqs(&sbi->osi_inodes, 0, 1);
+               obdfs_flush_reqs(&sbi->osi_inodes, 0);
        }
 
-#if 0
-       /* again, but now we wait for completion */
-       sl = &obdfs_super_list;
-       while ( (sl = sl->next) != &obdfs_super_list ) {
-               struct obdfs_sb_info *sbi = 
-                       list_entry(sl, struct obdfs_sb_info, sl_chain);
-
-               /* walk write requests here */
-               obdfs_flush_reqs(&sbi->osi_pages, 0, check_time);
-       }
-#endif
 }
 
 
@@ -285,6 +317,7 @@ static int pupdate(void *unused)
                else
                {
                stop_pupdate:
+                       obdfs_flush_dirty_pages(0);
                        tsk->state = TASK_STOPPED;
                        /* MOD_DEC_USE_COUNT; */
                        printk("pupdated stopped...\n");
@@ -307,7 +340,7 @@ static int pupdate(void *unused)
                }
                /* asynchronous setattr etc for the future ... */
                /* flush_inodes(); */
-               obdfs_flush_dirty_pages(1);
+               obdfs_flush_dirty_pages(1); 
        }
 }
 
@@ -337,7 +370,8 @@ int flushd_cleanup(void)
                /* XXX need to do something like this here:
                send_sig(SIGTERM, current, 0);
                 */
-               1;
+                1;
+               /*obdfs_flush_dirty_pages(0); */
        }
 
        /* not reached */
index 5320744..1f451d8 100644 (file)
@@ -37,6 +37,7 @@
 int obdfs_flush_reqs(struct list_head *page_list, 
                     int flush_inode, int check_time);
 
+void obdfs_flush_dirty_pages(int check_time);
 
 /* SYNCHRONOUS I/O for an inode */
 static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
@@ -89,6 +90,7 @@ int obdfs_readpage(struct dentry *dentry, struct page *page)
 } /* obdfs_readpage */
 
 static kmem_cache_t *obdfs_pgrq_cachep = NULL;
+static int obdfs_cache_count = 0;
 
 int obdfs_init_pgrqcache(void)
 {
@@ -116,7 +118,8 @@ int obdfs_init_pgrqcache(void)
 
 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
 {
-       CDEBUG(D_INODE, "deleting page %p from list\n", pgrq->rq_page);
+       obdfs_cache_count--;
+       CDEBUG(D_INODE, "deleting page %p from list [count %d]\n", pgrq->rq_page, obdfs_cache_count);
        list_del(&pgrq->rq_plist);
        kmem_cache_free(obdfs_pgrq_cachep, pgrq);
 }
@@ -125,8 +128,8 @@ void obdfs_cleanup_pgrqcache(void)
 {
        ENTRY;
        if (obdfs_pgrq_cachep != NULL) {
-               CDEBUG(D_INODE, "destroying obdfs_pgrqcache at %p\n",
-                      obdfs_pgrq_cachep);
+               CDEBUG(D_INODE, "destroying obdfs_pgrqcache at %p, count %d\n",
+                      obdfs_pgrq_cachep, obdfs_cache_count);
                if (kmem_cache_destroy(obdfs_pgrq_cachep))
                        printk(KERN_INFO "obd_cleanup_pgrqcache: unable to free all of cache\n");
        } else
@@ -172,6 +175,40 @@ obdfs_find_in_page_list(struct inode *inode, struct page *page)
 } /* obdfs_find_in_page_list */
 
 
+static struct page*
+obdfs_find_page_index(struct inode *inode, unsigned long index)
+{
+       struct list_head *page_list = obdfs_iplist(inode);
+       struct list_head *tmp;
+       struct page *page;
+
+       ENTRY;
+
+       CDEBUG(D_INODE, "looking for inode %ld pageindex %ld\n", inode->i_ino, index);
+       OIDEBUG(inode);
+
+       if (list_empty(page_list)) {
+               EXIT;
+               return NULL;
+       }
+       tmp = page_list;
+       while ( (tmp = tmp->next) != page_list ) {
+               struct obdfs_pgrq *pgrq;
+
+               pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+               page = pgrq->rq_page;
+               if (index == page->index) {
+                       CDEBUG(D_INODE, "INDEX SEARC found page %p in list, index %ld\n", page, index);
+                       EXIT;
+                       return page;
+               }
+       } 
+
+       EXIT;
+       return NULL;
+} /* obdfs_find_in_page_list */
+
+
 /* call and free pages from Linux page cache */
 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
                    obd_count num_obdos, struct obdo **obdos,
@@ -191,7 +228,10 @@ int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
        /* release the pages from the page cache */
        while ( num_io > 0 ) {
                num_io--;
-               CDEBUG(D_INODE, "calling put_page for %p\n", pages[num_io]);
+               CDEBUG(D_INODE, "calling put_page for %p, index %ld\n", pages[num_io], pages[num_io]->index);
+               /*
+               UnlockPage(pages[num_io]);
+               */
                put_page(pages[num_io]);
        }
 
@@ -213,43 +253,44 @@ int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
  */
 static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
 {
-       struct obdfs_pgrq *pgrq;
+       int res = 0;
 
        ENTRY;
-       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(pgrq, 0, sizeof(*pgrq)); 
-
-       pgrq->rq_page = page;
-
-       get_page(pgrq->rq_page);
 
        /* If this page isn't already in the inode page list, add it */
        if ( !obdfs_find_in_page_list(inode, page) ) {
-               CDEBUG(D_INODE, "adding page %p to inode list %p\n", page,
-                      obdfs_iplist(inode));
+               struct obdfs_pgrq *pgrq;
+               pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
+               CDEBUG(D_INODE, "adding inode %ld page %p, pgrq: %p, cache count [%d]\n",
+                      inode->i_ino, page, pgrq, obdfs_cache_count);
+               if (!pgrq) {
+                       EXIT;
+                       return -ENOMEM;
+               }
+               memset(pgrq, 0, sizeof(*pgrq)); 
+               
+               pgrq->rq_page = page;
+               get_page(pgrq->rq_page);
                list_add(&pgrq->rq_plist, obdfs_iplist(inode));
        }
 
        /* If inode isn't already on the superblock inodes list, add it */
        if ( list_empty(obdfs_islist(inode)) ) {
-               CDEBUG(D_INODE, "adding inode %p to superblock list %p\n",
-                      obdfs_islist(inode), obdfs_slist(inode));
+               CDEBUG(D_INODE, "adding inode %ld to superblock list %p\n",
+                      inode->i_ino, obdfs_slist(inode));
                list_add(obdfs_islist(inode), obdfs_slist(inode));
        }
 
 
-       EXIT;
        /* XXX For testing purposes, we write out the page here.
         *     In the future, a flush daemon will write out the page.
-       return obdfs_flush_reqs(obdfs_slist(inode), 0, 0);
+       res = obdfs_flush_reqs(obdfs_slist(inode), 0);
+       obdfs_flush_dirty_pages(1);
         */
-       return 0;
+
+       EXIT;
+       return res;
+       /*return 0;*/
 } /* obdfs_add_page_to_cache */
 
 
@@ -259,15 +300,17 @@ int obdfs_do_writepage(struct inode *inode, struct page *page, int sync)
        int err;
 
        ENTRY;
-       PDEBUG(page, "WRITEPAGE");
+       /* PDEBUG(page, "WRITEPAGE"); */
        if ( sync )
                err = obdfs_brw(WRITE, inode, page, 1);
-       else
+       else {
                err = obdfs_add_page_to_cache(inode, page);
+               CDEBUG(D_IOCTL, "DO_WR ino: %ld, page %p, err %d, uptodata %d\n", inode->i_ino, page, err, Page_Uptodate(page));
+       }
                
        if ( !err )
                SetPageUptodate(page);
-       PDEBUG(page,"WRITEPAGE");
+       /* PDEBUG(page,"WRITEPAGE"); */
        EXIT;
        return err;
 } /* obdfs_do_writepage */
@@ -362,6 +405,11 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create
                return page;
        } 
 
+
+       if ( obdfs_find_page_index(inode, offset) ) {
+               printk("OVERWRITE: found dirty page %p, index %ld\n", page, page->index);
+       }
+
        err = obdfs_brw(READ, inode, page, create);
 
        if ( err ) {
index fafdf96..e5d04a7 100644 (file)
@@ -308,7 +308,7 @@ void obdfs_read_inode(struct inode *inode)
        INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */
 
        obdo_free(oa);
-       OIDEBUG(inode);
+       /* OIDEBUG(inode); */
 
        if (S_ISREG(inode->i_mode)) {
                inode->i_op = &obdfs_file_inode_operations;
@@ -374,6 +374,9 @@ static void obdfs_delete_inode(struct inode *inode)
        oa->o_valid = OBD_MD_FLNOTOBD;
        obdfs_from_inode(oa, inode);
 
+       /* free the cache pages that might be hangning around */
+       obdfs_dequeue_reqs(inode);
+
        err = IOPS(inode, destroy)(IID(inode), oa);
        obdo_free(oa);