All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: viro@zeniv.linux.org.uk
Cc: Jan Harkes <jaharkes@cs.cmu.edu>,
	coda@cs.cmu.edu, codalist@coda.cs.cmu.edu, dhowells@redhat.com,
	linux-afs@lists.infradead.org, linux-ext4@vger.kernel.org,
	linux-ntfs-dev@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 1/6] vfs, coda: Fix the lack of locking in FID replacement inode rehashing
Date: Thu, 18 Apr 2019 15:06:07 +0100	[thread overview]
Message-ID: <155559636704.21702.4538723150377303298.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <155559635133.21702.4737487773869377967.stgit@warthog.procyon.org.uk>

When coda attempts to recover from disconnected operation, there exists the
possibility of an file created during disconnected operation not being
creatable on the server with the same file identifier (FID).  In such a
case, coda_replace_fid() has to rehash the inode and move it between chains
- but, as the comment notes, this really needs some locking.

Fix this by moving the core part of the code to fs/inode.c and providing it
with a set() function akin to iget5().  We can then take the inode cache
lock whilst performing the move.

Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Jan Harkes <jaharkes@cs.cmu.edu>
cc: coda@cs.cmu.edu
cc: codalist@coda.cs.cmu.edu
---

 fs/coda/cnode.c    |   11 +++++++++++
 fs/inode.c         |   23 +++++++++++++++++++++++
 include/linux/fs.h |    3 +++
 3 files changed, 37 insertions(+)

diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 845b5a66952a..ab6ba6e00674 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -107,6 +107,15 @@ struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
 }
 
 
+static void coda_reset_inode(struct inode *inode, unsigned long hash, void *data)
+{
+	struct CodaFid *fid = (struct CodaFid *)data;
+	struct coda_inode_info *cii = ITOC(inode);
+
+	cii->c_fid = *fid;
+	inode->i_ino = hash;
+}
+
 /* Although we treat Coda file identifiers as immutable, there is one
  * special case for files created during a disconnection where they may
  * not be globally unique. When an identifier collision is detected we
@@ -123,6 +132,8 @@ void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid,
 	
 	BUG_ON(!coda_fideq(&cii->c_fid, oldfid));
 
+	rehash_inode(inode, hash, coda_reset_inode, newfid);
+	
 	/* replace fid and rehash inode */
 	/* XXX we probably need to hold some lock here! */
 	remove_inode_hash(inode);
diff --git a/fs/inode.c b/fs/inode.c
index e9d97add2b36..00bb48ca3642 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -501,6 +501,29 @@ void __remove_inode_hash(struct inode *inode)
 }
 EXPORT_SYMBOL(__remove_inode_hash);
 
+/**
+ * rehash_inode - Relabel and rehash an inode
+ * @inode: Inode to rehash
+ * @hashval: New hash value (usually inode number) to get
+ * @reset: Callback used to relabel the inode
+ * @data: Opaque data pointer to pass to @reset
+ */
+void rehash_inode(struct inode *inode, unsigned long hashval,
+		  void (*reset)(struct inode *inode, unsigned long hashval, void *data),
+		  void *data)
+{
+	struct hlist_head *b = inode_hashtable + hash(inode->i_sb, hashval);
+
+	spin_lock(&inode_hash_lock);
+	spin_lock(&inode->i_lock);
+	hlist_del_init(&inode->i_hash);
+	reset(inode, hashval, data);
+	hlist_add_head(&inode->i_hash, b);
+	spin_unlock(&inode->i_lock);
+	spin_unlock(&inode_hash_lock);
+}
+EXPORT_SYMBOL(rehash_inode);
+
 void clear_inode(struct inode *inode)
 {
 	/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 744908e0bdec..654edbb93199 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3020,6 +3020,9 @@ static inline void remove_inode_hash(struct inode *inode)
 		__remove_inode_hash(inode);
 }
 
+extern void rehash_inode(struct inode *, unsigned long,
+			 void (*reset)(struct inode *, unsigned long, void *), void *);
+
 extern void inode_sb_list_add(struct inode *inode);
 
 #ifdef CONFIG_BLOCK


  reply	other threads:[~2019-04-18 14:06 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-18 14:05 [RFC PATCH 0/6] vfs: Make icache searchable under RCU David Howells
2019-04-18 14:06 ` David Howells [this message]
2019-04-18 14:48   ` [RFC PATCH 1/6] vfs, coda: Fix the lack of locking in FID replacement inode rehashing Jan Harkes
2019-04-18 16:10   ` Matthew Wilcox
2019-04-18 16:12   ` David Howells
2019-04-18 14:06 ` [RFC PATCH 2/6] vfs: Change inode_hash_lock to a seqlock David Howells
2019-04-18 14:06 ` [RFC PATCH 3/6] vfs: Allow searching of the icache under RCU conditions David Howells
2019-04-18 14:06 ` [RFC PATCH 4/6] afs: Use RCU inode cache search for callback resolution David Howells
2019-04-18 14:06 ` [RFC PATCH 5/6] ext4: Search for an inode to update under the RCU lock if we can David Howells
2019-04-18 15:08   ` Al Viro
2019-04-18 14:06 ` [RFC PATCH 6/6] vfs: Delete find_inode_nowait() David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=155559636704.21702.4538723150377303298.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=coda@cs.cmu.edu \
    --cc=codalist@coda.cs.cmu.edu \
    --cc=jaharkes@cs.cmu.edu \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-ntfs-dev@lists.sourceforge.net \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.