From patchwork Fri Aug 22 22:21:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 4767391 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3BFB29F344 for ; Fri, 22 Aug 2014 22:21:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 33A8B2013A for ; Fri, 22 Aug 2014 22:21:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3EF542012F for ; Fri, 22 Aug 2014 22:21:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752311AbaHVWVW (ORCPT ); Fri, 22 Aug 2014 18:21:22 -0400 Received: from mail-ob0-f180.google.com ([209.85.214.180]:63250 "EHLO mail-ob0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751812AbaHVWVW (ORCPT ); Fri, 22 Aug 2014 18:21:22 -0400 Received: by mail-ob0-f180.google.com with SMTP id uy5so8917508obc.25 for ; Fri, 22 Aug 2014 15:21:21 -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=bdgC4W3YHHtxDwx70V7QlsyVq/umG0lUlN3jW38o+fE=; b=LRyAnrvpsbxsJTy5XQYBpv3/yeGlD1IUOL+VrH8osnrf9voT1C2ciGdY5pe8D9l2vy S0ejgLQBRWq0NhjbkktJys//vmDBKlFDkLagbQaZnRuEStVwbmX95W2SVUlU+hnz2o8q UuSzkV9tHg1AqG5HE8YtaEY4KBcvnZCmKDTqtXSRVegzHal3/Xi4+9O4sdl6qW2n4mW/ VwQQNupOcovILDy4MaHo8UKRG0lziJXkY0MBR+z715PMlvYNsB4SRXGTeSha+XuLTeCp 08nSJRHTFnS3vvJ6Qj+5k9GT2KQq4xVdgtlX8ojdYbH1L98LHnAHWqiqlTLoleiEMl1f 3ZgQ== X-Received: by 10.182.66.16 with SMTP id b16mr7506104obt.49.1408746081323; Fri, 22 Aug 2014 15:21:21 -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 w4sm33085303obz.20.2014.08.22.15.21.19 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 22 Aug 2014 15:21:20 -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 3/5] cifs: shared-superblock - various routines to search disconnected root dentry Date: Fri, 22 Aug 2014 17:21:14 -0500 Message-Id: <1408746074-10223-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 The disconnected root dentries in a linked list off of superblock from servers that do not provide uniqueids can be searched by dentries, inodes, and full paths when time comes to search them for either splicing (during lookup) or freeing. Signed-off-by: Shirish Pargaonkar --- fs/cifs/cifsproto.h | 1 + fs/cifs/dir.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c31ce98..c1047e2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -205,6 +205,7 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid, struct tcon_link *tlink, struct cifs_pending_open *open); extern void cifs_del_pending_open(struct cifs_pending_open *open); +extern void cifs_free_rdelem(struct cifs_rdelem *); #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) extern void cifs_dfs_release_automount_timer(void); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3db0c5f..d835ae2 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -691,6 +691,58 @@ mknod_out: return rc; } +struct cifs_rdelem * +find_rdelem_by_inode(struct inode *rdinode, struct cifs_sb_info * cifs_sb) +{ + struct cifs_rdelem *rdelem; + + spin_lock(&cifs_sb->rtdislock); + list_for_each_entry(rdelem, &cifs_sb->rtdislist, rdlist) { + if (rdelem->rdinode == rdinode) { + list_del(&rdelem->rdlist); + spin_unlock(&cifs_sb->rtdislock); + return rdelem; + } + } + spin_unlock(&cifs_sb->rtdislock); + return NULL; +} + +static struct cifs_rdelem * +find_rdelem_by_dentry(const struct dentry *rdentry, + struct cifs_sb_info * cifs_sb) +{ + struct cifs_rdelem *rdelem; + + spin_lock(&cifs_sb->rtdislock); + list_for_each_entry(rdelem, &cifs_sb->rtdislist, rdlist) { + if (rdelem->rdentry == rdentry) { + list_del(&rdelem->rdlist); + spin_unlock(&cifs_sb->rtdislock); + return rdelem; + } + } + spin_unlock(&cifs_sb->rtdislock); + return NULL; +} + +void +find_rdelem_by_path(char *full_path, struct inode **newInode, + struct cifs_sb_info * cifs_sb) +{ + struct cifs_rdelem *rdelem; + + spin_lock(&cifs_sb->rtdislock); + list_for_each_entry(rdelem, &cifs_sb->rtdislist, rdlist) { + if (!strcmp(rdelem->rdname, full_path)) { + *newInode = ilookup(rdelem->rdinode->i_sb, + rdelem->rdinode->i_ino); + break; + } + } + spin_unlock(&cifs_sb->rtdislock); +} + struct dentry * cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, unsigned int flags) @@ -772,6 +824,35 @@ lookup_out: return ERR_PTR(rc); } +static void +cifs_d_common_releasedelete(const struct dentry *dentry) +{ + struct cifs_rdelem *rdelem; + struct cifs_sb_info *cifs_sb; + + cifs_sb = CIFS_SB(dentry->d_sb); + + /* disconnected root dentries that did not get spliced */ + if (IS_ROOT(dentry) && dentry->d_flags & DCACHE_DISCONNECTED) { + rdelem = find_rdelem_by_dentry(dentry, cifs_sb); + if (rdelem) + cifs_free_rdelem(rdelem); + } +} + +static int +cifs_d_delete(const struct dentry *dentry) +{ + cifs_d_common_releasedelete(dentry); + return 0; +} + +static void +cifs_d_release(struct dentry *dentry) +{ + cifs_d_common_releasedelete(dentry); +} + static int cifs_d_revalidate(struct dentry *direntry, unsigned int flags) { @@ -821,19 +902,11 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) return 1; } -/* static int cifs_d_delete(struct dentry *direntry) -{ - int rc = 0; - - cifs_dbg(FYI, "In cifs d_delete, name = %s\n", direntry->d_name.name); - - return rc; -} */ - const struct dentry_operations cifs_dentry_ops = { .d_revalidate = cifs_d_revalidate, .d_automount = cifs_dfs_d_automount, -/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ + .d_delete = cifs_d_delete, + .d_release = cifs_d_release, }; static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q) @@ -908,4 +981,6 @@ const struct dentry_operations cifs_ci_dentry_ops = { .d_hash = cifs_ci_hash, .d_compare = cifs_ci_compare, .d_automount = cifs_dfs_d_automount, + .d_delete = cifs_d_delete, + .d_release = cifs_d_release, };