From d9a0ca8abf1e23b9d7bef407a892b0526682e6b9 Mon Sep 17 00:00:00 2001 From: braam Date: Sun, 21 Oct 2001 02:52:05 +0000 Subject: [PATCH] Another very major cleanup: - new lookup/new_inode code based on iget4 (saves RPC's) - reorganized the layout of ext2_obd.c - the bonnie++ bug can be fixed by patching the 2.4.3 kernel. --- lustre/include/linux/obd_class.h | 2 +- lustre/obdfs/dir.c | 16 +++--- lustre/obdfs/namei.c | 43 +++++++++------ lustre/obdfs/rw.c | 19 ++++--- lustre/obdfs/super.c | 109 +++++++++++++++++++++------------------ 5 files changed, 109 insertions(+), 80 deletions(-) diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 9d05040..193c083 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -249,7 +249,7 @@ static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id, EXIT; return ERR_PTR(-ENOMEM); } - memset(oa, 0, sizeof(*oa)); + oa->o_id = id; oa->o_valid = valid; if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) { diff --git a/lustre/obdfs/dir.c b/lustre/obdfs/dir.c index 444d6bb..dbc57c2 100644 --- a/lustre/obdfs/dir.c +++ b/lustre/obdfs/dir.c @@ -406,11 +406,10 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, BUG(); de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type (de, inode); + dir->i_mtime = dir->i_ctime = CURRENT_TIME; err = ext2_commit_chunk(page, from, to); UnlockPage(page); ext2_put_page(page); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - obdfs_change_inode(dir); } /* @@ -446,6 +445,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) goto out_page; name_len = EXT2_DIR_REC_LEN(de->name_len); rec_len = le16_to_cpu(de->rec_len); + if ( n==npages && rec_len == 0) { + printk("Fatal dir behaviour\n"); + goto out_page; + } if (!de->inode && rec_len >= reclen) goto got_it; if (rec_len >= name_len + reclen) @@ -474,9 +477,11 @@ got_it: memcpy (de->name, name, namelen); de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type (de, inode); - err = ext2_commit_chunk(page, from, to); dir->i_mtime = dir->i_ctime = CURRENT_TIME; - obdfs_change_inode(dir); + err = ext2_commit_chunk(page, from, to); + + // change_inode happens with the commit_chunk + // obdfs_change_inode(dir); /* OFFSET_CACHE */ out_unlock: UnlockPage(page); @@ -514,11 +519,10 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) if (pde) pde->rec_len = cpu_to_le16(to-from); dir->inode = 0; + inode->i_ctime = inode->i_mtime = CURRENT_TIME; err = ext2_commit_chunk(page, from, to); UnlockPage(page); ext2_put_page(page); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - obdfs_change_inode(inode); return err; } diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 4e297c6..55a58ba 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -68,7 +68,8 @@ static inline void ext2_dec_count(struct inode *inode) static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) { - int err = ext2_add_link(dentry, inode); + int err; + err = ext2_add_link(dentry, inode); if (!err) { d_instantiate(dentry, inode); return 0; @@ -81,19 +82,32 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) /* methods */ static struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) { - struct inode * inode; + struct obdo *oa; + struct inode * inode = NULL; ino_t ino; + ENTRY; if (dentry->d_name.len > EXT2_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); ino = ext2_inode_by_name(dir, dentry); - inode = NULL; - if (ino) { - inode = iget(dir->i_sb, ino); - if (!inode) - return ERR_PTR(-EACCES); - } + if (!ino) + goto negative; + + oa = obdo_fromid(IID(dir), ino, OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS); + if ( IS_ERR(oa) ) { + printk(__FUNCTION__ ": obdo_fromid failed\n"); + EXIT; + return ERR_PTR(-EACCES); + } + + inode = iget4(dir->i_sb, ino, NULL, oa); + obdo_free(oa); + + if (!inode) + return ERR_PTR(-EACCES); + + negative: d_add(dentry, inode); return NULL; } @@ -146,26 +160,26 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode) return ERR_PTR(err); } - inode = iget(dir->i_sb, (ino_t)oa->o_id); + inode = iget4(dir->i_sb, (ino_t)oa->o_id, NULL, oa); + obdo_free(oa); if (!inode) { printk("new_inode -fatal: %ld\n", (long)oa->o_id); IOPS(dir, destroy)(IID(dir), oa); - obdo_free(oa); EXIT; return ERR_PTR(-EIO); } if (!list_empty(&inode->i_dentry)) { - printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n", (long)oa->o_id, - atomic_read(&inode->i_count), inode->i_nlink); + printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n", + (long)oa->o_id, + atomic_read(&inode->i_count), + inode->i_nlink); IOPS(dir, destroy)(IID(dir), oa); - obdo_free(oa); iput(inode); EXIT; return ERR_PTR(-EIO); } - obdo_free(oa); EXIT; return inode; @@ -188,7 +202,6 @@ static int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) inode->i_op = &obdfs_file_inode_operations; inode->i_fop = &obdfs_file_operations; inode->i_mapping->a_ops = &obdfs_aops; - obdfs_change_inode(inode); err = ext2_add_nondir(dentry, inode); } return err; diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index 82b0df8..edb6301 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -38,7 +38,7 @@ void obdfs_change_inode(struct inode *inode); -/* SYNCHRONOUS I/O for an inode */ +/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) { obd_count num_obdo = 1; @@ -56,21 +56,20 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) return -EIO; } - oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD); - if ( IS_ERR(oa) ) { + oa = obdo_alloc(); + if ( !oa ) { EXIT; - return PTR_ERR(oa); + return -ENOMEM; } + oa->o_valid = OBD_MD_FLNOTOBD; obdfs_from_inode(oa, inode); err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo, &page, &count, &offset, &flags); - if ( !err ) obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */ obdo_free(oa); - EXIT; return err; } /* obdfs_brw */ @@ -82,7 +81,13 @@ int obdfs_readpage(struct file *file, struct page *page) int rc; ENTRY; - + + if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) + <= page->index) { + memset(kmap(page), 0, PAGE_CACHE_SIZE); + goto readpage_out; + } + if (Page_Uptodate(page)) { EXIT; goto readpage_out; diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index e047218..8827bfb 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -128,6 +128,7 @@ static struct super_block * obdfs_read_super(struct super_block *sb, unsigned long blocksize_bits; unsigned long root_ino; int scratch; + struct obdo *oa; ENTRY; @@ -236,9 +237,21 @@ static struct super_block * obdfs_read_super(struct super_block *sb, /* make root inode */ CDEBUG(D_INFO, "\n"); - root = iget(sb, root_ino); - if (!root || is_bad_inode(root)) { - printk("OBDFS: bad iget for root\n"); + oa = obdo_fromid(&sbi->osi_conn, root_ino, + OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS); + CDEBUG(D_INFO, "\n"); + if ( IS_ERR(oa) ) { + printk(__FUNCTION__ ": obdo_fromid failed\n"); + iput(root); + EXIT; + goto ERR; + } + CDEBUG(D_INFO, "\n"); + root = iget4(sb, root_ino, NULL, oa); + obdo_free(oa); + CDEBUG(D_INFO, "\n"); + if (!root) { + printk("OBDFS: bad iget4 for root\n"); sb->s_dev = 0; err = -ENOENT; EXIT; @@ -294,53 +307,6 @@ static void obdfs_put_super(struct super_block *sb) } /* obdfs_put_super */ -/* all filling in of inodes postponed until lookup */ -static void obdfs_read_inode(struct inode *inode) -{ - struct obdo *oa; - ENTRY; - oa = obdo_fromid(IID(inode), inode->i_ino, - OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS); - if ( IS_ERR(oa) ) { - printk(__FUNCTION__ ": obdo_fromid failed\n"); - EXIT; - return /* PTR_ERR(oa) */; - } - - ODEBUG(oa); - obdfs_to_inode(inode, oa); - INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */ - INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */ - - obdo_free(oa); - /* OIDEBUG(inode); */ - - if (S_ISREG(inode->i_mode)) { - inode->i_op = &obdfs_file_inode_operations; - inode->i_fop = &obdfs_file_operations; - inode->i_mapping->a_ops = &obdfs_aops; - EXIT; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &obdfs_dir_inode_operations; - inode->i_fop = &obdfs_dir_operations; - inode->i_mapping->a_ops = &obdfs_aops; - EXIT; - } else if (S_ISLNK(inode->i_mode)) { - if (inode->i_blocks) { - inode->i_op = &obdfs_symlink_inode_operations; - inode->i_mapping->a_ops = &obdfs_aops; - }else { - inode->i_op = &obdfs_fast_symlink_inode_operations; - } - EXIT; - } else { - init_special_inode(inode, inode->i_mode, - ((int *)obdfs_i2info(inode)->oi_inline)[0]); - } - - return; -} - void obdfs_do_change_inode(struct inode *inode, int mask) { struct obdo *oa; @@ -520,16 +486,56 @@ static int obdfs_statfs(struct super_block *sb, struct statfs *buf) return err; } +static inline void obdfs_read_inode2(struct inode *inode, void *opaque) +{ + struct obdo *oa = opaque; + + ENTRY; + obdfs_to_inode(inode, oa); + + INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */ + INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */ + + /* OIDEBUG(inode); */ + + if (S_ISREG(inode->i_mode)) { + inode->i_op = &obdfs_file_inode_operations; + inode->i_fop = &obdfs_file_operations; + inode->i_mapping->a_ops = &obdfs_aops; + EXIT; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &obdfs_dir_inode_operations; + inode->i_fop = &obdfs_dir_operations; + inode->i_mapping->a_ops = &obdfs_aops; + EXIT; + } else if (S_ISLNK(inode->i_mode)) { + if (inode->i_blocks) { + inode->i_op = &obdfs_symlink_inode_operations; + inode->i_mapping->a_ops = &obdfs_aops; + }else { + inode->i_op = &obdfs_fast_symlink_inode_operations; + } + EXIT; + } else { + init_special_inode(inode, inode->i_mode, + ((int *)obdfs_i2info(inode)->oi_inline)[0]); + } + + EXIT; + return; +} + /* exported operations */ struct super_operations obdfs_super_operations = { - read_inode: obdfs_read_inode, + read_inode2: obdfs_read_inode2, put_inode: obdfs_put_inode, delete_inode: obdfs_delete_inode, put_super: obdfs_put_super, statfs: obdfs_statfs }; + struct file_system_type obdfs_fs_type = { "obdfs", 0, obdfs_read_super, NULL }; @@ -551,6 +557,7 @@ int init_obdfs(void) return register_filesystem(&obdfs_fs_type); } + struct address_space_operations obdfs_aops = { readpage: obdfs_readpage, writepage: obdfs_writepage, -- 1.8.3.1