Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/771/?format=api
{ "id": 771, "url": "http://patchwork.ozlabs.org/api/patches/771/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/E1KhEil-0004s7-Ve@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": "<E1KhEil-0004s7-Ve@closure.thunk.org>", "list_archive_url": null, "date": "2008-09-21T02:30:47", "name": "ext4: Don't use 'struct dentry' for internal lookups", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": true, "hash": "c565175ceebc55fc39d6143a1cebec0ad512dbdc", "submitter": { "id": 350, "url": "http://patchwork.ozlabs.org/api/people/350/?format=api", "name": "Theodore Ts'o", "email": "tytso@mit.edu" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/E1KhEil-0004s7-Ve@closure.thunk.org/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/771/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/771/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 C7C56DDE98\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSun, 21 Sep 2008 13:16:01 +1000 (EST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752342AbYIUDP5 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tSat, 20 Sep 2008 23:15:57 -0400", "(majordomo@vger.kernel.org) by vger.kernel.org id S1752425AbYIUDP4\n\t(ORCPT <rfc822;linux-ext4-outgoing>);\n\tSat, 20 Sep 2008 23:15:56 -0400", "from www.church-of-our-saviour.org ([69.25.196.31]:40967 \"EHLO\n\tthunker.thunk.org\" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org\n\twith ESMTP id S1752342AbYIUDPz (ORCPT\n\t<rfc822; linux-ext4@vger.kernel.org>); Sat, 20 Sep 2008 23:15:55 -0400", "from root (helo=closure.thunk.org)\n\tby thunker.thunk.org with local-esmtp (Exim 4.50 #1 (Debian))\n\tid 1KhFQP-0001fl-Fi; Sat, 20 Sep 2008 23:15:54 -0400", "from tytso by closure.thunk.org with local (Exim 4.69)\n\t(envelope-from <tytso@mit.edu>)\n\tid 1KhEil-0004s7-Ve; Sat, 20 Sep 2008 22:30:47 -0400" ], "To": "linux-ext4@vger.kernel.org", "cc": "Linus Torvalds <torvalds@linux-foundation.org>", "Subject": "[PATCH] ext4: Don't use 'struct dentry' for internal lookups", "From": "\"Theodore Ts'o\" <tytso@mit.edu>", "Full-Name": "Theodore Ts'o", "Phone": "(781) 391-3464", "Message-Id": "<E1KhEil-0004s7-Ve@closure.thunk.org>", "Date": "Sat, 20 Sep 2008 22:30:47 -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": "This is a port of a patch from Linus which fixes a 200+ byte stack\nusage problem in ext4_get_parent().\n\nIt's more efficient to pass down only the actual parts of the dentry\nthat matter: the parent inode and the name, instead of allocating a\nstruct dentry on the stack.\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\nSigned-off-by: \"Theodore Ts'o\" <tytso@mit.edu>\n---\n\nLinus, I plan to push this to you at the next patch window; I'm just\ncc'ing you now since you authored the original patch.\n\nIt seems that the ext3 version of the patch seems not to have been\npicked up by akpm. Want me to resend it to him?\n\nAlso, per your complaints about the stack-heavy ext3 users, one fairly\neasy fix for x86_64 (the stack usage isn't all that bad on x86 when\npointers are only 32-bits) is pretty much all of the places where we use\n\"unsigned long\" in fs/ext3 should be safely replaceable by \"unsigned\nint\" or \"u32\". Sigh... legacy code back when long==int==32-bits, but no\none has bothered to fix it. This won't completely fix the worst of the\nstack abusers, but it should help a little.... I'll try to put together\na patch to deal with this, in my copious spare time.... hey, at least\nour stack usage is not as bad as XFS! :-P\n\n\t\t\t\t\t - Ted\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/namei.c b/fs/ext4/namei.c\nindex a1f72d2..205e740 100644\n--- a/fs/ext4/namei.c\n+++ b/fs/ext4/namei.c\n@@ -159,7 +159,7 @@ static void dx_set_count(struct dx_entry *entries, unsigned value);\n static void dx_set_limit(struct dx_entry *entries, unsigned value);\n static unsigned dx_root_limit(struct inode *dir, unsigned infosize);\n static unsigned dx_node_limit(struct inode *dir);\n-static struct dx_frame *dx_probe(struct dentry *dentry,\n+static struct dx_frame *dx_probe(const struct qstr *d_name,\n \t\t\t\t struct inode *dir,\n \t\t\t\t struct dx_hash_info *hinfo,\n \t\t\t\t struct dx_frame *frame,\n@@ -177,8 +177,10 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,\n \t\t\t\t struct dx_frame *frame,\n \t\t\t\t struct dx_frame *frames,\n \t\t\t\t __u32 *start_hash);\n-static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,\n-\t\t struct ext4_dir_entry_2 **res_dir, int *err);\n+static struct buffer_head * ext4_dx_find_entry(struct inode *dir,\n+\t\tconst struct qstr *d_name,\n+\t\tstruct ext4_dir_entry_2 **res_dir,\n+\t\tint *err);\n static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,\n \t\t\t struct inode *inode);\n \n@@ -345,7 +347,7 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,\n * back to userspace.\n */\n static struct dx_frame *\n-dx_probe(struct dentry *dentry, struct inode *dir,\n+dx_probe(const struct qstr *d_name, struct inode *dir,\n \t struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)\n {\n \tunsigned count, indirect;\n@@ -356,8 +358,6 @@ dx_probe(struct dentry *dentry, struct inode *dir,\n \tu32 hash;\n \n \tframe->bh = NULL;\n-\tif (dentry)\n-\t\tdir = dentry->d_parent->d_inode;\n \tif (!(bh = ext4_bread (NULL,dir, 0, 0, err)))\n \t\tgoto fail;\n \troot = (struct dx_root *) bh->b_data;\n@@ -373,8 +373,8 @@ dx_probe(struct dentry *dentry, struct inode *dir,\n \t}\n \thinfo->hash_version = root->info.hash_version;\n \thinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;\n-\tif (dentry)\n-\t\text4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);\n+\tif (d_name)\n+\t\text4fs_dirhash(d_name->name, d_name->len, hinfo);\n \thash = hinfo->hash;\n \n \tif (root->info.unused_flags & 1) {\n@@ -649,7 +649,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,\n \t}\n \thinfo.hash = start_hash;\n \thinfo.minor_hash = 0;\n-\tframe = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err);\n+\tframe = dx_probe(NULL, dir, &hinfo, frames, &err);\n \tif (!frame)\n \t\treturn err;\n \n@@ -805,15 +805,15 @@ static inline int ext4_match (int len, const char * const name,\n */\n static inline int search_dirblock(struct buffer_head *bh,\n \t\t\t\t struct inode *dir,\n-\t\t\t\t struct dentry *dentry,\n+\t\t\t\t const struct qstr *d_name,\n \t\t\t\t unsigned long offset,\n \t\t\t\t struct ext4_dir_entry_2 ** res_dir)\n {\n \tstruct ext4_dir_entry_2 * de;\n \tchar * dlimit;\n \tint de_len;\n-\tconst char *name = dentry->d_name.name;\n-\tint namelen = dentry->d_name.len;\n+\tconst char *name = d_name->name;\n+\tint namelen = d_name->len;\n \n \tde = (struct ext4_dir_entry_2 *) bh->b_data;\n \tdlimit = bh->b_data + dir->i_sb->s_blocksize;\n@@ -852,7 +852,8 @@ static inline int search_dirblock(struct buffer_head *bh,\n * The returned buffer_head has ->b_count elevated. The caller is expected\n * to brelse() it when appropriate.\n */\n-static struct buffer_head * ext4_find_entry (struct dentry *dentry,\n+static struct buffer_head * ext4_find_entry (struct inode *dir,\n+\t\t\t\t\tconst struct qstr *d_name,\n \t\t\t\t\tstruct ext4_dir_entry_2 ** res_dir)\n {\n \tstruct super_block *sb;\n@@ -866,16 +867,15 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,\n \tint num = 0;\n \text4_lblk_t nblocks;\n \tint i, err;\n-\tstruct inode *dir = dentry->d_parent->d_inode;\n \tint namelen;\n \n \t*res_dir = NULL;\n \tsb = dir->i_sb;\n-\tnamelen = dentry->d_name.len;\n+\tnamelen = d_name.len;\n \tif (namelen > EXT4_NAME_LEN)\n \t\treturn NULL;\n \tif (is_dx(dir)) {\n-\t\tbh = ext4_dx_find_entry(dentry, res_dir, &err);\n+\t\tbh = ext4_dx_find_entry(dir, d_name, res_dir, &err);\n \t\t/*\n \t\t * On success, or if the error was file not found,\n \t\t * return. Otherwise, fall back to doing a search the\n@@ -928,7 +928,7 @@ restart:\n \t\t\tbrelse(bh);\n \t\t\tgoto next;\n \t\t}\n-\t\ti = search_dirblock(bh, dir, dentry,\n+\t\ti = search_dirblock(bh, dir, d_name,\n \t\t\t block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);\n \t\tif (i == 1) {\n \t\t\tEXT4_I(dir)->i_dir_start_lookup = block;\n@@ -962,7 +962,7 @@ cleanup_and_exit:\n \treturn ret;\n }\n \n-static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,\n+static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,\n \t\t struct ext4_dir_entry_2 **res_dir, int *err)\n {\n \tstruct super_block * sb;\n@@ -973,14 +973,13 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,\n \tstruct buffer_head *bh;\n \text4_lblk_t block;\n \tint retval;\n-\tint namelen = dentry->d_name.len;\n-\tconst u8 *name = dentry->d_name.name;\n-\tstruct inode *dir = dentry->d_parent->d_inode;\n+\tint namelen = d_name->len;\n+\tconst u8 *name = d_name->name;\n \n \tsb = dir->i_sb;\n \t/* NFS may look up \"..\" - look at dx_root directory block */\n \tif (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\\0')){\n-\t\tif (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))\n+\t\tif (!(frame = dx_probe(d_name, dir, &hinfo, frames, err)))\n \t\t\treturn NULL;\n \t} else {\n \t\tframe = frames;\n@@ -1041,7 +1040,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru\n \tif (dentry->d_name.len > EXT4_NAME_LEN)\n \t\treturn ERR_PTR(-ENAMETOOLONG);\n \n-\tbh = ext4_find_entry(dentry, &de);\n+\tbh = ext4_find_entry(dir, &dentry->d_name, &de);\n \tinode = NULL;\n \tif (bh) {\n \t\tunsigned long ino = le32_to_cpu(de->inode);\n@@ -1064,15 +1063,14 @@ struct dentry *ext4_get_parent(struct dentry *child)\n \tunsigned long ino;\n \tstruct dentry *parent;\n \tstruct inode *inode;\n-\tstruct dentry dotdot;\n+\tstatic const struct qstr dotdot = {\n+\t\t.name = \"..\",\n+\t\t.len = 2,\n+\t};\n \tstruct ext4_dir_entry_2 * de;\n \tstruct buffer_head *bh;\n \n-\tdotdot.d_name.name = \"..\";\n-\tdotdot.d_name.len = 2;\n-\tdotdot.d_parent = child; /* confusing, isn't it! */\n-\n-\tbh = ext4_find_entry(&dotdot, &de);\n+\tbh = ext4_find_entry(child->d_inode, &dotdot, &de);\n \tinode = NULL;\n \tif (!bh)\n \t\treturn ERR_PTR(-ENOENT);\n@@ -1508,7 +1506,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,\n \tstruct ext4_dir_entry_2 *de;\n \tint err;\n \n-\tframe = dx_probe(dentry, NULL, &hinfo, frames, &err);\n+\tframe = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err);\n \tif (!frame)\n \t\treturn err;\n \tentries = frame->entries;\n@@ -2089,7 +2087,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)\n \t\treturn PTR_ERR(handle);\n \n \tretval = -ENOENT;\n-\tbh = ext4_find_entry(dentry, &de);\n+\tbh = ext4_find_entry(dir, &dentry->d_name, &de);\n \tif (!bh)\n \t\tgoto end_rmdir;\n \n@@ -2151,7 +2149,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)\n \t\thandle->h_sync = 1;\n \n \tretval = -ENOENT;\n-\tbh = ext4_find_entry(dentry, &de);\n+\tbh = ext4_find_entry(dir, &dentry->d_name, &de);\n \tif (!bh)\n \t\tgoto end_unlink;\n \n@@ -2312,7 +2310,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,\n \tif (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))\n \t\thandle->h_sync = 1;\n \n-\told_bh = ext4_find_entry(old_dentry, &old_de);\n+\told_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de);\n \t/*\n \t * Check for inode number is _not_ due to possible IO errors.\n \t * We might rmdir the source, keep it as pwd of some process\n@@ -2325,7 +2323,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,\n \t\tgoto end_rename;\n \n \tnew_inode = new_dentry->d_inode;\n-\tnew_bh = ext4_find_entry(new_dentry, &new_de);\n+\tnew_bh = ext4_find_entry(new_dir, &new_dentry->d_name, &new_de);\n \tif (new_bh) {\n \t\tif (!new_inode) {\n \t\t\tbrelse(new_bh);\n@@ -2392,7 +2390,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,\n \t\tstruct buffer_head *old_bh2;\n \t\tstruct ext4_dir_entry_2 *old_de2;\n \n-\t\told_bh2 = ext4_find_entry(old_dentry, &old_de2);\n+\t\told_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de2);\n \t\tif (old_bh2) {\n \t\t\tretval = ext4_delete_entry(handle, old_dir,\n \t\t\t\t\t\t old_de2, old_bh2);\n", "prefixes": [] }