From c53abec054cffa4ce2502168120cbdd4f1b9e1f9 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 28 Jul 2003 12:02:04 +0000 Subject: [PATCH] - minor changes in Andreas'es ext3 direct-io patch to be applicable for 2.4.18-chaos - ext3-o_direct-1-2.4.18-chaos.patch have been added to chaos-2.4.18 series --- .../patches/ext3-o_direct-1-2.4.18-chaos.patch | 198 +++++++++++++++++++++ .../pc/ext3-o_direct-1-2.4.18-chaos.pc | 1 + 2 files changed, 199 insertions(+) create mode 100644 lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch create mode 100644 lustre/kernel_patches/pc/ext3-o_direct-1-2.4.18-chaos.pc diff --git a/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch new file mode 100644 index 0000000..04f4948 --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch @@ -0,0 +1,198 @@ + +--- linux-2.4.18/fs/ext3/inode.c~ext3-o_direct-1-2.4.18-chaos Mon Jul 28 14:13:05 2003 ++++ linux-2.4.18-alexey/fs/ext3/inode.c Mon Jul 28 15:50:14 2003 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -733,9 +734,9 @@ err_out: + * The BKL may not be held on entry here. Be sure to take it early. + */ + +-static int ext3_get_block_handle(handle_t *handle, struct inode *inode, +- long iblock, +- struct buffer_head *bh_result, int create) ++static int ++ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock, ++ struct buffer_head *bh_result, int create, int extend_disksize) + { + int err = -EIO; + int offsets[4]; +@@ -816,16 +817,18 @@ out: + if (err) + goto cleanup; + +- new_size = inode->i_size; +- /* +- * This is not racy against ext3_truncate's modification of i_disksize +- * because VM/VFS ensures that the file cannot be extended while +- * truncate is in progress. It is racy between multiple parallel +- * instances of get_block, but we have the BKL. +- */ +- if (new_size > ei->i_disksize) +- ei->i_disksize = new_size; +- ++ if (extend_disksize) { ++ /* ++ * This is not racy against ext3_truncate's modification of ++ * i_disksize because VM/VFS ensures that the file cannot be ++ * extended while truncate is in progress. It is racy between ++ * multiple parallel instances of get_block, but we have BKL. ++ */ ++ struct ext3_inode_info *ei = EXT3_I(inode); ++ new_size = inode->i_size; ++ if (new_size > ei->i_disksize) ++ ei->i_disksize = new_size; ++ } + bh_result->b_state |= (1UL << BH_New); + goto got_it; + +@@ -852,7 +855,38 @@ static int ext3_get_block(struct inode * + handle = ext3_journal_current_handle(); + J_ASSERT(handle != 0); + } +- ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create); ++ ret = ext3_get_block_handle(handle, inode, iblock, ++ bh_result, create, 1); ++ return ret; ++} ++ ++#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32) ++ ++static int ++ext3_direct_io_get_block(struct inode *inode, long iblock, ++ struct buffer_head *bh_result, int create) ++{ ++ handle_t *handle = journal_current_handle(); ++ int ret = 0; ++ ++ lock_kernel(); ++ if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) { ++ /* ++ * Getting low on buffer credits... ++ */ ++ if (!ext3_journal_extend(handle, DIO_CREDITS)) { ++ /* ++ * Couldn't extend the transaction. Start a new one ++ */ ++ ret = ext3_journal_restart(handle, DIO_CREDITS); ++ } ++ } ++ if (ret == 0) ++ ret = ext3_get_block_handle(handle, inode, iblock, ++ bh_result, create, 0); ++ if (ret == 0) ++ bh_result->b_size = (1 << inode->i_blkbits); ++ unlock_kernel(); + return ret; + } + +@@ -870,7 +904,7 @@ struct buffer_head *ext3_getblk(handle_t + dummy.b_state = 0; + dummy.b_blocknr = -1000; + buffer_trace_init(&dummy.b_history); +- *errp = ext3_get_block_handle(handle, inode, block, &dummy, create); ++ *errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1); + if (!*errp && buffer_mapped(&dummy)) { + struct buffer_head *bh; + bh = sb_getblk(inode->i_sb, dummy.b_blocknr); +@@ -1380,6 +1414,67 @@ static int ext3_releasepage(struct page + return journal_try_to_free_buffers(journal, page, wait); + } + ++static int ++ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, ++ unsigned long blocknr, int blocksize) ++{ ++ struct ext3_inode_info *ei = EXT3_I(inode); ++ handle_t *handle = NULL; ++ int ret; ++ int orphan = 0; ++ loff_t offset = blocknr << inode->i_blkbits; /* ugh */ ++ ssize_t count = iobuf->length; /* ditto */ ++ ++ if (rw == WRITE) { ++ loff_t final_size = offset + count; ++ ++ lock_kernel(); ++ handle = ext3_journal_start(inode, DIO_CREDITS); ++ unlock_kernel(); ++ if (IS_ERR(handle)) { ++ ret = PTR_ERR(handle); ++ goto out; ++ } ++ if (final_size > inode->i_size) { ++ lock_kernel(); ++ ret = ext3_orphan_add(handle, inode); ++ unlock_kernel(); ++ if (ret) ++ goto out_stop; ++ orphan = 1; ++ ei->i_disksize = inode->i_size; ++ } ++ } ++ ++ ret = generic_direct_IO(rw, inode, iobuf, blocknr, ++ blocksize, ext3_direct_io_get_block); ++ ++out_stop: ++ if (handle) { ++ int err; ++ ++ lock_kernel(); ++ if (orphan) ++ ext3_orphan_del(handle, inode); ++ if (orphan && ret > 0) { ++ loff_t end = offset + ret; ++ if (end > inode->i_size) { ++ ei->i_disksize = end; ++ inode->i_size = end; ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (!ret) ++ ret = err; ++ } ++ } ++ err = ext3_journal_stop(handle, inode); ++ if (ret == 0) ++ ret = err; ++ unlock_kernel(); ++ } ++out: ++ return ret; ++ ++} + + struct address_space_operations ext3_aops = { + readpage: ext3_readpage, /* BKL not held. Don't need */ +@@ -1390,6 +1485,7 @@ struct address_space_operations ext3_aop + bmap: ext3_bmap, /* BKL held */ + flushpage: ext3_flushpage, /* BKL not held. Don't need */ + releasepage: ext3_releasepage, /* BKL not held. Don't need */ ++ direct_IO: ext3_direct_IO, /* BKL not held. Don't need */ + }; + + /* +@@ -2987,7 +3083,7 @@ int ext3_prep_san_write(struct inode *in + /* alloc blocks one by one */ + for (i = 0; i < nblocks; i++) { + ret = ext3_get_block_handle(handle, inode, blocks[i], +- &bh_tmp, 1); ++ &bh_tmp, 1, 1); + if (ret) + break; + +@@ -3047,7 +3143,7 @@ int ext3_map_inode_page(struct inode *in + if (blocks[i] != 0) + continue; + +- rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1); ++ rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1, 1); + if (rc) { + printk(KERN_INFO "ext3_map_inode_page: error reading " + "block %ld\n", iblock); + +_ diff --git a/lustre/kernel_patches/pc/ext3-o_direct-1-2.4.18-chaos.pc b/lustre/kernel_patches/pc/ext3-o_direct-1-2.4.18-chaos.pc new file mode 100644 index 0000000..76d683f --- /dev/null +++ b/lustre/kernel_patches/pc/ext3-o_direct-1-2.4.18-chaos.pc @@ -0,0 +1 @@ +fs/ext3/inode.c -- 1.8.3.1