Whamcloud - gitweb
- minor changes in Andreas'es ext3 direct-io patch to be applicable for
authoralex <alex>
Mon, 28 Jul 2003 12:02:04 +0000 (12:02 +0000)
committeralex <alex>
Mon, 28 Jul 2003 12:02:04 +0000 (12:02 +0000)
  2.4.18-chaos
- ext3-o_direct-1-2.4.18-chaos.patch have been added to chaos-2.4.18 series

lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-o_direct-1-2.4.18-chaos.pc [new file with mode: 0644]

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 (file)
index 0000000..04f4948
--- /dev/null
@@ -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 <linux/ext3_jbd.h>
+ #include <linux/jbd.h>
+ #include <linux/locks.h>
++#include <linux/iobuf.h>
+ #include <linux/smp_lock.h>
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+@@ -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 (file)
index 0000000..76d683f
--- /dev/null
@@ -0,0 +1 @@
+fs/ext3/inode.c