From mboxrd@z Thu Jan 1 00:00:00 1970 From: Linus Torvalds Subject: [PATCH 4/3] Avoid using 'lstat()' to figure out directories Date: Thu, 9 Jul 2009 13:44:46 -0700 (PDT) Message-ID: References: <20090707000500.GA5594@dpotapov.dyndns.org> <7vskh646bw.fsf@alter.siamese.dyndns.org> <7vws6h3ji4.fsf@alter.siamese.dyndns.org> <7vab3d3dpc.fsf@alter.siamese.dyndns.org> Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Cc: Dmitry Potapov , Git Mailing List , Kjetil Barvik To: Junio C Hamano X-From: git-owner@vger.kernel.org Thu Jul 09 22:45:40 2009 Return-path: Envelope-to: gcvg-git-2@gmane.org Received: from vger.kernel.org ([209.132.176.167]) by lo.gmane.org with esmtp (Exim 4.50) id 1MP0Ut-0006Ja-Ev for gcvg-git-2@gmane.org; Thu, 09 Jul 2009 22:45:39 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754637AbZGIUpd (ORCPT ); Thu, 9 Jul 2009 16:45:33 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754476AbZGIUpc (ORCPT ); Thu, 9 Jul 2009 16:45:32 -0400 Received: from smtp1.linux-foundation.org ([140.211.169.13]:40364 "EHLO smtp1.linux-foundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753644AbZGIUpb (ORCPT ); Thu, 9 Jul 2009 16:45:31 -0400 Received: from imap1.linux-foundation.org (imap1.linux-foundation.org [140.211.169.55]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id n69KikAX017740 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 9 Jul 2009 13:44:48 -0700 Received: from localhost (localhost [127.0.0.1]) by imap1.linux-foundation.org (8.13.5.20060308/8.13.5/Debian-3ubuntu1.1) with ESMTP id n69Kiket006394; Thu, 9 Jul 2009 13:44:46 -0700 X-X-Sender: torvalds@localhost.localdomain In-Reply-To: User-Agent: Alpine 2.01 (LFD 1184 2008-12-16) X-Spam-Status: No, hits=-3.966 required=5 tests=AWL,BAYES_00,OSDL_HEADER_SUBJECT_BRACKETED X-Spam-Checker-Version: SpamAssassin 3.2.4-osdl_revision__1.47__ X-MIMEDefang-Filter: lf$Revision: 1.188 $ X-Scanned-By: MIMEDefang 2.63 on 140.211.169.13 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: From: Linus Torvalds Date: Thu, 9 Jul 2009 13:14:28 -0700 Subject: [PATCH 4/3] Avoid using 'lstat()' to figure out directories If we have an up-to-date index entry for a file in that directory, we can know that the directories leading up to that file must be directories. No need to do an lstat() on the directory. Signed-off-by: Linus Torvalds --- This is the patch I already sent out earlier. Now it's just numbered. There's going to be an additional three patches to actually give the right behavior for index preloading, so that we can really say "if CE_UPTODATE is set, then the whole directory structure is valid". dir.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 42 insertions(+), 5 deletions(-) diff --git a/dir.c b/dir.c index 8a9e7d8..e05b850 100644 --- a/dir.c +++ b/dir.c @@ -566,18 +566,55 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si return 0; } +static int get_index_dtype(const char *path, int len) +{ + int pos; + struct cache_entry *ce; + + ce = cache_name_exists(path, len, 0); + if (ce) { + if (!ce_uptodate(ce)) + return DT_UNKNOWN; + if (S_ISGITLINK(ce->ce_mode)) + return DT_DIR; + /* + * Nobody actually cares about the + * difference between DT_LNK and DT_REG + */ + return DT_REG; + } + + /* Try to look it up as a directory */ + pos = cache_name_pos(path, len); + if (pos >= 0) + return DT_UNKNOWN; + pos = -pos-1; + while (pos < active_nr) { + ce = active_cache[pos++]; + if (strncmp(ce->name, path, len)) + break; + if (ce->name[len] > '/') + break; + if (ce->name[len] < '/') + continue; + if (!ce_uptodate(ce)) + break; /* continue? */ + return DT_DIR; + } + return DT_UNKNOWN; +} + static int get_dtype(struct dirent *de, const char *path, int len) { int dtype = de ? DTYPE(de) : DT_UNKNOWN; - struct cache_entry *ce; struct stat st; if (dtype != DT_UNKNOWN) return dtype; - ce = cache_name_exists(path, len, 0); - if (ce && ce_uptodate(ce)) - st.st_mode = ce->ce_mode; - else if (lstat(path, &st)) + dtype = get_index_dtype(path, len); + if (dtype != DT_UNKNOWN) + return dtype; + if (lstat(path, &st)) return dtype; if (S_ISREG(st.st_mode)) return DT_REG; -- 1.6.3.3.415.ga8877