From patchwork Fri Aug 22 22:21:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 4767411 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 533DCC0338 for ; Fri, 22 Aug 2014 22:21:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6A13D2013A for ; Fri, 22 Aug 2014 22:21:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7E15F2012F for ; Fri, 22 Aug 2014 22:21:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752308AbaHVWVw (ORCPT ); Fri, 22 Aug 2014 18:21:52 -0400 Received: from mail-oi0-f52.google.com ([209.85.218.52]:57970 "EHLO mail-oi0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752061AbaHVWVw (ORCPT ); Fri, 22 Aug 2014 18:21:52 -0400 Received: by mail-oi0-f52.google.com with SMTP id h136so8150935oig.39 for ; Fri, 22 Aug 2014 15:21:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=qlNhF9degNSfkTLFwPizSQ2hc/06+pSLlE/PfMG3pP4=; b=aGJh05AVPnLHpUhTvGRgwM1cjz5WFc2I+BhsPcRnse+iUoKxEapezYf7jWOat0Gvk+ 4rDzORAdc++oicjOPmKADU+XXVevxXIG0tCq/8o/uoUoheZ1wjGw7ULNW/iqZGhn6XtJ tvi2HJ+1X4E47cTvBcm1QO0Zu5z+fQwKJvhLfuIdvROwpRjZM994Giqzns6My0fXCFgd 6TqGDkcxruaNIX6zs7zHd4PORRINRuQibvNNXi8k8y2BaNSOU1LMlbyx72UR6AtNcSj9 4lZAOPss2apYGI+lXGazFrGHBi7qncCKtRrC3btDRbeQhdGRNtgTT7rsmneuXQ0Z6W3L goIQ== X-Received: by 10.60.74.232 with SMTP id x8mr70041oev.84.1408746111652; Fri, 22 Aug 2014 15:21:51 -0700 (PDT) Received: from shirish-ThinkPad-T400.gns.novell.com (75-13-85-90.lightspeed.austtx.sbcglobal.net. [75.13.85.90]) by mx.google.com with ESMTPSA id o2sm8953174obn.13.2014.08.22.15.21.49 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 22 Aug 2014 15:21:50 -0700 (PDT) From: shirishpargaonkar@gmail.com X-Google-Original-From: spargaonkar@suse.com To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org, shirish , Shirish Pargaonkar Subject: [PATCH 5/5] cifs: shared-superblock - splice disconnected dentry Date: Fri, 22 Aug 2014 17:21:43 -0500 Message-Id: <1408746103-10300-1-git-send-email-spargaonkar@suse.com> X-Mailer: git-send-email 1.8.3.2 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: shirish splice the dentry during lookup. In case of servers who do not provide uniqueids, look in the linked list off of superblock before sending out a query on the wire and also do a dentry search before splicing and free the entry in the linked list. Signed-off-by: Shirish Pargaonkar --- fs/cifs/dir.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index d835ae2..b6ebb8c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -691,7 +691,7 @@ mknod_out: return rc; } -struct cifs_rdelem * +static struct cifs_rdelem * find_rdelem_by_inode(struct inode *rdinode, struct cifs_sb_info * cifs_sb) { struct cifs_rdelem *rdelem; @@ -726,7 +726,7 @@ find_rdelem_by_dentry(const struct dentry *rdentry, return NULL; } -void +static void find_rdelem_by_path(char *full_path, struct inode **newInode, struct cifs_sb_info * cifs_sb) { @@ -754,6 +754,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct cifs_tcon *pTcon; struct inode *newInode = NULL; char *full_path = NULL; + struct dentry *ret = NULL; + struct cifs_rdelem *rdelem; + struct qstr dname; xid = get_xid(); @@ -791,20 +794,62 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, direntry->d_inode); - if (pTcon->unix_ext) { - rc = cifs_get_inode_info_unix(&newInode, full_path, - parent_dir_inode->i_sb, xid); - } else { - rc = cifs_get_inode_info(&newInode, full_path, NULL, - parent_dir_inode->i_sb, xid, NULL); + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { + /* + * Looking for an existing disconnected root dentry if any, + * before sending out a lookup on the wire. + */ + find_rdelem_by_path(full_path, &newInode, cifs_sb); } + if (!newInode) { + if (pTcon->unix_ext) { + rc = cifs_get_inode_info_unix(&newInode, full_path, + parent_dir_inode->i_sb, xid); + } else + rc = cifs_get_inode_info(&newInode, full_path, NULL, + parent_dir_inode->i_sb, xid, NULL); + } + /* else, found an anonymous root dentry with an inode */ + if ((rc == 0) && (newInode != NULL)) { - d_add(direntry, newInode); /* since paths are not looked up by component - the parent directories are presumed to be good here */ - renew_parental_timestamps(direntry); + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { + dname.name = direntry->d_name.name; + dname.len = strlen(direntry->d_name.name) + 1; + /* + * Perhaps another lookup beat us to this. + */ + spin_lock(&cifs_sb->rtdislock); + ret = d_lookup(direntry->d_parent, &dname); + if (ret && !IS_ERR(ret)) { + dput(ret); + spin_unlock(&cifs_sb->rtdislock); + goto lookup_out; + } else + ret = d_splice_alias(newInode, direntry); + spin_unlock(&cifs_sb->rtdislock); + } else + ret = d_splice_alias(newInode, direntry); + if (!ret) + renew_parental_timestamps(direntry); + else { + if (!IS_ERR(ret)) { + if (!(cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_SERVER_INUM)) { + rdelem = + find_rdelem_by_inode(newInode, cifs_sb); + if (rdelem) + cifs_free_rdelem(rdelem); + } + renew_parental_timestamps(ret); + dput(ret); + goto lookup_out; + } else + rc = PTR_ERR(ret); + } } else if (rc == -ENOENT) { rc = 0; direntry->d_time = jiffies; @@ -816,12 +861,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, /* We special case check for Access Denied - since that is a common return code */ } + ret = ERR_PTR(rc); lookup_out: kfree(full_path); cifs_put_tlink(tlink); free_xid(xid); - return ERR_PTR(rc); + return ret; } static void