From 3176c416ee47d8749806da2b552a29df9ac6ccef Mon Sep 17 00:00:00 2001 From: adilger Date: Sat, 22 Jan 2000 11:54:29 +0000 Subject: [PATCH] flush daemon debugging/testing - copy + async I/O with flush daemon working properly - some problem with rm -r for large numbers of files. inode list needs a lock snapshot now compiles, but is untested - it appears to be correct --- lustre/include/linux/obd_class.h | 4 - lustre/include/linux/obd_ext2.h | 16 ++++ lustre/include/linux/obd_support.h | 94 +++++++++------------ lustre/include/linux/obdfs.h | 65 ++++++++------- lustre/obdfs/flushd.c | 165 ++++++++++++++++++++----------------- lustre/obdfs/rw.c | 31 ++++--- 6 files changed, 203 insertions(+), 172 deletions(-) diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 07b9951..7195bde 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -326,8 +326,6 @@ static __inline__ void obdo_cpy_md(struct obdo *dst, struct obdo *src) static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src) { - CDEBUG(D_INODE, "src inode %ld, dst obdo %Ld valid 0x%08x\n", - src->i_ino, dst->o_id, dst->o_valid); if ( dst->o_valid & OBD_MD_FLID ) dst->o_id = src->i_ino; if ( dst->o_valid & OBD_MD_FLATIME ) @@ -359,8 +357,6 @@ static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src) static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src) { - CDEBUG(D_INODE, "src obdo %Ld valid 0x%08x, dst inode %ld\n", - src->o_id, src->o_valid, dst->i_ino); if ( src->o_valid & OBD_MD_FLID ) dst->i_ino = src->o_id; if ( src->o_valid & OBD_MD_FLATIME ) diff --git a/lustre/include/linux/obd_ext2.h b/lustre/include/linux/obd_ext2.h index 34d92f6..e78660a 100644 --- a/lustre/include/linux/obd_ext2.h +++ b/lustre/include/linux/obd_ext2.h @@ -79,4 +79,20 @@ extern struct inode_operations ext2_file_inode_operations; /* super.c */ extern struct super_operations ext2_sops; +static inline struct page *addr_to_page(char *buf) +{ + unsigned long addr = (unsigned long)buf; + unsigned long map_nr; + +#ifdef CONFIG_DISCONTIGMEM + if (addr == 0) return; +#endif + map_nr = MAP_NR(addr); + if (map_nr < max_mapnr) + return mem_map + map_nr; + else + return 0; +} + + #endif diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 47731a3..a37aa93 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -59,56 +59,60 @@ extern int obd_print_entry; #define CMD(cmd) (( cmd == READ ) ? "read" : "write") -/* Inode common information printed out */ +/* Inode common information printed out (used by obdfs and ext2obd inodes) */ #define ICDEBUG(inode) { \ - printk("]]%s line %d[[ ino %ld, blocks %ld, size %Ld, atm %ld, ctm %ld, mtm %ld, mode %o, uid %d, gid %d\n", \ - __FUNCTION__ , __LINE__, \ - inode->i_ino, inode->i_blocks, inode->i_size,\ - inode->i_atime, inode->i_ctime, inode->i_mtime,\ - inode->i_mode, inode->i_uid, inode->i_gid);\ - } + printk("]]%s line %d[[ ino %ld, atm %ld, mtm %ld, ctm %ld, "\ + "size %Ld, blocks %ld\n", __FUNCTION__ , __LINE__,\ + inode->i_ino, inode->i_atime, inode->i_mtime, inode->i_ctime,\ + inode->i_size, inode->i_blocks);\ + printk("]]%s line %d[[ mode %o, uid %d, gid %d, nlnk %d\n",\ + __FUNCTION__, __LINE__, inode->i_mode, inode->i_uid,\ + inode->i_gid, inode->i_nlink);\ +} /* Ext2 inode information */ #define EXDEBUG(inode) { \ - ICDEBUG(inode);\ - printk("data: 0x%08x 0x%08x 0x%08x 0x%08x\n",\ - inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],\ - inode->u.ext2_i.i_data[2], inode->u.ext2_i.i_data[3]);\ - } + ICDEBUG(inode);\ + printk("ext2 blocks: %d %d %d %d %d %d %d %d\n",\ + inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],\ + inode->u.ext2_i.i_data[2], inode->u.ext2_i.i_data[3],\ + inode->u.ext2_i.i_data[4], inode->u.ext2_i.i_data[5],\ + inode->u.ext2_i.i_data[6], inode->u.ext2_i.i_data[7]);\ +} /* OBDFS inode information */ -/* Should print these with oi_flags and oi_list.prev, next instead of i_data */ #define OIDEBUG(inode) { \ - ICDEBUG(inode);\ - printk("oinfo: flags 0x%08x next 0x%08x prev 0x%08x\n",\ - inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],\ - inode->u.ext2_i.i_data[2]);\ - } + ICDEBUG(inode);\ + printk("oinfo: flags 0x%08x\n", OBDFS_INFO(inode)->oi_flags);\ + obdfs_print_plist(inode);\ +} #define ODEBUG(obdo) { \ - printk("]]%s line %d[[ id %ld, atm %ld, mtm %ld, ctm %ld, size %ld, blocks %ld\n",\ - __FUNCTION__ , __LINE__, \ - (long)(obdo)->o_id, (long)(obdo)->o_atime,\ - (long)(obdo)->o_mtime, (long)(obdo)->o_ctime,\ - (long)(obdo)->o_size, (long)(obdo)->o_blocks);\ - printk("]]%s line %d[[ mode %o, uid %d, gid %d, flg 0x%0x, obdflg 0x%0x, nlnk %d, valid 0x%0x\n", \ - __FUNCTION__ , __LINE__, \ - (obdo)->o_mode, (obdo)->o_uid, (obdo)->o_gid,\ - (obdo)->o_flags, (obdo)->o_obdflags, (obdo)->o_nlink,\ - (obdo)->o_valid);\ - } - - -#define PDEBUG(page,cmd) {if (page){\ + printk("]]%s line %d[[ id %ld, atm %ld, mtm %ld, ctm %ld, "\ + "size %ld, blocks %ld\n", __FUNCTION__ , __LINE__,\ + (long)(obdo)->o_id, (long)(obdo)->o_atime,\ + (long)(obdo)->o_mtime, (long)(obdo)->o_ctime,\ + (long)(obdo)->o_size, (long)(obdo)->o_blocks);\ + printk("]]%s line %d[[ mode %o, uid %d, gid %d, flg 0x%0x, "\ + "obdflg 0x%0x, nlnk %d, valid 0x%0x\n", __FUNCTION__ , __LINE__,\ + (obdo)->o_mode, (obdo)->o_uid, (obdo)->o_gid, (obdo)->o_flags,\ + (obdo)->o_obdflags, (obdo)->o_nlink, (obdo)->o_valid);\ +} + + +#define PDEBUG(page,cmd) { \ + if (page){\ char *uptodate = (Page_Uptodate(page)) ? "yes" : "no";\ char *locked = (PageLocked(page)) ? "yes" : "no";\ int count = page->count.counter;\ - long index = page->index;\ - \ + long index = page->index;\ CDEBUG(D_IOCTL, " ** %s, cmd: %s, off %ld, uptodate: %s, "\ - "locked: %s, cnt %d page %p pages %ld** \n", __FUNCTION__,\ - cmd, index, uptodate, locked, count, page, (!page->mapping) ? -1 : page->mapping->nrpages);\ - } else { CDEBUG(D_IOCTL, "** %s, no page\n", __FUNCTION__); }} + "locked: %s, cnt %d page %p pages %ld** \n",\ + __FUNCTION__, cmd, index, uptodate, locked, count, \ + page, (!page->mapping) ? -1 : page->mapping->nrpages);\ + } else \ + CDEBUG(D_IOCTL, "** %s, no page\n", __FUNCTION__);\ +} #define OBD_ALLOC(ptr, cast, size) \ @@ -143,21 +147,5 @@ do { \ } while (0) -static inline struct page *addr_to_page(char *buf) -{ - unsigned long addr = (unsigned long)buf; - unsigned long map_nr; - -#ifdef CONFIG_DISCONTIGMEM - if (addr == 0) return; -#endif - map_nr = MAP_NR(addr); - if (map_nr < max_mapnr) - return mem_map + map_nr; - else - return 0; -} - - #endif diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index 655d690..6949f42 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -42,9 +42,8 @@ int obdfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dent int obdfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); /* dir.c */ int obdfs_check_dir_entry (const char * function, struct inode * dir, - struct ext2_dir_entry_2 * de, - struct page * page, - unsigned long offset); + struct ext2_dir_entry_2 * de, struct page * page, + unsigned long offset); /* symlink.c */ int obdfs_readlink (struct dentry *, char *, int); struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int); @@ -59,34 +58,23 @@ struct obdfs_pgrq { struct page *rq_page; /* page to be written */ }; -#if 0 -void obdfs_print_list(struct list_head *page_list) { - struct list_head *tmp = page_list; - while ( (tmp = tmp->next) != page_list) { - struct obdfs_pgrq *pgrq; - pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist); - CDEBUG(D_INODE, "page %p\n", pgrq->rq_page); - } -} - -#endif inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq); -int obdfs_do_vec_wr(struct super_block *sb, obd_count num_io, obd_count num_oa, - struct obdo **obdos, obd_count *oa_bufs, - struct page **pages, char **bufs, obd_size *counts, - obd_off *offsets, obd_flag *flags); +int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io, obd_count num_oa, + struct obdo **obdos, obd_count *oa_bufs, + struct page **pages, char **bufs, obd_size *counts, + obd_off *offsets, obd_flag *flags); struct obdfs_sb_info { - struct list_head osi_list; /* list of supers */ + struct list_head osi_list; /* list of supers */ struct obd_conn osi_conn; struct super_block *osi_super; struct obd_device *osi_obd; - struct obd_ops *osi_ops; - ino_t osi_rootino; /* which root inode */ - int osi_minor; /* minor of /dev/obdX */ - struct list_head osi_inodes; /* linked list of dirty inodes */ + struct obd_ops *osi_ops; + ino_t osi_rootino; /* number of root inode */ + int osi_minor; /* minor of /dev/obdX */ + struct list_head osi_inodes; /* list of dirty inodes */ }; struct obdfs_inode_info { @@ -96,6 +84,8 @@ struct obdfs_inode_info { char oi_inline[OBD_INLINESZ]; }; +#define OBDFS_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip)) + static inline struct list_head *obdfs_iplist(struct inode *inode) { struct obdfs_inode_info *info = (struct obdfs_inode_info *)&inode->u.generic_ip; @@ -115,7 +105,24 @@ static inline struct list_head *obdfs_slist(struct inode *inode) { return &sbi->osi_inodes; } -#define OBDFS_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip)) +static inline void obdfs_print_plist(struct inode *inode) { + struct list_head *page_list = obdfs_iplist(inode); + struct list_head *tmp; + + CDEBUG(D_INODE, "inode %ld: page", inode->i_ino); + if (list_empty(page_list)) { + printk(" list empty\n"); + return; + } + + tmp = page_list; + while ( (tmp = tmp->next) != page_list) { + struct obdfs_pgrq *pgrq; + pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist); + printk(" %p", pgrq->rq_page); + } + printk("\n"); +} void obdfs_sysctl_init(void); void obdfs_sysctl_clean(void); @@ -134,10 +141,11 @@ static void inline obdfs_from_inode(struct obdo *oa, struct inode *inode) { struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); - CDEBUG(D_INODE, "inode %ld (%p)\n", inode->i_ino, inode); + CDEBUG(D_INODE, "src inode %ld, dst obdo %ld valid 0x%08x\n", + inode->i_ino, (long)oa->o_id, oa->o_valid); obdo_from_inode(oa, inode); if (obdfs_has_inline(inode)) { - CDEBUG(D_INODE, "inode has inline data\n"); + CDEBUG(D_INODE, "copying inline data from inode to obdo\n"); memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ); oa->o_obdflags |= OBD_FL_INLINEDATA; oa->o_valid |= OBD_MD_FLINLINE; @@ -148,11 +156,12 @@ static void inline obdfs_to_inode(struct inode *inode, struct obdo *oa) { struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); - CDEBUG(D_INODE, "inode %ld (%p)\n", inode->i_ino, inode); + CDEBUG(D_INODE, "src obdo %ld valid 0x%08x, dst inode %ld\n", + (long)oa->o_id, oa->o_valid, inode->i_ino); obdo_to_inode(inode, oa); if (obdo_has_inline(oa)) { - CDEBUG(D_INODE, "obdo has inline data\n"); + CDEBUG(D_INODE, "copying inline data from obdo to inode\n"); memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ); oinfo->oi_flags |= OBD_FL_INLINEDATA; } diff --git a/lustre/obdfs/flushd.c b/lustre/obdfs/flushd.c index e102edd..d12c63f 100644 --- a/lustre/obdfs/flushd.c +++ b/lustre/obdfs/flushd.c @@ -48,7 +48,8 @@ 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 }; */ +} pupd_prm = {40, 500, 64, 256, 10*HZ, 30*HZ, 5*HZ }; static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo, @@ -58,18 +59,10 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo, { struct list_head *page_list = obdfs_iplist(inode); struct list_head *tmp; - int i = 0; + int num = 0; ENTRY; - /* if there are no pages, remove from super block list */ - if (list_empty(obdfs_iplist(inode))) { - list_del(obdfs_islist(inode)); - /* we check for "empty" on this animal: must init it! */ - INIT_LIST_HEAD(obdfs_islist(inode)); - CDEBUG(D_INODE, "empty list\n"); - EXIT; - return 0; - } + OIDEBUG(inode); *obdo = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD); if ( IS_ERR(*obdo) ) { @@ -77,43 +70,45 @@ static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo, return PTR_ERR(*obdo); } - obdfs_from_inode(*obdo, inode); + obdfs_from_inode(*obdo, inode); /* FIXME revisit fromid & from_inode */ *flag = OBD_BRW_CREATE; tmp = page_list; - while ( (tmp = tmp->next) != page_list && (i < 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); - /* remove request from list before write to avoid conflict */ - obdfs_pgrq_del(req); page = req->rq_page; - if ( !page ) { - CDEBUG(D_INODE, "no page \n"); - EXIT; - return 0; - } - if (check_time && - req->rq_jiffies > (jiffies - pupd_prm.age_buffer)) + (jiffies - req->rq_jiffies) < pupd_prm.age_buffer) continue; + + /* Remove request from list before write to avoid conflict. + * Note that obdfs_pgrq_del() also deletes the request. + */ + obdfs_pgrq_del(req); + if ( !page ) { + CDEBUG(D_INODE, "no page \n"); + continue; + } + CDEBUG(D_INODE, "adding page %p to vector\n", page); - bufs[i] = (char *)page_address(page); - pages[i] = page; - counts[i] = PAGE_SIZE; - offsets[i] = ((obd_off)page->index) << PAGE_SHIFT; - i++; + bufs[num] = (char *)page_address(page); + pages[num] = page; + counts[num] = PAGE_SIZE; + offsets[num] = ((obd_off)page->index) << PAGE_SHIFT; + num++; } - /* If no more pages for this inode, remove from superblock list */ - if ( list_empty(obdfs_iplist(inode)) ) - list_del(obdfs_islist(inode)); + if (!list_empty(page_list)) + CDEBUG(D_INODE, "inode %ld list not empty\n", inode->i_ino); + CDEBUG(D_INODE, "added %d page(s) to vector\n", num); EXIT; - return i; + return num; } @@ -122,18 +117,18 @@ int obdfs_flush_reqs(struct list_head *inode_list, int flush_inode, int check_time) { struct list_head *tmp = inode_list; + int total_io = 0; obd_count num_io = 0; obd_count num_obdos = 0; - struct inode *inodes[MAX_IOVEC]; + struct inode *inodes[MAX_IOVEC]; /* write data back to these */ + struct page *pages[MAX_IOVEC]; /* call put_page on these */ struct obdo *obdos[MAX_IOVEC]; - struct page *pages[MAX_IOVEC]; char *bufs[MAX_IOVEC]; obd_size counts[MAX_IOVEC]; obd_off offsets[MAX_IOVEC]; obd_flag flags[MAX_IOVEC]; obd_count bufs_per_obdo[MAX_IOVEC]; int err = 0; - int i; ENTRY; @@ -149,58 +144,78 @@ int obdfs_flush_reqs(struct list_head *inode_list, int flush_inode, return 0; } - - /* add all of the outstanding pages to a write vector, and write it */ - while ( (tmp = tmp->next) != inode_list ) { + /* add each inode's outstanding pages to a write vector, and write it */ + while ( (tmp = tmp->next) != inode_list && total_io < pupd_prm.ndirty) { struct obdfs_inode_info *ii; + struct inode *inode; int res; ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes); - inodes[num_obdos] = list_entry(ii, struct inode, u); - - res = obdfs_enqueue_pages(inodes[num_obdos], &obdos[num_obdos], - MAX_IOVEC - num_io, &pages[num_io], - &bufs[num_io], &counts[num_io], - &offsets[num_io], &flags[num_obdos],1); - if ( res < 0 ) { - return -EIO; - } - - bufs_per_obdo[num_obdos] = res; - num_io += res; - num_obdos++; - - if ( num_io == MAX_IOVEC ) { - err = obdfs_do_vec_wr(inodes[0]->i_sb, num_io, - num_obdos, obdos, bufs_per_obdo, - pages, bufs, counts, offsets, - flags); - for (i = 0 ; i < num_obdos ; i++) { - obdfs_to_inode(inodes[i], obdos[i]); - obdo_free(obdos[i]); - } - if ( err ) { - EXIT; + inode = list_entry(ii, struct inode, u); + inodes[num_obdos] = inode; + + res = 1; + + /* Loop on this inode until we can't get more pages from it + * (either no more pages, or the pages aren't old enough). + * Make sure we reference "inode" and not "inodes[num_obdos]", + * as num_obdos will change after the loop is run. + */ + while (!list_empty(obdfs_iplist(inode)) && res && + total_io < pupd_prm.ndirty ) { + res = obdfs_enqueue_pages(inode, &obdos[num_obdos], + MAX_IOVEC - num_io, + &pages[num_io], &bufs[num_io], + &counts[num_io], + &offsets[num_io], + &flags[num_obdos],1); + if ( res < 0 ) { + err = res; goto ERR; } - num_io = 0; - num_obdos = 0; + + num_io += res; + total_io += res; + bufs_per_obdo[num_obdos] = res; + num_obdos++; + + if ( num_io == MAX_IOVEC ) { + err = obdfs_do_vec_wr(inodes, num_io, num_obdos, + obdos, bufs_per_obdo, + pages, bufs, counts, + offsets, flags); + if ( err ) { + EXIT; + goto ERR; + } + inodes[0] = inode; + num_io = 0; + num_obdos = 0; + } } - } + + /* Remove inode from superblock dirty list when no more pages. + * Make sure we don't point at the current inode with tmp + * when we re-init the list on the inode, or we will loop. + */ + if (list_empty(obdfs_iplist(inode))) { + CDEBUG(D_INODE, "remove inode %ld from dirty list\n", + inode->i_ino); + tmp = tmp->prev; + list_del(obdfs_islist(inode)); + INIT_LIST_HEAD(obdfs_islist(inode)); + } + } /* flush any remaining I/Os */ if ( num_io ) { - err = obdfs_do_vec_wr(inodes[0]->i_sb, num_io, num_obdos, - obdos, bufs_per_obdo, pages, bufs, - counts, offsets, flags); - for (i = 0 ; i < num_obdos ; i++) { - obdfs_to_inode(inodes[i], obdos[i]); - obdo_free(obdos[i]); - } + err = obdfs_do_vec_wr(inodes, num_io, num_obdos, obdos, + bufs_per_obdo, pages, bufs, counts, + offsets, flags); } + CDEBUG(D_INODE, "flushed %d pages in total\n", total_io); EXIT; ERR: - return err; } /* obdfs_remove_pages_from_cache */ @@ -292,11 +307,7 @@ static int pupdate(void *unused) } /* asynchronous setattr etc for the future ... */ /* flush_inodes(); */ - CDEBUG(D_INODE, "about to flush pages...\n"); - /* obdfs_flush_dirty_pages(1); - */ - CDEBUG(D_INODE, "done flushing pages...\n"); } } diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index 59a7b73..5320744 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -116,8 +116,9 @@ int obdfs_init_pgrqcache(void) inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq) { - list_del(&pgrq->rq_plist); - kmem_cache_free(obdfs_pgrq_cachep, pgrq); + CDEBUG(D_INODE, "deleting page %p from list\n", pgrq->rq_page); + list_del(&pgrq->rq_plist); + kmem_cache_free(obdfs_pgrq_cachep, pgrq); } void obdfs_cleanup_pgrqcache(void) @@ -146,9 +147,11 @@ obdfs_find_in_page_list(struct inode *inode, struct page *page) struct list_head *tmp; ENTRY; + CDEBUG(D_INODE, "looking for inode %ld page %p\n", inode->i_ino, page); + OIDEBUG(inode); + if (list_empty(page_list)) { - CDEBUG(D_INODE, "empty list\n"); EXIT; return NULL; } @@ -157,7 +160,6 @@ obdfs_find_in_page_list(struct inode *inode, struct page *page) struct obdfs_pgrq *pgrq; pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist); - 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; @@ -171,16 +173,17 @@ obdfs_find_in_page_list(struct inode *inode, struct page *page) /* call and free pages from Linux page cache */ -int obdfs_do_vec_wr(struct super_block *sb, obd_count num_io, +int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io, obd_count num_obdos, struct obdo **obdos, obd_count *oa_bufs, struct page **pages, char **bufs, obd_size *counts, obd_off *offsets, obd_flag *flags) { + struct super_block *sb = inodes[0]->i_sb; struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)&sb->u.generic_sbp; int err; ENTRY; - CDEBUG(D_INODE, "writing %d pages, %d obdos in vector\n", + CDEBUG(D_INODE, "writing %d page(s), %d obdo(s) in vector\n", num_io, num_obdos); err = OPS(sb, brw)(WRITE, &sbi->osi_conn, num_obdos, obdos, oa_bufs, bufs, counts, offsets, flags); @@ -188,9 +191,17 @@ int obdfs_do_vec_wr(struct super_block *sb, 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]); put_page(pages[num_io]); - } + } + while ( num_obdos > 0) { + num_obdos--; + CDEBUG(D_INODE, "copy/free obdo %ld\n", + (long)obdos[num_obdos]->o_id); + obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]); + obdo_free(obdos[num_obdos]); + } EXIT; return err; } @@ -228,7 +239,7 @@ static int obdfs_add_page_to_cache(struct inode *inode, struct page *page) /* 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_islist(inode)); + obdfs_islist(inode), obdfs_slist(inode)); list_add(obdfs_islist(inode), obdfs_slist(inode)); } @@ -236,9 +247,9 @@ static int obdfs_add_page_to_cache(struct inode *inode, struct page *page) EXIT; /* XXX For testing purposes, we write out the page here. * In the future, a flush daemon will write out the page. - return 0; - */ return obdfs_flush_reqs(obdfs_slist(inode), 0, 0); + */ + return 0; } /* obdfs_add_page_to_cache */ -- 1.8.3.1