From bfc94e18ec983bb0d6da58f78f604181f2b3bd29 Mon Sep 17 00:00:00 2001 From: adilger Date: Sat, 8 Jan 2000 03:46:26 +0000 Subject: [PATCH] Fixing brw page lock issue. --- lustre/include/linux/obd_class.h | 10 +-- lustre/include/linux/obd_support.h | 24 ++++-- lustre/obdclass/genops.c | 29 ++++--- lustre/obdfs/dir.c | 2 +- lustre/obdfs/namei.c | 97 +++++++++++------------ lustre/obdfs/rw.c | 152 ++++++++++++++++++------------------- lustre/obdfs/super.c | 8 +- lustre/obdfs/symlink.c | 4 +- 8 files changed, 169 insertions(+), 157 deletions(-) diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 5ba16a8..2cd4c29 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -147,7 +147,7 @@ struct obd_ops { int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf, obd_size *count, obd_off offset); int (*o_brw)(int rw, struct obd_conn *conn, struct obdo *oa, - char *buf, obd_size count, obd_off offset, obd_flag flags); + char *buf, obd_size *count, obd_off offset, obd_flag flags); int (*o_punch)(struct obd_conn *conn, struct obdo *tgt, obd_size count, obd_off offset); int (*o_sync)(struct obd_conn *conn, struct obdo *tgt, obd_size count, @@ -302,7 +302,7 @@ 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, "flags %x\n", dst->o_valid); + CDEBUG(D_INODE, "flags 0x%08x\n", dst->o_valid); if ( dst->o_valid & OBD_MD_FLID ) dst->o_id = src->i_ino; if ( dst->o_valid & OBD_MD_FLATIME ) @@ -334,7 +334,7 @@ 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, "flags %x\n", src->o_valid); + CDEBUG(D_INODE, "flags 0x%08x\n", src->o_valid); if ( src->o_valid & OBD_MD_FLID ) dst->i_ino = src->o_id; if ( src->o_valid & OBD_MD_FLATIME ) @@ -453,9 +453,9 @@ struct oic_attr_s { /* for copy, migrate */ struct ioc_mv_s { - unsigned int src_conn_id; + uint32_t src_conn_id; struct obdo src; - unsigned int dst_conn_id; + uint32_t dst_conn_id; struct obdo dst; }; diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 623b0f7..9c5df5f 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -59,18 +59,30 @@ extern int obd_print_entry; #define CMD(cmd) (( cmd == READ ) ? "read" : "write") -#define IDEBUG(inode) { \ +/* Inode common information printed out */ +#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("blk: %d %d %d %d %d %d %d %d %d %d\n",\ + } + +/* 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]);\ + } + +/* 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], 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],\ - inode->u.ext2_i.i_data[8], inode->u.ext2_i.i_data[9]);\ + inode->u.ext2_i.i_data[2]);\ } #define ODEBUG(obdo) { \ diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index a756910..3f9801b 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -37,18 +37,15 @@ kmem_cache_t *obdo_cachep = NULL; int obd_init_obdo_cache(void) { ENTRY; - if (obdo_cachep != NULL) { - printk(KERN_INFO "obdo_cache already exists\n"); - EXIT; - /* XXX maybe this shoul be an error return? */ - return 0; - } - - obdo_cachep = kmem_cache_create("obdo_cache", sizeof(struct obdo), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (obdo_cachep == NULL) { - EXIT; - return -ENOMEM; + obdo_cachep = kmem_cache_create("obdo_cache", + sizeof(struct obdo), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (obdo_cachep == NULL) { + EXIT; + return -ENOMEM; + } } EXIT; return 0; @@ -57,10 +54,12 @@ int obd_init_obdo_cache(void) void obd_cleanup_obdo_cache(void) { ENTRY; - if (obdo_cachep != NULL) - kmem_cache_destroy(obdo_cachep); + if (obdo_cachep != NULL) { + if (kmem_cache_shrink(obdo_cachep)) + printk(KERN_INFO "obd_cleanup_obdo_cache: unable to free all of cache\n"); + } else + printk(KERN_INFO "obd_cleanup_obdo_cache: called with NULL cache pointer\n"); - obdo_cachep = NULL; EXIT; } @@ -272,7 +271,7 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst, CDEBUG(D_INODE, "Read page %ld ...\n", page->index); rc = OBP(dst_conn->oc_dev, brw) - (WRITE, dst_conn, dst, (char *)page_address(page), + (WRITE, dst_conn, dst, (char *)page_address(page), PAGE_SIZE, (page->index) << PAGE_SHIFT, 1); if ( rc != PAGE_SIZE) break; diff --git a/lustre/obdfs/dir.c b/lustre/obdfs/dir.c index 30262e0..c106e8e 100644 --- a/lustre/obdfs/dir.c +++ b/lustre/obdfs/dir.c @@ -143,7 +143,7 @@ static int obdfs_readdir(struct file * filp, void * dirent, filldir_t filldir) offset = filp->f_pos & (PAGE_SIZE - 1); while (!error && !stored && filp->f_pos < inode->i_size) { - IDEBUG(inode); + OIDEBUG(inode); page = obdfs_getpage(inode, offset, 0, LOCKED); PDEBUG(page, "readdir"); if (!page) { diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 8c7d018..7a811c8 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -63,16 +63,17 @@ static inline int ext2_match (int len, const char * const name, } /* - * ext2_find_entry() + * obdfs_find_entry() * * finds an entry in the specified directory with the wanted name. It * returns the cache buffer in which the entry was found, and the entry - * itself (as a parameter - res_dir). It does NOT read the inode of the + * itself (as a parameter - res_dir). It does NOT read the inode of the * entry - you'll have to do that yourself if you want to. */ static struct page * obdfs_find_entry (struct inode * dir, - const char * const name, int namelen, - struct ext2_dir_entry_2 ** res_dir, int lock) + const char * const name, int namelen, + struct ext2_dir_entry_2 ** res_dir, + int lock) { struct super_block * sb; unsigned long offset; @@ -149,7 +150,7 @@ failure: } EXIT; return NULL; -} +} /* obdfs_find_entry */ struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) { @@ -184,11 +185,11 @@ struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) d_add(dentry, inode); EXIT; return NULL; -} +} /* obdfs_lookup */ /* - * ext2_add_entry() + * obdfs_add_entry() * * adds a file entry to the specified directory, using the same * semantics as ext2_find_entry(). It returns NULL if it failed. @@ -242,6 +243,7 @@ static struct page *obdfs_add_entry (struct inode * dir, } rec_len = EXT2_DIR_REC_LEN(namelen); CDEBUG(D_INODE, "reclen: %d\n", rec_len); + PDEBUG(page, "starting search"); offset = 0; de = (struct ext2_dir_entry_2 *) page_address(page); *err = -ENOSPC; @@ -256,6 +258,7 @@ static struct page *obdfs_add_entry (struct inode * dir, EXIT; return NULL; } + PDEBUG(page, "new directory page"); if (dir->i_size <= offset) { if (dir->i_size == 0) { *err = -ENOENT; @@ -350,7 +353,7 @@ static struct page *obdfs_add_entry (struct inode * dir, PDEBUG(page, "addentry"); EXIT; return NULL; -} +} /* obdfs_add_entry */ /* * obdfs_delete_entry deletes a directory entry by merging it with the @@ -383,7 +386,7 @@ static int obdfs_delete_entry (struct ext2_dir_entry_2 * dir, de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); } return -ENOENT; -} +} /* obdfs_delete_entry */ static inline void ext2_set_de_type(struct super_block *sb, @@ -439,53 +442,54 @@ static void show_dentry(struct list_head * dlist, int subdirs) dentry->d_name.name, dentry->d_count, unhashed); } -} +} /* show_dentry */ #endif struct inode *obdfs_new_inode(struct inode *dir) { - struct obdo *obdo; + struct obdo *oa; struct inode *inode; - struct obdfs_inode_info *oinfo; - ino_t ino; int err; ENTRY; - obdo = obdo_alloc(); - if (!obdo) { + oa = obdo_alloc(); + if (!oa) { EXIT; return ERR_PTR(-ENOMEM); } - err = IOPS(dir, create)(IID(dir), obdo); - ino = (ino_t)obdo->o_id; - obdo_free(obdo); + err = IOPS(dir, create)(IID(dir), oa); if ( err ) { + obdo_free(oa); EXIT; return ERR_PTR(err); } - inode = iget(dir->i_sb, ino); + inode = iget(dir->i_sb, (ino_t)oa->o_id); if (!inode) { + IOPS(dir, destroy)(IID(dir), oa); + obdo_free(oa); EXIT; return ERR_PTR(-EIO); } if (!list_empty(&inode->i_dentry)) { CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", inode->i_ino); + IOPS(dir, destroy)(IID(dir), oa); + obdo_free(oa); iput(inode); EXIT; return ERR_PTR(-EIO); } - oinfo = OBD_INFO(inode); - INIT_LIST_HEAD(&oinfo->oi_list); + INIT_LIST_HEAD(&OBD_LIST(inode)); + EXIT; return inode; -} +} /* obdfs_new_inode */ /* @@ -532,7 +536,7 @@ int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) d_instantiate(dentry, inode); EXIT; return err; -} +} /* obdfs_create */ int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) { @@ -573,7 +577,7 @@ out_no_entry: mark_inode_dirty(inode); iput(inode); goto out; -} +} /* obdfs_mknod */ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { @@ -662,7 +666,7 @@ out_no_entry: iput (inode); EXIT; goto out; -} +} /* obdfs_mkdir */ /* @@ -730,7 +734,7 @@ static int empty_dir (struct inode * inode) UnlockPage(page); page_cache_release(page); return 1; -} +} /* empty_dir */ int obdfs_rmdir (struct inode * dir, struct dentry *dentry) { @@ -784,7 +788,7 @@ end_rmdir: page_cache_release(page); EXIT; return retval; -} +} /* obdfs_rmdir */ int obdfs_unlink(struct inode * dir, struct dentry *dentry) { @@ -835,7 +839,7 @@ end_unlink: page_cache_release(page); EXIT; return retval; -} +} /* obdfs_unlink */ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname) { @@ -899,11 +903,10 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type(dir->i_sb, de, S_IFLNK); dir->i_version = ++event; - obdfs_do_writepage(dir, page, IS_SYNC(dir)); + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); d_instantiate(dentry, inode); - err = 0; out: EXIT; return err; @@ -913,7 +916,7 @@ out_no_entry: mark_inode_dirty(inode); iput (inode); goto out; -} +} /* obdfs_symlink */ int obdfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry *dentry) @@ -939,7 +942,7 @@ int obdfs_link (struct dentry * old_dentry, ext2_set_de_type(dir->i_sb, de, inode->i_mode); dir->i_version = ++event; - obdfs_do_writepage(dir, page, IS_SYNC(dir)); + err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); UnlockPage(page); page_cache_release(page); @@ -948,8 +951,8 @@ int obdfs_link (struct dentry * old_dentry, mark_inode_dirty(inode); inode->i_count++; d_instantiate(dentry, inode); - return 0; -} + return err; +} /* obdfs_link */ #define PARENT_INO(buffer) \ ((struct ext2_dir_entry_2 *) ((char *) buffer + \ @@ -965,7 +968,7 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, struct inode * old_inode, * new_inode; struct page * old_page, * new_page, * dir_page; struct ext2_dir_entry_2 * old_de, * new_de; - int retval; + int err; ENTRY; @@ -981,7 +984,7 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, * same name. Goodbye sticky bit ;-< */ old_inode = old_dentry->d_inode; - retval = -ENOENT; + err = -ENOENT; if (!old_page || le32_to_cpu(old_de->inode) != old_inode->i_ino) goto end_rename; @@ -1002,11 +1005,11 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, if (S_ISDIR(old_inode->i_mode)) { /* can only rename into empty new directory */ if (new_inode) { - retval = -ENOTEMPTY; + err = -ENOTEMPTY; if (!empty_dir (new_inode)) goto end_rename; } - retval = -EIO; + err = -EIO; dir_page= obdfs_getpage (old_inode, 0, 0, LOCKED); PDEBUG(dir_page, "rename dir page"); @@ -1014,7 +1017,7 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, goto end_rename; if (le32_to_cpu(PARENT_INO(page_address(dir_page))) != old_dir->i_ino) goto end_rename; - retval = -EMLINK; + err = -EMLINK; if (!new_inode && new_dir!=old_dir && new_dir->i_nlink >= EXT2_LINK_MAX) goto end_rename; @@ -1023,7 +1026,7 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, if (!new_page) { new_page = obdfs_add_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de, - &retval); + &err); PDEBUG(new_page, "rename new page"); if (!new_page) goto end_rename; @@ -1051,7 +1054,8 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, mark_inode_dirty(old_dir); if (dir_page) { PARENT_INO(page_address(dir_page)) = le32_to_cpu(new_dir->i_ino); - obdfs_do_writepage(old_inode, dir_page, IS_SYNC(old_inode)); + /* XXX handle err */ + err = obdfs_do_writepage(old_inode, dir_page, IS_SYNC(old_inode)); old_dir->i_nlink--; mark_inode_dirty(old_dir); if (new_inode) { @@ -1070,12 +1074,11 @@ int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry, page_cache_release(old_page); old_page = obdfs_getpage(old_dir, index >> PAGE_SHIFT, 0, LOCKED); CDEBUG(D_INODE, "old_page at %p\n", old_page); - obdfs_do_writepage(old_dir, old_page, IS_SYNC(old_dir)); + /* XXX handle err */ + err = obdfs_do_writepage(old_dir, old_page, IS_SYNC(old_dir)); } - obdfs_do_writepage(new_dir, new_page, IS_SYNC(new_dir)); - - retval = 0; + err = obdfs_do_writepage(new_dir, new_page, IS_SYNC(new_dir)); end_rename: if (old_page && PageLocked(old_page) ) @@ -1092,5 +1095,5 @@ end_rename: page_cache_release(dir_page); - return retval; -} + return err; +} /* obdfs_rename */ diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index fd3ff34..3e9825f 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -36,11 +36,13 @@ int console_loglevel; /* SYNCHRONOUS I/O for an inode */ -int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) +static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) { struct obdo *obdo; - int res; + obd_size count = PAGE_SIZE; + int err; + ENTRY; obdo = obdo_alloc(); if ( ! obdo ) { EXIT; @@ -49,19 +51,15 @@ int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) obdo->o_id = inode->i_ino; - res = IOPS(inode, brw)(rw, IID(inode), obdo, - (char *)page_address(page), - PAGE_SIZE, - (page->index) >> PAGE_SHIFT, - create); + err = IOPS(inode, brw)(rw, IID(inode), obdo, (char *)page_address(page), + &count, (page->index) >> PAGE_SHIFT, create); obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */ obdo_free(obdo); - if ( res == PAGE_SIZE ) - res = 0; - return res; -} + EXIT; + return err; +} /* obdfs_brw */ /* returns the page unlocked, but with a reference */ int obdfs_readpage(struct dentry *dentry, struct page *page) @@ -71,49 +69,55 @@ int obdfs_readpage(struct dentry *dentry, struct page *page) ENTRY; PDEBUG(page, "READ"); - rc = obdfs_brw(READ, inode, page, 0); - if (!rc) { + rc = obdfs_brw(READ, inode, page, 0); + if ( !rc ) { SetPageUptodate(page); UnlockPage(page); } PDEBUG(page, "READ"); EXIT; return rc; -} +} /* obdfs_readpage */ -static kmem_cache_t *obdfs_wreq_cachep; +static kmem_cache_t *obdfs_wreq_cachep = NULL; int obdfs_init_wreqcache(void) { - /* XXX need to free this somewhere? */ ENTRY; - 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_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; + } } EXIT; return 0; -} +} /* obdfs_init_wreqcache */ void obdfs_cleanup_wreqcache(void) { - if (obdfs_wreq_cachep != NULL) - kmem_cache_destroy(obdfs_wreq_cachep); + 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"); - obdfs_wreq_cachep = NULL; -} + EXIT; +} /* obdfs_cleanup_wreqcache */ /* * 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_wreq *obdfs_find_in_page_cache(struct inode *inode, + struct page *page) { struct list_head *list_head = &OBD_LIST(inode); struct obdfs_wreq *head, *wreq; @@ -137,22 +141,22 @@ obdfs_find_in_page_cache(struct inode *inode, struct page *page) EXIT; return NULL; -} +} /* obdfs_find_in_page_cache */ /* * 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_wreq *wreq) { struct inode *inode = wreq->wb_inode; struct page *page = wreq->wb_page; int rc; ENTRY; - CDEBUG(D_INODE, "removing inode %ld page %p, wreq: %p\n", - inode->i_ino, page, wreq); + CDEBUG(D_INODE, "removing inode %ld, wreq: %p\n", + inode->i_ino, wreq); + PDEBUG(page, "REM_CACHE"); 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? @@ -163,13 +167,12 @@ obdfs_remove_from_page_cache(struct obdfs_wreq *wreq) EXIT; return rc; -} +} /* obdfs_remove_from_page_cache */ /* * Add a page to the write request cache list for later writing */ -static int -obdfs_add_to_page_cache(struct inode *inode, struct page *page) +static int obdfs_add_to_page_cache(struct inode *inode, struct page *page) { struct obdfs_wreq *wreq; @@ -186,23 +189,12 @@ obdfs_add_to_page_cache(struct inode *inode, struct page *page) wreq->wb_page = page; wreq->wb_inode = inode; - CDEBUG(D_INODE, "getting page %p\n", wreq->wb_page); get_page(wreq->wb_page); - CDEBUG(D_INODE, "adding wreq %p to inode %p\n", wreq, inode); - { struct obdfs_inode_info *oinfo = OBD_INFO(inode); - CDEBUG(D_INODE, "generic is %p\n", inode->u.generic_ip); - CDEBUG(D_INODE, "oinfo is %p\n", oinfo); - } - CDEBUG(D_INODE, "wreq_list %p\n", &wreq->wb_list); - return -EIO; - CDEBUG(D_INODE, "inode_list: next %p, prev %p\n", OBD_LIST(inode).next, - OBD_LIST(inode).prev); - CDEBUG(D_INODE, "inode_list_addr: %p\n", &OBD_LIST(inode)); - list_add(&wreq->wb_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); @@ -214,27 +206,25 @@ obdfs_add_to_page_cache(struct inode *inode, struct page *page) EXIT; return obdfs_remove_from_page_cache(wreq); -} +} /* obdfs_add_to_page_cache */ int obdfs_do_writepage(struct inode *inode, struct page *page, int sync) { - int rc; + int err; ENTRY; PDEBUG(page, "WRITEPAGE"); - if ( sync ) { - rc = obdfs_brw(WRITE, inode, page, 1); - } else { - /* XXX flush stuff */ - rc = obdfs_add_to_page_cache(inode, page); - } + if ( sync ) + err = obdfs_brw(WRITE, inode, page, 1); + else + err = obdfs_add_to_page_cache(inode, page); - if (!rc) + if ( !err ) SetPageUptodate(page); PDEBUG(page,"WRITEPAGE"); - return rc; -} + return err; +} /* obdfs_do_writepage */ /* returns the page unlocked, but with a reference */ int obdfs_writepage(struct dentry *dentry, struct page *page) @@ -251,34 +241,32 @@ int obdfs_writepage(struct dentry *dentry, struct page *page) * If the writer ends up delaying the write, the writer needs to * increment the page use counts until he is done with the page. */ -int obdfs_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf) +int obdfs_write_one_page(struct file *file, struct page *page, + unsigned long offset, unsigned long bytes, + const char * buf) { - long status; struct inode *inode = file->f_dentry->d_inode; + int err; ENTRY; if ( !Page_Uptodate(page) ) { - status = obdfs_brw(READ, inode, page, 1); - if (!status) { + err = obdfs_brw(READ, inode, page, 1); + if ( !err ) SetPageUptodate(page); - } else { - return status; - } + else + return err; } bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes); - status = -EFAULT; + err = -EFAULT; if (bytes) { lock_kernel(); - status = obdfs_writepage(file->f_dentry, page); + err = obdfs_writepage(file->f_dentry, page); unlock_kernel(); } - EXIT; - if ( status != PAGE_SIZE ) - return status; - else - return bytes; -} + + return err; +} /* obdfs_write_one_page */ /* return an up to date page: @@ -293,7 +281,7 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create struct page *page_cache; struct page ** hash; struct page * page; - int rc; + int err; ENTRY; @@ -302,8 +290,10 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create page = NULL; page_cache = page_cache_alloc(); - if ( ! page_cache ) + if ( ! page_cache ) { + EXIT; return NULL; + } CDEBUG(D_INODE, "page_cache %p\n", page_cache); hash = page_hash(&inode->i_data, offset); @@ -312,6 +302,7 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create /* Yuck, no page */ if (! page) { printk("grab_cache_page says no dice ...\n"); + EXIT; return 0; } @@ -324,11 +315,12 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create return page; } - rc = obdfs_brw(READ, inode, page, create); + err = obdfs_brw(READ, inode, page, create); - if ( rc != PAGE_SIZE ) { + if ( err ) { SetPageError(page); UnlockPage(page); + EXIT; return page; } @@ -338,6 +330,6 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create PDEBUG(page,"GETPAGE - after reading"); EXIT; return page; -} +} /* obdfs_getpage */ diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index 58ea060..f417d77 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -346,8 +346,10 @@ void obdfs_read_inode(struct inode *inode) ODEBUG(oa); obdfs_to_inode(inode, oa); + INIT_LIST_HEAD(&OBD_LIST(inode)); + obdo_free(oa); - IDEBUG(inode); + OIDEBUG(inode); if (S_ISREG(inode->i_mode)) inode->i_op = &obdfs_file_inode_operations; @@ -358,6 +360,8 @@ void obdfs_read_inode(struct inode *inode) else /* XXX what do we pass here??? */ init_special_inode(inode, inode->i_mode, 0 /* XXX XXX */ ); + + EXIT; return; } @@ -494,6 +498,8 @@ void cleanup_module(void) obdfs_cleanup_wreqcache(); obdfs_sysctl_clean(); unregister_filesystem(&obdfs_fs_type); + + EXIT; } #endif diff --git a/lustre/obdfs/symlink.c b/lustre/obdfs/symlink.c index 45b176d..767f469 100644 --- a/lustre/obdfs/symlink.c +++ b/lustre/obdfs/symlink.c @@ -71,7 +71,7 @@ struct dentry * obdfs_follow_link(struct dentry * dentry, ENTRY; link = (char *) inode->u.ext2_i.i_data; if (inode->i_blocks) { - IDEBUG(inode); + OIDEBUG(inode); page = obdfs_getpage(inode, 0, 0, 0); PDEBUG(page, "follow_link"); if (!page) { @@ -104,7 +104,7 @@ int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen) link = (char *) inode->u.ext2_i.i_data; if (inode->i_blocks) { - IDEBUG(inode); + OIDEBUG(inode); page = obdfs_getpage(inode, 0, 0, 0); PDEBUG(page, "readlink"); if (!page) { -- 1.8.3.1