Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/994/?format=api
{ "id": 994, "url": "http://patchwork.ozlabs.org/api/patches/994/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/E1KhvsB-0002Ik-Ex@closure.thunk.org/", "project": { "id": 8, "url": "http://patchwork.ozlabs.org/api/projects/8/?format=api", "name": "Linux ext4 filesystem development", "link_name": "linux-ext4", "list_id": "linux-ext4.vger.kernel.org", "list_email": "linux-ext4@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<E1KhvsB-0002Ik-Ex@closure.thunk.org>", "list_archive_url": null, "date": "2008-09-23T00:35:23", "name": "[RFC] ext4: Use preallocation when reading from the inode table", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "f3f0932d47a2b218ac18c0b6220920880f3097a7", "submitter": { "id": 350, "url": "http://patchwork.ozlabs.org/api/people/350/?format=api", "name": "Theodore Ts'o", "email": "tytso@mit.edu" }, "delegate": { "id": 38, "url": "http://patchwork.ozlabs.org/api/users/38/?format=api", "username": "tytso", "first_name": "Theodore", "last_name": "Ts'o", "email": "tytso@mit.edu" }, "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/E1KhvsB-0002Ik-Ex@closure.thunk.org/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/994/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/994/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-ext4-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 2D914DDEDD\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 23 Sep 2008 10:35:29 +1000 (EST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753427AbYIWAf1 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 22 Sep 2008 20:35:27 -0400", "(majordomo@vger.kernel.org) by vger.kernel.org id S1753468AbYIWAf1\n\t(ORCPT <rfc822;linux-ext4-outgoing>);\n\tMon, 22 Sep 2008 20:35:27 -0400", "from www.church-of-our-saviour.org ([69.25.196.31]:53048 \"EHLO\n\tthunker.thunk.org\" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org\n\twith ESMTP id S1753427AbYIWAf0 (ORCPT\n\t<rfc822; linux-ext4@vger.kernel.org>); Mon, 22 Sep 2008 20:35:26 -0400", "from root (helo=closure.thunk.org)\n\tby thunker.thunk.org with local-esmtp (Exim 4.50 #1 (Debian))\n\tid 1KhvsC-00043s-RQ; Mon, 22 Sep 2008 20:35:24 -0400", "from tytso by closure.thunk.org with local (Exim 4.69)\n\t(envelope-from <tytso@mit.edu>)\n\tid 1KhvsB-0002Ik-Ex; Mon, 22 Sep 2008 20:35:23 -0400" ], "To": "linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org", "Subject": "[PATCH,\n\tRFC] ext4: Use preallocation when reading from the inode table", "From": "\"Theodore Ts'o\" <tytso@mit.edu>", "Full-Name": "Theodore Ts'o", "Phone": "(781) 391-3464", "Message-Id": "<E1KhvsB-0002Ik-Ex@closure.thunk.org>", "Date": "Mon, 22 Sep 2008 20:35:23 -0400", "X-SA-Exim-Connect-IP": "<locally generated>", "X-SA-Exim-Mail-From": "tytso@mit.edu", "X-SA-Exim-Scanned": "No (on thunker.thunk.org); SAEximRunCond expanded to false", "Sender": "linux-ext4-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<linux-ext4.vger.kernel.org>", "X-Mailing-List": "linux-ext4@vger.kernel.org" }, "content": "With modern hard drives, reading 64k takes roughly the same time as\nreading a 4k block. So request adjacent inode table blocks to reduce\nthe time it takes when iterating over directories (especially when doing\nthis in htree sort order) in a cold cache case. With this patch, the\ntime it takes to run \"git status\" on a kernel tree after flushing the\ncaches via \"echo 3 > /proc/sys/vm/drop_caches\", is reduced by 21%.\n\nSigned-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n----\n\nNote: this patch could work for ext3 as well. Anyone see any downsides?\nA 20% improvement seems too easy... I guess it does increase what we\nhold in the buffer cache by a small amount, but once the inodes are\ncached, we'll stop needing to do any I/O, and we only try to do the\nreadahead when we know that we need to do some I/O anyway.\n\nThis patch also eliminates ext4_get_inode_block(), since it's a static\nfunction which is only called once, and we needed access to the block\ngroup descriptor, so it simplified the code to move the code into\n__ext4_get_inode_loc(). The interesting bits are in the very last hunk\nof the patch.\n\n\n--\nTo unsubscribe from this list: send the line \"unsubscribe linux-ext4\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at http://vger.kernel.org/majordomo-info.html", "diff": "diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c\nindex eed1265..9f6c10e 100644\n--- a/fs/ext4/inode.c\n+++ b/fs/ext4/inode.c\n@@ -3833,41 +3833,6 @@ out_stop:\n \text4_journal_stop(handle);\n }\n \n-static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,\n-\t\tunsigned long ino, struct ext4_iloc *iloc)\n-{\n-\text4_group_t block_group;\n-\tunsigned long offset;\n-\text4_fsblk_t block;\n-\tstruct ext4_group_desc *gdp;\n-\n-\tif (!ext4_valid_inum(sb, ino)) {\n-\t\t/*\n-\t\t * This error is already checked for in namei.c unless we are\n-\t\t * looking at an NFS filehandle, in which case no error\n-\t\t * report is needed\n-\t\t */\n-\t\treturn 0;\n-\t}\n-\n-\tblock_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);\n-\tgdp = ext4_get_group_desc(sb, block_group, NULL);\n-\tif (!gdp)\n-\t\treturn 0;\n-\n-\t/*\n-\t * Figure out the offset within the block group inode table\n-\t */\n-\toffset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *\n-\t\tEXT4_INODE_SIZE(sb);\n-\tblock = ext4_inode_table(sb, gdp) +\n-\t\t(offset >> EXT4_BLOCK_SIZE_BITS(sb));\n-\n-\tiloc->block_group = block_group;\n-\tiloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);\n-\treturn block;\n-}\n-\n /*\n * ext4_get_inode_loc returns with an extra refcount against the inode's\n * underlying buffer_head on success. If 'in_mem' is true, we have all\n@@ -3877,13 +3842,30 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,\n static int __ext4_get_inode_loc(struct inode *inode,\n \t\t\t\tstruct ext4_iloc *iloc, int in_mem)\n {\n+\tstruct ext4_group_desc *gdp;\n \text4_fsblk_t block;\n \tstruct buffer_head *bh;\n \n-\tblock = ext4_get_inode_block(inode->i_sb, inode->i_ino, iloc);\n-\tif (!block)\n+\tiloc->bh = 0;\n+\tif (!ext4_valid_inum(inode->i_sb, inode->i_ino))\n \t\treturn -EIO;\n \n+\tiloc->block_group = (inode->i_ino - 1) / \n+\t\tEXT4_INODES_PER_GROUP(inode->i_sb);\n+\tgdp = ext4_get_group_desc(inode->i_sb, iloc->block_group, NULL);\n+\tif (!gdp)\n+\t\treturn -EIO;\n+\n+\t/*\n+\t * Figure out the offset within the block group inode table\n+\t */\n+\tiloc->offset = ((inode->i_ino - 1) % \n+\t\t\tEXT4_INODES_PER_GROUP(inode->i_sb)) *\n+\t\tEXT4_INODE_SIZE(inode->i_sb);\n+\tblock = ext4_inode_table(inode->i_sb, gdp) +\n+\t\t(iloc->offset >> EXT4_BLOCK_SIZE_BITS(inode->i_sb));\n+\tiloc->offset = iloc->offset & (EXT4_BLOCK_SIZE(inode->i_sb) - 1);\n+\n \tbh = sb_getblk(inode->i_sb, block);\n \tif (!bh) {\n \t\text4_error (inode->i_sb, \"ext4_get_inode_loc\",\n@@ -3969,6 +3951,31 @@ static int __ext4_get_inode_loc(struct inode *inode,\n \n make_io:\n \t\t/*\n+\t\t * If we need to do any I/O, try to readahead up to 16\n+\t\t * blocks from the inode table.\n+\t\t */\n+\t\t{\n+\t\t\text4_fsblk_t b, end, table;\n+\t\t\tunsigned num;\n+\n+\t\t\ttable = ext4_inode_table(inode->i_sb, gdp);\n+\t\t\tb = block & ~15;\n+\t\t\tif (table > b)\n+\t\t\t\tb = table;\n+\t\t\tend = b+16;\n+\t\t\tnum = EXT4_INODES_PER_GROUP(inode->i_sb);\n+\t\t\tif (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, \n+\t\t\t\t EXT4_FEATURE_RO_COMPAT_GDT_CSUM))\n+\t\t\t\tnum -= le16_to_cpu(gdp->bg_itable_unused);\n+\t\t\ttable += num / (EXT4_BLOCK_SIZE(inode->i_sb) /\n+\t\t\t\t\tEXT4_INODE_SIZE(inode->i_sb));\n+\t\t\tif (end > table)\n+\t\t\t\tend = table;\n+\t\t\twhile (b <= end)\n+\t\t\t\tsb_breadahead(inode->i_sb, b++);\n+\t\t}\n+\n+\t\t/*\n \t\t * There are other valid inodes in the buffer, this inode\n \t\t * has in-inode xattrs, or we don't have this inode in memory.\n \t\t * Read the block from disk.\n", "prefixes": [ "RFC" ] }