Whamcloud - gitweb
- ext3-noread-inode.patch added
authoralex_tomas <alex_tomas>
Sat, 12 Jul 2003 09:36:55 +0000 (09:36 +0000)
committeralex_tomas <alex_tomas>
Sat, 12 Jul 2003 09:36:55 +0000 (09:36 +0000)
lustre/kernel_patches/patches/ext3-noread-inode.patch [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-noread-inode.pc [new file with mode: 0644]

diff --git a/lustre/kernel_patches/patches/ext3-noread-inode.patch b/lustre/kernel_patches/patches/ext3-noread-inode.patch
new file mode 100644 (file)
index 0000000..a50d12b
--- /dev/null
@@ -0,0 +1,177 @@
+
+ext3_get_inode_loc() read inode's block only if:
+  1) this inode has no copy in memory
+  2) inode's block has another valid inode(s)
+
+this optimization allows to avoid needless I/O in two cases:
+1) just allocated inode is first valid in the inode's block
+2) kernel wants to write inode, but buffer in which inode
+   belongs to gets freed by VM
+
+
+
+
+diff -puN fs/ext3/inode.c~ext3-noread-inode fs/ext3/inode.c
+--- linux-2.5.73/fs/ext3/inode.c~ext3-noread-inode     Thu Jul 10 12:03:52 2003
++++ linux-2.5.73-alexey/fs/ext3/inode.c        Thu Jul 10 15:52:59 2003
+@@ -2286,7 +2286,7 @@ out_stop:
+  * inode's underlying buffer_head on success. 
+  */
+-int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
++int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc, int in_mem)
+ {
+       struct buffer_head *bh = 0;
+       unsigned long block;
+@@ -2328,12 +2328,88 @@ int ext3_get_inode_loc (struct inode *in
+               EXT3_INODE_SIZE(inode->i_sb);
+       block = le32_to_cpu(gdp[desc].bg_inode_table) +
+               (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
+-      if (!(bh = sb_bread(inode->i_sb, block))) {
++      if (!(bh = sb_getblk(inode->i_sb, block))) {
+               ext3_error (inode->i_sb, "ext3_get_inode_loc",
+                           "unable to read inode block - "
+                           "inode=%lu, block=%lu", inode->i_ino, block);
+               goto bad_inode;
+       }
++      if (!buffer_uptodate(bh)) {
++              lock_buffer(bh);
++              if (buffer_uptodate(bh)) {
++                      /* someone has already initialized buffer */
++                      unlock_buffer(bh);
++                      goto has_buffer;
++              }
++
++              /* we can't skip I/O if inode is on a disk only */
++              if (in_mem) {
++                      struct buffer_head *bitmap_bh; 
++                      struct ext3_group_desc *desc;
++                      int inodes_per_buffer;
++                      int inode_offset, i;
++                      int start;
++
++                      /*
++                       * if this inode is only valid in buffer we need not I/O
++                       */
++                      inodes_per_buffer = bh->b_size /
++                              EXT3_INODE_SIZE(inode->i_sb);
++                      inode_offset = ((inode->i_ino - 1) %
++                                      EXT3_INODES_PER_GROUP(inode->i_sb));
++                      start = inode_offset & ~(inodes_per_buffer - 1);
++
++                      /* check is inode bitmap is in cache? */
++                      desc = ext3_get_group_desc(inode->i_sb, block_group, NULL);
++                      if (!desc)
++                              goto make_io;
++
++                      bitmap_bh = sb_getblk(inode->i_sb, le32_to_cpu(desc->bg_inode_bitmap));
++                      if (!bitmap_bh)
++                              goto make_io;
++
++                      /* 
++                       * if inode bitmap isn't in cache then we may end up by 2 reads
++                       * instead of 1 read before optimizing. skip it
++                       */
++                      if (!buffer_uptodate(bitmap_bh)) {
++                              brelse(bitmap_bh);
++                              goto make_io;
++                      }
++                      for (i = start; i < start + inodes_per_buffer; i++) {
++                              if (i == inode_offset)
++                                      continue;
++                              if (ext3_test_bit(i, bitmap_bh->b_data))
++                                      break;
++                      }
++                      brelse(bitmap_bh);
++                      if (i == start + inodes_per_buffer) {
++                              /* all inodes (but our) are free. so, we skip I/O */
++                              memset(bh->b_data, 0, bh->b_size);
++                              set_buffer_uptodate(bh);
++                              unlock_buffer(bh);
++                              goto has_buffer;
++                      }
++              }
++
++make_io:
++              /*
++               * No, there are another valid inodes in the buffer
++               * so, to preserve them we have to read buffer from
++               * the disk
++               */
++              get_bh(bh);
++              bh->b_end_io = end_buffer_io_sync;
++              submit_bh(READ, bh);
++              wait_on_buffer(bh);
++              if (!buffer_uptodate(bh)) {
++                      ext3_error (inode->i_sb, "ext3_get_inode_loc",
++                                      "unable to read inode block - "
++                                      "inode=%lu, block=%lu", inode->i_ino, block);
++                      goto bad_inode;
++              }
++      }
++  has_buffer:
+       offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
+       iloc->bh = bh;
+@@ -2376,7 +2452,7 @@ void ext3_read_inode(struct inode * inod
+ endif
+       if (ext3_iopen_get_inode(inode))
+               return;
+-      if (ext3_get_inode_loc(inode, &iloc))
++      if (ext3_get_inode_loc(inode, &iloc, 0))
+               goto bad_inode;
+       bh = iloc.bh;
+       raw_inode = iloc.raw_inode;
+@@ -2781,7 +2857,7 @@ ext3_reserve_inode_write(handle_t *handl
+ {
+       int err = 0;
+       if (handle) {
+-              err = ext3_get_inode_loc(inode, iloc);
++              err = ext3_get_inode_loc(inode, iloc, 1);
+               if (!err) {
+                       BUFFER_TRACE(iloc->bh, "get_write_access");
+                       err = ext3_journal_get_write_access(handle, iloc->bh);
+@@ -2879,7 +2955,7 @@ ext3_pin_inode(handle_t *handle, struct 
+       int err = 0;
+       if (handle) {
+-              err = ext3_get_inode_loc(inode, &iloc);
++              err = ext3_get_inode_loc(inode, &iloc, 1);
+               if (!err) {
+                       BUFFER_TRACE(iloc.bh, "get_write_access");
+                       err = journal_get_write_access(handle, iloc.bh);
+diff -puN fs/ext3/ialloc.c~ext3-noread-inode fs/ext3/ialloc.c
+--- linux-2.5.73/fs/ext3/ialloc.c~ext3-noread-inode    Thu Jul 10 13:05:37 2003
++++ linux-2.5.73-alexey/fs/ext3/ialloc.c       Thu Jul 10 13:06:12 2003
+@@ -50,7 +50,7 @@
+  *
+  * Return buffer_head of bitmap on success or NULL.
+  */
+-static struct buffer_head *
++struct buffer_head *
+ read_inode_bitmap(struct super_block * sb, unsigned long block_group)
+ {
+       struct ext3_group_desc *desc;
+diff -puN include/linux/ext3_fs.h~ext3-noread-inode include/linux/ext3_fs.h
+--- linux-2.5.73/include/linux/ext3_fs.h~ext3-noread-inode     Thu Jul 10 13:41:59 2003
++++ linux-2.5.73-alexey/include/linux/ext3_fs.h        Thu Jul 10 14:40:13 2003
+@@ -717,6 +717,8 @@ extern unsigned long ext3_count_free_ino
+ extern unsigned long ext3_count_dirs (struct super_block *);
+ extern void ext3_check_inodes_bitmap (struct super_block *);
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
++extern struct buffer_head * read_inode_bitmap(struct super_block *, unsigned long);
++
+ /* inode.c */
+@@ -724,7 +726,7 @@ extern int ext3_forget(handle_t *, int, 
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+-extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
++extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *, int);
+ extern void ext3_read_inode (struct inode *);
+ extern void ext3_write_inode (struct inode *, int);
+ extern int  ext3_setattr (struct dentry *, struct iattr *);
+
+_
diff --git a/lustre/kernel_patches/pc/ext3-noread-inode.pc b/lustre/kernel_patches/pc/ext3-noread-inode.pc
new file mode 100644 (file)
index 0000000..9c3cea8
--- /dev/null
@@ -0,0 +1,3 @@
+fs/ext3/ialloc.c
+fs/ext3/inode.c
+include/linux/ext3_fs.h