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>
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);
int bindex = 0, bstart;
char *name = NULL;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
/* We start out in the leftmost branch. */
int whiteout_unlinked = 0;
struct sioq_args args;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
bstart = dbstart(dentry);
char *name = NULL;
int whiteout_unlinked = 0;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
bstart = dbstart(dentry);
int err;
struct dentry *hidden_dentry;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
hidden_dentry = unionfs_lower_dentry(dentry);
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) {
int i;
int copyup = 0;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
bstart = dbstart(dentry);
bend = dbend(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))
int err = 0;
struct super_block *sb, *hidden_sb;
+ BUG_ON(!is_valid_dentry(dentry));
+
sb = dentry->d_sb;
unionfs_read_lock(sb);
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
{
int err = 0;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
err = unionfs_unlink_whiteout(dir, 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 */
struct dentry *hidden_dentry = NULL;
int err = -EOPNOTSUPP;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
hidden_dentry = unionfs_lower_dentry(dentry);
struct dentry *hidden_dentry = NULL;
int err = -EOPNOTSUPP;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
hidden_dentry = unionfs_lower_dentry(dentry);
struct dentry *hidden_dentry = NULL;
int err = -EOPNOTSUPP;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
hidden_dentry = unionfs_lower_dentry(dentry);
int err = -EOPNOTSUPP;
char *encoded_list = NULL;
+ BUG_ON(!is_valid_dentry(dentry));
+
unionfs_lock_dentry(dentry);
hidden_dentry = unionfs_lower_dentry(dentry);