linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Erez Zadok <ezk@cs.sunysb.edu>
To: hch@infradead.org, viro@ftp.linux.org.uk, akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	Erez Zadok <ezk@cs.sunysb.edu>
Subject: [PATCH 30/42] Unionfs: debugging infrastructure
Date: Sun,  9 Dec 2007 21:42:03 -0500	[thread overview]
Message-ID: <11972545541475-git-send-email-ezk@cs.sunysb.edu> (raw)
In-Reply-To: <11972545353262-git-send-email-ezk@cs.sunysb.edu>

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
---
 fs/unionfs/debug.c |  532 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 532 insertions(+), 0 deletions(-)
 create mode 100644 fs/unionfs/debug.c

diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
new file mode 100644
index 0000000..c2b8b58
--- /dev/null
+++ b/fs/unionfs/debug.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
+ * Copyright (c) 2003-2007 Stony Brook University
+ * Copyright (c) 2003-2007 The Research Foundation of SUNY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "union.h"
+
+/*
+ * Helper debugging functions for maintainers (and for users to report back
+ * useful information back to maintainers)
+ */
+
+/* it's always useful to know what part of the code called us */
+#define PRINT_CALLER(fname, fxn, line)					\
+	do {								\
+		if (!printed_caller) {					\
+			pr_debug("PC:%s:%s:%d\n", (fname), (fxn), (line)); \
+			printed_caller = 1;				\
+		}							\
+	} while (0)
+
+/*
+ * __unionfs_check_{inode,dentry,file} perform exhaustive sanity checking on
+ * the fan-out of various Unionfs objects.  We check that no lower objects
+ * exist  outside the start/end branch range; that all objects within are
+ * non-NULL (with some allowed exceptions); that for every lower file
+ * there's a lower dentry+inode; that the start/end ranges match for all
+ * corresponding lower objects; that open files/symlinks have only one lower
+ * objects, but directories can have several; and more.
+ */
+void __unionfs_check_inode(const struct inode *inode,
+			   const char *fname, const char *fxn, int line)
+{
+	int bindex;
+	int istart, iend;
+	struct inode *lower_inode;
+	struct super_block *sb;
+	int printed_caller = 0;
+	void *poison_ptr;
+
+	/* for inodes now */
+	BUG_ON(!inode);
+	sb = inode->i_sb;
+	istart = ibstart(inode);
+	iend = ibend(inode);
+	/* don't check inode if no lower branches */
+	if (istart < 0 && iend < 0)
+		return;
+	if (unlikely(istart > iend)) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" Ci0: inode=%p istart/end=%d:%d\n",
+			 inode, istart, iend);
+	}
+	if (unlikely((istart == -1 && iend != -1) ||
+		     (istart != -1 && iend == -1))) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" Ci1: inode=%p istart/end=%d:%d\n",
+			 inode, istart, iend);
+	}
+	if (!S_ISDIR(inode->i_mode)) {
+		if (unlikely(iend != istart)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" Ci2: inode=%p istart=%d iend=%d\n",
+				 inode, istart, iend);
+		}
+	}
+
+	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
+		if (unlikely(!UNIONFS_I(inode))) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" Ci3: no inode_info %p\n", inode);
+			return;
+		}
+		if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" Ci4: no lower_inodes %p\n", inode);
+			return;
+		}
+		lower_inode = unionfs_lower_inode_idx(inode, bindex);
+		if (lower_inode) {
+			memset(&poison_ptr, POISON_INUSE, sizeof(void *));
+			if (unlikely(bindex < istart || bindex > iend)) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" Ci5: inode/linode=%p:%p bindex=%d "
+					 "istart/end=%d:%d\n", inode,
+					 lower_inode, bindex, istart, iend);
+			} else if (unlikely(lower_inode == poison_ptr)) {
+				/* freed inode! */
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" Ci6: inode/linode=%p:%p bindex=%d "
+					 "istart/end=%d:%d\n", inode,
+					 lower_inode, bindex, istart, iend);
+			}
+			continue;
+		}
+		/* if we get here, then lower_inode == NULL */
+		if (bindex < istart || bindex > iend)
+			continue;
+		/*
+		 * directories can have NULL lower inodes in b/t start/end,
+		 * but NOT if at the start/end range.
+		 */
+		if (unlikely(S_ISDIR(inode->i_mode) &&
+			     bindex > istart && bindex < iend))
+			continue;
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" Ci7: inode/linode=%p:%p "
+			 "bindex=%d istart/end=%d:%d\n",
+			 inode, lower_inode, bindex, istart, iend);
+	}
+}
+
+void __unionfs_check_dentry(const struct dentry *dentry,
+			    const char *fname, const char *fxn, int line)
+{
+	int bindex;
+	int dstart, dend, istart, iend;
+	struct dentry *lower_dentry;
+	struct inode *inode, *lower_inode;
+	struct super_block *sb;
+	struct vfsmount *lower_mnt;
+	int printed_caller = 0;
+	void *poison_ptr;
+
+	BUG_ON(!dentry);
+	sb = dentry->d_sb;
+	inode = dentry->d_inode;
+	dstart = dbstart(dentry);
+	dend = dbend(dentry);
+	/* don't check dentry/mnt if no lower branches */
+	if (dstart < 0 && dend < 0)
+		goto check_inode;
+	BUG_ON(dstart > dend);
+
+	if (unlikely((dstart == -1 && dend != -1) ||
+		     (dstart != -1 && dend == -1))) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CD0: dentry=%p dstart/end=%d:%d\n",
+			 dentry, dstart, dend);
+	}
+	/*
+	 * check for NULL dentries inside the start/end range, or
+	 * non-NULL dentries outside the start/end range.
+	 */
+	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
+		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
+		if (lower_dentry) {
+			if (unlikely(bindex < dstart || bindex > dend)) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CD1: dentry/lower=%p:%p(%p) "
+					 "bindex=%d dstart/end=%d:%d\n",
+					 dentry, lower_dentry,
+					 (lower_dentry ? lower_dentry->d_inode :
+					  (void *) -1L),
+					 bindex, dstart, dend);
+			}
+		} else {	/* lower_dentry == NULL */
+			if (bindex < dstart || bindex > dend)
+				continue;
+			/*
+			 * Directories can have NULL lower inodes in b/t
+			 * start/end, but NOT if at the start/end range.
+			 * Ignore this rule, however, if this is a NULL
+			 * dentry or a deleted dentry.
+			 */
+			if (unlikely(!d_deleted((struct dentry *) dentry) &&
+				     inode &&
+				     !(inode && S_ISDIR(inode->i_mode) &&
+				       bindex > dstart && bindex < dend))) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CD2: dentry/lower=%p:%p(%p) "
+					 "bindex=%d dstart/end=%d:%d\n",
+					 dentry, lower_dentry,
+					 (lower_dentry ?
+					  lower_dentry->d_inode :
+					  (void *) -1L),
+					 bindex, dstart, dend);
+			}
+		}
+	}
+
+	/* check for vfsmounts same as for dentries */
+	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
+		lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
+		if (lower_mnt) {
+			if (unlikely(bindex < dstart || bindex > dend)) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CM0: dentry/lmnt=%p:%p bindex=%d "
+					 "dstart/end=%d:%d\n", dentry,
+					 lower_mnt, bindex, dstart, dend);
+			}
+		} else {	/* lower_mnt == NULL */
+			if (bindex < dstart || bindex > dend)
+				continue;
+			/*
+			 * Directories can have NULL lower inodes in b/t
+			 * start/end, but NOT if at the start/end range.
+			 * Ignore this rule, however, if this is a NULL
+			 * dentry.
+			 */
+			if (unlikely(inode &&
+				     !(inode && S_ISDIR(inode->i_mode) &&
+				       bindex > dstart && bindex < dend))) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CM1: dentry/lmnt=%p:%p "
+					 "bindex=%d dstart/end=%d:%d\n",
+					 dentry, lower_mnt, bindex,
+					 dstart, dend);
+			}
+		}
+	}
+
+check_inode:
+	/* for inodes now */
+	if (!inode)
+		return;
+	istart = ibstart(inode);
+	iend = ibend(inode);
+	/* don't check inode if no lower branches */
+	if (istart < 0 && iend < 0)
+		return;
+	BUG_ON(istart > iend);
+	if (unlikely((istart == -1 && iend != -1) ||
+		     (istart != -1 && iend == -1))) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CI0: dentry/inode=%p:%p istart/end=%d:%d\n",
+			 dentry, inode, istart, iend);
+	}
+	if (unlikely(istart != dstart)) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CI1: dentry/inode=%p:%p istart=%d dstart=%d\n",
+			 dentry, inode, istart, dstart);
+	}
+	if (unlikely(iend != dend)) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CI2: dentry/inode=%p:%p iend=%d dend=%d\n",
+			 dentry, inode, iend, dend);
+	}
+
+	if (!S_ISDIR(inode->i_mode)) {
+		if (unlikely(dend != dstart)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" CI3: dentry/inode=%p:%p dstart=%d dend=%d\n",
+				 dentry, inode, dstart, dend);
+		}
+		if (unlikely(iend != istart)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" CI4: dentry/inode=%p:%p istart=%d iend=%d\n",
+				 dentry, inode, istart, iend);
+		}
+	}
+
+	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
+		lower_inode = unionfs_lower_inode_idx(inode, bindex);
+		if (lower_inode) {
+			memset(&poison_ptr, POISON_INUSE, sizeof(void *));
+			if (unlikely(bindex < istart || bindex > iend)) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CI5: dentry/linode=%p:%p bindex=%d "
+					 "istart/end=%d:%d\n", dentry,
+					 lower_inode, bindex, istart, iend);
+			} else if (unlikely(lower_inode == poison_ptr)) {
+				/* freed inode! */
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CI6: dentry/linode=%p:%p bindex=%d "
+					 "istart/end=%d:%d\n", dentry,
+					 lower_inode, bindex, istart, iend);
+			}
+			continue;
+		}
+		/* if we get here, then lower_inode == NULL */
+		if (bindex < istart || bindex > iend)
+			continue;
+		/*
+		 * directories can have NULL lower inodes in b/t start/end,
+		 * but NOT if at the start/end range.
+		 */
+		if (unlikely(S_ISDIR(inode->i_mode) &&
+			     bindex > istart && bindex < iend))
+			continue;
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CI7: dentry/linode=%p:%p "
+			 "bindex=%d istart/end=%d:%d\n",
+			 dentry, lower_inode, bindex, istart, iend);
+	}
+
+	/*
+	 * If it's a directory, then intermediate objects b/t start/end can
+	 * be NULL.  But, check that all three are NULL: lower dentry, mnt,
+	 * and inode.
+	 */
+	if (dstart >= 0 && dend >= 0 && S_ISDIR(inode->i_mode))
+		for (bindex = dstart+1; bindex < dend; bindex++) {
+			lower_inode = unionfs_lower_inode_idx(inode, bindex);
+			lower_dentry = unionfs_lower_dentry_idx(dentry,
+								bindex);
+			lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
+			if (unlikely(!((lower_inode && lower_dentry &&
+					lower_mnt) ||
+				       (!lower_inode &&
+					!lower_dentry && !lower_mnt)))) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" Cx: lmnt/ldentry/linode=%p:%p:%p "
+					 "bindex=%d dstart/end=%d:%d\n",
+					 lower_mnt, lower_dentry, lower_inode,
+					 bindex, dstart, dend);
+			}
+		}
+	/* check if lower inode is newer than upper one (it shouldn't) */
+	if (unlikely(is_newer_lower(dentry))) {
+		PRINT_CALLER(fname, fxn, line);
+		for (bindex = ibstart(inode); bindex <= ibend(inode);
+		     bindex++) {
+			lower_inode = unionfs_lower_inode_idx(inode, bindex);
+			if (unlikely(!lower_inode))
+				continue;
+			pr_debug(" CI8: bindex=%d mtime/lmtime=%lu.%lu/%lu.%lu "
+				 "ctime/lctime=%lu.%lu/%lu.%lu\n",
+				 bindex,
+				 inode->i_mtime.tv_sec,
+				 inode->i_mtime.tv_nsec,
+				 lower_inode->i_mtime.tv_sec,
+				 lower_inode->i_mtime.tv_nsec,
+				 inode->i_ctime.tv_sec,
+				 inode->i_ctime.tv_nsec,
+				 lower_inode->i_ctime.tv_sec,
+				 lower_inode->i_ctime.tv_nsec);
+		}
+	}
+}
+
+void __unionfs_check_file(const struct file *file,
+			  const char *fname, const char *fxn, int line)
+{
+	int bindex;
+	int dstart, dend, fstart, fend;
+	struct dentry *dentry;
+	struct file *lower_file;
+	struct inode *inode;
+	struct super_block *sb;
+	int printed_caller = 0;
+
+	BUG_ON(!file);
+	dentry = file->f_path.dentry;
+	sb = dentry->d_sb;
+	dstart = dbstart(dentry);
+	dend = dbend(dentry);
+	BUG_ON(dstart > dend);
+	fstart = fbstart(file);
+	fend = fbend(file);
+	BUG_ON(fstart > fend);
+
+	if (unlikely((fstart == -1 && fend != -1) ||
+		     (fstart != -1 && fend == -1))) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n",
+			 file, dentry, fstart, fend);
+	}
+	if (unlikely(fstart != dstart)) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n",
+			 file, dentry, fstart, dstart);
+	}
+	if (unlikely(fend != dend)) {
+		PRINT_CALLER(fname, fxn, line);
+		pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n",
+			 file, dentry, fend, dend);
+	}
+	inode = dentry->d_inode;
+	if (!S_ISDIR(inode->i_mode)) {
+		if (unlikely(fend != fstart)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" CF3: file/inode=%p:%p fstart=%d fend=%d\n",
+				 file, inode, fstart, fend);
+		}
+		if (unlikely(dend != dstart)) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" CF4: file/dentry=%p:%p dstart=%d dend=%d\n",
+				 file, dentry, dstart, dend);
+		}
+	}
+
+	/*
+	 * check for NULL dentries inside the start/end range, or
+	 * non-NULL dentries outside the start/end range.
+	 */
+	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
+		lower_file = unionfs_lower_file_idx(file, bindex);
+		if (lower_file) {
+			if (unlikely(bindex < fstart || bindex > fend)) {
+				PRINT_CALLER(fname, fxn, line);
+				pr_debug(" CF5: file/lower=%p:%p bindex=%d "
+					 "fstart/end=%d:%d\n", file,
+					 lower_file, bindex, fstart, fend);
+			}
+		} else {	/* lower_file == NULL */
+			if (bindex >= fstart && bindex <= fend) {
+				/*
+				 * directories can have NULL lower inodes in
+				 * b/t start/end, but NOT if at the
+				 * start/end range.
+				 */
+				if (unlikely(!(S_ISDIR(inode->i_mode) &&
+					       bindex > fstart &&
+					       bindex < fend))) {
+					PRINT_CALLER(fname, fxn, line);
+					pr_debug(" CF6: file/lower=%p:%p "
+						 "bindex=%d fstart/end=%d:%d\n",
+						 file, lower_file, bindex,
+						 fstart, fend);
+				}
+			}
+		}
+	}
+
+	__unionfs_check_dentry(dentry, fname, fxn, line);
+}
+
+void __unionfs_check_nd(const struct nameidata *nd,
+			const char *fname, const char *fxn, int line)
+{
+	struct file *file;
+	int printed_caller = 0;
+
+	if (unlikely(!nd))
+		return;
+	if (nd->flags & LOOKUP_OPEN) {
+		file = nd->intent.open.file;
+		if (unlikely(file->f_path.dentry &&
+			     strcmp(file->f_path.dentry->d_sb->s_type->name,
+				    UNIONFS_NAME))) {
+			PRINT_CALLER(fname, fxn, line);
+			pr_debug(" CND1: lower_file of type %s\n",
+				 file->f_path.dentry->d_sb->s_type->name);
+			BUG();
+		}
+	}
+}
+
+/* useful to track vfsmount leaks that could cause EBUSY on unmount */
+void __show_branch_counts(const struct super_block *sb,
+			  const char *file, const char *fxn, int line)
+{
+	int i;
+	struct vfsmount *mnt;
+
+	pr_debug("BC:");
+	for (i = 0; i < sbmax(sb); i++) {
+		if (likely(sb->s_root))
+			mnt = UNIONFS_D(sb->s_root)->lower_paths[i].mnt;
+		else
+			mnt = NULL;
+		pr_debug("%d:", (mnt ? atomic_read(&mnt->mnt_count) : -99));
+	}
+	pr_debug("%s:%s:%d\n", file, fxn, line);
+}
+
+void __show_inode_times(const struct inode *inode,
+			const char *file, const char *fxn, int line)
+{
+	struct inode *lower_inode;
+	int bindex;
+
+	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
+		lower_inode = unionfs_lower_inode_idx(inode, bindex);
+		if (unlikely(!lower_inode))
+			continue;
+		pr_debug("IT(%lu:%d): ", inode->i_ino, bindex);
+		pr_debug("%s:%s:%d ", file, fxn, line);
+		pr_debug("um=%lu/%lu lm=%lu/%lu ",
+			 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+			 lower_inode->i_mtime.tv_sec,
+			 lower_inode->i_mtime.tv_nsec);
+		pr_debug("uc=%lu/%lu lc=%lu/%lu\n",
+			 inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+			 lower_inode->i_ctime.tv_sec,
+			 lower_inode->i_ctime.tv_nsec);
+	}
+}
+
+void __show_dinode_times(const struct dentry *dentry,
+			const char *file, const char *fxn, int line)
+{
+	struct inode *inode = dentry->d_inode;
+	struct inode *lower_inode;
+	int bindex;
+
+	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
+		lower_inode = unionfs_lower_inode_idx(inode, bindex);
+		if (!lower_inode)
+			continue;
+		pr_debug("DT(%s:%lu:%d): ", dentry->d_name.name, inode->i_ino,
+			 bindex);
+		pr_debug("%s:%s:%d ", file, fxn, line);
+		pr_debug("um=%lu/%lu lm=%lu/%lu ",
+			 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+			 lower_inode->i_mtime.tv_sec,
+			 lower_inode->i_mtime.tv_nsec);
+		pr_debug("uc=%lu/%lu lc=%lu/%lu\n",
+			 inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+			 lower_inode->i_ctime.tv_sec,
+			 lower_inode->i_ctime.tv_nsec);
+	}
+}
+
+void __show_inode_counts(const struct inode *inode,
+			const char *file, const char *fxn, int line)
+{
+	struct inode *lower_inode;
+	int bindex;
+
+	if (unlikely(!inode)) {
+		pr_debug("SiC: Null inode\n");
+		return;
+	}
+	for (bindex = sbstart(inode->i_sb); bindex <= sbend(inode->i_sb);
+	     bindex++) {
+		lower_inode = unionfs_lower_inode_idx(inode, bindex);
+		if (unlikely(!lower_inode))
+			continue;
+		pr_debug("SIC(%lu:%d:%d): ", inode->i_ino, bindex,
+			 atomic_read(&(inode)->i_count));
+		pr_debug("lc=%d ", atomic_read(&(lower_inode)->i_count));
+		pr_debug("%s:%s:%d\n", file, fxn, line);
+	}
+}
-- 
1.5.2.2


  parent reply	other threads:[~2007-12-10  2:43 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-10  2:41 [UNIONFS] 00/42 Unionfs and related patches review Erez Zadok
2007-12-10  2:41 ` [PATCH 01/42] Unionfs: filesystems documentation index Erez Zadok
2007-12-10 14:47   ` Jan Engelhardt
2007-12-13 15:06     ` Erez Zadok
2007-12-13 21:25       ` Jan Engelhardt
2007-12-10  2:41 ` [PATCH 02/42] Unionfs: unionfs " Erez Zadok
2007-12-10  2:41 ` [PATCH 03/42] Unionfs: documentation for general concepts Erez Zadok
2007-12-10  2:41 ` [PATCH 04/42] Unionfs: usage documentation for users Erez Zadok
2007-12-10  2:41 ` [PATCH 05/42] Unionfs: documentation for any known issues Erez Zadok
2007-12-10  2:41 ` [PATCH 06/42] Unionfs: documentation about renaming operations Erez Zadok
2007-12-10  2:41 ` [PATCH 07/42] Unionfs maintainers Erez Zadok
2007-12-10  2:41 ` [PATCH 08/42] Makefile: hook to compile unionfs Erez Zadok
2007-12-10  2:41 ` [PATCH 09/42] Unionfs: main Makefile Erez Zadok
2007-12-10  2:41 ` [PATCH 10/42] Unionfs: fanout header definitions Erez Zadok
2007-12-10  2:41 ` [PATCH 11/42] Unionfs: main header file Erez Zadok
2007-12-10  2:41 ` [PATCH 12/42] Unionfs: common file copyup/revalidation operations Erez Zadok
2007-12-10  2:41 ` [PATCH 13/42] Unionfs: basic file operations Erez Zadok
2007-12-10  2:41 ` [PATCH 14/42] Unionfs: lower-level copyup routines Erez Zadok
2007-12-10  2:41 ` [PATCH 15/42] Unionfs: dentry revalidation Erez Zadok
2007-12-10  2:41 ` [PATCH 16/42] Unionfs: lower-level lookup routines Erez Zadok
2007-12-10  2:41 ` [PATCH 17/42] Unionfs: rename method and helpers Erez Zadok
2007-12-10  2:41 ` [PATCH 18/42] Unionfs: directory reading file operations Erez Zadok
2007-12-10  2:41 ` [PATCH 19/42] Unionfs: readdir helper functions Erez Zadok
2007-12-10  2:41 ` [PATCH 20/42] Unionfs: readdir state helpers Erez Zadok
2007-12-10  2:41 ` [PATCH 21/42] Unionfs: inode operations Erez Zadok
2007-12-10  2:41 ` [PATCH 22/42] Unionfs: unlink/rmdir operations Erez Zadok
2007-12-10  2:41 ` [PATCH 23/42] Unionfs: address-space operations Erez Zadok
2007-12-10  2:41 ` [PATCH 24/42] Unionfs: mount-time and stacking-interposition functions Erez Zadok
2007-12-10  2:41 ` [PATCH 25/42] Unionfs: super_block operations Erez Zadok
2007-12-10  2:41 ` [PATCH 26/42] Unionfs: extended attributes operations Erez Zadok
2007-12-10  2:42 ` [PATCH 27/42] Unionfs: async I/O queue headers Erez Zadok
2007-12-10  2:42 ` [PATCH 28/42] Unionfs: async I/O queue operations Erez Zadok
2007-12-10  2:42 ` [PATCH 29/42] Unionfs: miscellaneous helper routines Erez Zadok
2007-12-10  2:42 ` Erez Zadok [this message]
2007-12-10  2:42 ` [PATCH 31/42] VFS: fs_stack header cleanups Erez Zadok
2007-12-10  2:42 ` [PATCH 32/42] Unionfs file system magic number Erez Zadok
2007-12-10  2:42 ` [PATCH 33/42] MM: extern for drop_pagecache_sb Erez Zadok
2007-12-10 14:04   ` Adrian Bunk
2007-12-13 15:05     ` Erez Zadok
2007-12-10  2:42 ` [PATCH 34/42] VFS path get/put ops used by Unionfs Erez Zadok
2007-12-10  2:42 ` [PATCH 35/42] Unionfs: common header file for user-land utilities and kernel Erez Zadok
2007-12-10  2:42 ` [PATCH 36/42] VFS: export drop_pagecache_sb Erez Zadok
2007-12-12  5:38   ` Nick Piggin
2007-12-13 15:24     ` Erez Zadok
2007-12-13 22:47       ` Nick Piggin
2007-12-10  2:42 ` [PATCH 37/42] VFS: export release_open_intent symbol Erez Zadok
2007-12-10  2:42 ` [PATCH 38/42] VFS: simplified fsstack_copy_attr_all Erez Zadok
2007-12-10  2:42 ` [PATCH 39/42] Put Unionfs and eCryptfs under one layered filesystems menu Erez Zadok
2007-12-10  2:42 ` [PATCH 40/42] eCryptfs: use simplified fs_stack API for dentry operations Erez Zadok
2007-12-10  2:42 ` [PATCH 41/42] eCryptfs: use simplified fs_stack API for inode operations Erez Zadok
2007-12-10  2:42 ` [PATCH 42/42] eCryptfs: use simplified fs_stack API for main operations Erez Zadok
2007-12-10  3:20 ` [UNIONFS] 00/42 Unionfs and related patches review hooanon05
2007-12-13 15:29   ` Erez Zadok
2007-12-14 21:15     ` hooanon05

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=11972545541475-git-send-email-ezk@cs.sunysb.edu \
    --to=ezk@cs.sunysb.edu \
    --cc=akpm@linux-foundation.org \
    --cc=hch@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ftp.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).