All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Josef 'Jeff' Sipek" <jsipek@cs.sunysb.edu>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Cc: akpm@linux-foundation.org, Erez Zadok <ezk@cs.sunysb.edu>,
	"Josef 'Jeff' Sipek" <jsipek@cs.sunysb.edu>
Subject: [PATCH 20/21] Unionfs: Added several BUG_ONs to assert dentry validity
Date: Mon,  9 Apr 2007 10:54:11 -0400	[thread overview]
Message-ID: <11761304561019-git-send-email-jsipek@cs.sunysb.edu> (raw)
In-Reply-To: <11761304521844-git-send-email-jsipek@cs.sunysb.edu>

From: Erez Zadok <ezk@cs.sunysb.edu>

This should help catch races between the VFS and the branch-management code.

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
---
 fs/unionfs/inode.c  |   15 +++++++++++++++
 fs/unionfs/rename.c |    3 +++
 fs/unionfs/super.c  |    2 ++
 fs/unionfs/union.h  |   13 +++++++++++++
 fs/unionfs/unlink.c |    4 ++++
 fs/unionfs/xattr.c  |    8 ++++++++
 6 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 5c452b6..97dad8c 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -249,6 +249,9 @@ static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
 	struct dentry *whiteout_dentry;
 	char *name = NULL;
 
+	BUG_ON(!is_valid_dentry(new_dentry));
+	BUG_ON(!is_valid_dentry(old_dentry));
+
 	double_lock_dentry(new_dentry, old_dentry);
 
 	hidden_new_dentry = unionfs_lower_dentry(new_dentry);
@@ -373,6 +376,8 @@ static int unionfs_symlink(struct inode *dir, struct dentry *dentry,
 	int bindex = 0, bstart;
 	char *name = NULL;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 
 	/* We start out in the leftmost branch. */
@@ -495,6 +500,8 @@ static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode)
 	int whiteout_unlinked = 0;
 	struct sioq_args args;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	bstart = dbstart(dentry);
 
@@ -622,6 +629,8 @@ static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
 	char *name = NULL;
 	int whiteout_unlinked = 0;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	bstart = dbstart(dentry);
 
@@ -724,6 +733,8 @@ static int unionfs_readlink(struct dentry *dentry, char __user * buf,
 	int err;
 	struct dentry *hidden_dentry;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	hidden_dentry = unionfs_lower_dentry(dentry);
 
@@ -749,6 +760,8 @@ static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 	int len = PAGE_SIZE, err;
 	mm_segment_t old_fs;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	/* This is freed by the put_link method assuming a successful call. */
 	buf = kmalloc(len, GFP_KERNEL);
 	if (!buf) {
@@ -908,6 +921,8 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
 	int i;
 	int copyup = 0;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	bstart = dbstart(dentry);
 	bend = dbend(dentry);
diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
index c9aa040..0044492 100644
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -379,6 +379,9 @@ int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	int err = 0;
 	struct dentry *wh_dentry;
 
+	BUG_ON(!is_valid_dentry(old_dentry));
+	BUG_ON(!is_valid_dentry(new_dentry));
+
 	double_lock_dentry(old_dentry, new_dentry);
 
 	if (!S_ISDIR(old_dentry->d_inode->i_mode))
diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
index 5d11908..ec5706b 100644
--- a/fs/unionfs/super.c
+++ b/fs/unionfs/super.c
@@ -129,6 +129,8 @@ static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	int err	= 0;
 	struct super_block *sb, *hidden_sb;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	sb = dentry->d_sb;
 
 	unionfs_read_lock(sb);
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index faaa87e..b6fa0a2 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -399,6 +399,19 @@ static inline int is_robranch(const struct dentry *dentry)
 	return is_robranch_idx(dentry, index);
 }
 
+/*
+ * Check if dentry is valid or not, as per our generation numbers.
+ * @dentry: dentry to check.
+ * Returns 1 (valid) or 0 (invalid/stale).
+ */
+static inline int is_valid_dentry(struct dentry *dentry)
+{
+	BUG_ON(!UNIONFS_D(dentry));
+	BUG_ON(!UNIONFS_SB(dentry->d_sb));
+	return (atomic_read(&UNIONFS_D(dentry)->generation) ==
+		atomic_read(&UNIONFS_SB(dentry->d_sb)->generation));
+}
+
 /* What do we use for whiteouts. */
 #define UNIONFS_WHPFX ".wh."
 #define UNIONFS_WHLEN 4
diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
index f5b250a..dd1dd9c 100644
--- a/fs/unionfs/unlink.c
+++ b/fs/unionfs/unlink.c
@@ -74,6 +74,8 @@ int unionfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int err = 0;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 
 	err = unionfs_unlink_whiteout(dir, dentry);
@@ -122,6 +124,8 @@ int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
 	int err = 0;
 	struct unionfs_dir_state *namelist = NULL;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 
 	/* check if this unionfs directory is empty or not */
diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c
index d57f079..6e1f4bd 100644
--- a/fs/unionfs/xattr.c
+++ b/fs/unionfs/xattr.c
@@ -56,6 +56,8 @@ ssize_t unionfs_getxattr(struct dentry * dentry, const char *name, void *value,
 	struct dentry *hidden_dentry = NULL;
 	int err = -EOPNOTSUPP;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 
 	hidden_dentry = unionfs_lower_dentry(dentry);
@@ -75,6 +77,8 @@ int unionfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 	struct dentry *hidden_dentry = NULL;
 	int err = -EOPNOTSUPP;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	hidden_dentry = unionfs_lower_dentry(dentry);
 
@@ -92,6 +96,8 @@ int unionfs_removexattr(struct dentry *dentry, const char *name)
 	struct dentry *hidden_dentry = NULL;
 	int err = -EOPNOTSUPP;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 	hidden_dentry = unionfs_lower_dentry(dentry);
 
@@ -110,6 +116,8 @@ ssize_t unionfs_listxattr(struct dentry * dentry, char *list, size_t size)
 	int err = -EOPNOTSUPP;
 	char *encoded_list = NULL;
 
+	BUG_ON(!is_valid_dentry(dentry));
+
 	unionfs_lock_dentry(dentry);
 
 	hidden_dentry = unionfs_lower_dentry(dentry);
-- 
1.5.0.3.268.g3dda


  parent reply	other threads:[~2007-04-09 14:55 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-09 14:53 [GIT PULL -mm] Unionfs branch management code Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 01/21] fs: Introduce path{get,put} Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 02/21] fs: Export drop_pagecache_sb symbol Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 03/21] Unionfs: Documentation updates for branch-management Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 04/21] Unionfs: Proper comment on rwsem field Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 05/21] Unionfs: Rename unionfs_data sbcount field to more appropriate open_files Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 06/21] Unionfs: Provide more helpful info on branch leaks during unmount Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 07/21] Unionfs: Actually verify if dentry's info node is locked Josef 'Jeff' Sipek
2007-04-09 14:53 ` [PATCH 08/21] Unionfs: Introduce branch-id code Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 09/21] Unionfs: Bulk of branch-management remount code Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 10/21] Unionfs: Introduce unionfs_mnt{get,put} Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 11/21] Unionfs: Rewrite unionfs_d_revalidate Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 12/21] Unionfs: Grab the unionfs sb private data lock around branch info users Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 13/21] Unionfs: Remove the older incgen ioctl Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 14/21] Unionfs: Document unionfs_d_release locking Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 15/21] Unionfs: Decrement totalopens counter on error in unionfs_open Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 16/21] Unionfs: unionfs_create needs to revalidate the dentry Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 17/21] Unionfs: vfsmount reference counting fixes Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 18/21] Unionfs: Pass lowernd to lower ->revalidate function Josef 'Jeff' Sipek
2007-04-09 14:54 ` [PATCH 19/21] Unionfs: Properly handle stale inodes passed to unionfs_permission Josef 'Jeff' Sipek
2007-04-09 14:54 ` Josef 'Jeff' Sipek [this message]
2007-04-09 14:54 ` [PATCH 21/21] Unionfs: Don't inline do_remount_{add,del,mode}_option Josef 'Jeff' Sipek
2007-04-09 17:49 ` [GIT PULL -mm] Unionfs branch management code Andrew Morton
2007-04-09 22:47   ` Josef Sipek
2007-04-10 17:22   ` Shaya Potter
2007-04-10 17:35     ` Josef Sipek
2007-04-09 19:52 ` Jan Engelhardt

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=11761304561019-git-send-email-jsipek@cs.sunysb.edu \
    --to=jsipek@cs.sunysb.edu \
    --cc=akpm@linux-foundation.org \
    --cc=ezk@cs.sunysb.edu \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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.