All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Halcrow <mhalcrow@us.ibm.com>
To: Andrew Morton <akpm@osdl.org>
Cc: Christoph Hellwig <hch@lst.de>, linux-fsdevel@vger.kernel.org
Subject: Re: ecryptfs
Date: Mon, 7 Aug 2006 11:31:15 -0500	[thread overview]
Message-ID: <20060807163115.GA4028@us.ibm.com> (raw)
In-Reply-To: <20060807161939.GC2950@us.ibm.com>

***DO NOT ACCEPT THIS PATCH***

On Mon, Aug 07, 2006 at 11:19:39AM -0500, Michael Halcrow wrote:
> I have a couple more bogus patches I would like feedback on; they're
> bogus at this stage because I am struggling to get them to work
> right. I'll send them as a follow-on to this message.

***DO NOT ACCEPT THIS PATCH***

This code is for commentary only at this stage. Note that it applies
on top of a patch that associates the vfsmount with the dentry rather
than the superblock.

Here is where I am thinking about going with crossing lower mount
points. This patch makes sure that there is a 1-to-1 mapping in inode
numbers between the stacked inodes and the lower inodes. It maintains
the association by modifying the struct inode to include a back
pointer from the lower inode to the stacked inode. Note that Unionfs
has a persistent inode approach that is much more heavy-weight than
this approach, but it does not need to modify anything in the VFS.

I would like the CONFIG_STACK_FS to govern VFS modifications that make
stackable filesystems more functional. My approach is to allow the
kernel to be built without any such modifications, but certain
features will be disabled/degraded in the stacked filesystem.

Unfortunately, with this patch, things blow up on umount; I'll have to
investigate what's going on.

diff --git a/fs/Kconfig b/fs/Kconfig
index afacf48..30c78b9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -443,6 +443,14 @@ config QUOTA
 	  with the quota tools. Probably the quota support is only useful for
 	  multi user systems. If unsure, say N.
 
+config STACK_FS
+	bool "Stacked filesystem support"
+	default y
+	help
+	  Select Y to enable all features in stacked filesystems (such
+	  as eCryptfs and Unionfs).  Slightly increases the size of
+	  inodes in memory.  If unsure, say Y.
+
 config QFMT_V1
 	tristate "Old quota format support"
 	depends on QUOTA
@@ -984,6 +992,9 @@ config ECRYPT_FS
 	  Encrypted filesystem that operates on the VFS layer.  See
 	  Documentation/ecryptfs.txt to learn more about eCryptfs.
 
+	  It is strongly recommended that you also enable ``Stacked
+	  filesystem support'' (CONFIG_STACK_FS) if you build eCryptfs.
+
 	  To compile this file system support as a module, choose M here: the
 	  module will be called ecryptfs.
 
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 349ce2a..3e8f377 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -376,6 +376,51 @@ ecryptfs_set_dentry_lower_mnt(struct den
 		lower_mnt;
 }
 
+#ifdef CONFIG_STACK_FS
+static inline int
+ecryptfs_get_inode(struct inode **inode, struct inode *lower_inode,
+		   struct super_block *sb)
+{
+	*inode = lower_inode->i_stacked_inode;
+	if (!*inode) {
+		*inode = iget(sb, iunique(sb, 0));
+		if (!*inode)
+			return -EACCES;
+		lower_inode->i_stacked_inode = *inode;
+	}
+	return 0;
+}
+#else
+static inline int
+ecryptfs_get_inode(struct inode **inode, struct inode *lower_inode,
+		   struct super_block *sb)
+{
+	/* Without CONFIG_STACK_FS enabled, we have no way to safely
+	 * cross mount points in the lower filesystem. */
+	if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) {
+		printk(KERN_ERR "Cannot cross mount point in lower filesystem; "
+		       "recompile your kernel with CONFIG_STACK_FS to enable "
+		       "this feature.\n");
+		return -EXDEV;
+	}
+	*inode = iget(sb, lower_inode->i_ino);
+	if (!*inode)
+		return -EACCES;
+	return 0;
+}
+#endif /* CONFIG_STACK_FS */
+
+#ifdef CONFIG_STACK_FS
+static inline void ecryptfs_clear_inode_stacking(struct inode *inode)
+{
+	struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
+
+	lower_inode->i_stacked_inode = NULL;
+}
+#else
+static inline void ecryptfs_clear_inode_stacking(struct inode *inode) { }
+#endif /* CONFIG_STACK_FS */
+
 #define ecryptfs_printk(type, fmt, arg...) \
         __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg);
 void __ecryptfs_printk(const char *fmt, ...);
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index d2e1cb0..119c0a5 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -77,22 +77,16 @@ int ecryptfs_interpose(struct dentry *lo
 		       struct super_block *sb, int flag)
 {
 	struct inode *lower_inode;
-	int rc = 0;
 	struct inode *inode;
+	int rc = 0;
 
 	lower_inode = lower_dentry->d_inode;
-	if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) {
-		rc = -EXDEV;
-		goto out;
-	}
-	inode = iget(sb, lower_inode->i_ino);
-	if (!inode) {
-		rc = -EACCES;
+	rc = ecryptfs_get_inode(&inode, lower_inode, sb);
+	if (rc) {
+		printk(KERN_ERR "Error getting inode\n");
 		goto out;
 	}
-	/* This check is required here because if we failed to allocated the
-	 * required space for an inode_info_cache struct, then the only way
-	 * we know we failed, is by the pointer being NULL */
+	/* Did we succeed in allocating ecryptfs_inode_info? */
 	if (!ecryptfs_inode_to_private(inode)) {
 		ecryptfs_printk(KERN_ERR, "Out of memory. Failure to "
 				"allocate memory in ecryptfs_read_inode.\n");
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 120f060..d96aa65 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -138,6 +138,7 @@ static int ecryptfs_statfs(struct dentry
  */
 static void ecryptfs_clear_inode(struct inode *inode)
 {
+	ecryptfs_clear_inode_stacking(inode);
 	iput(ecryptfs_inode_to_lower(inode));
 }
 
diff --git a/fs/inode.c b/fs/inode.c
index 89ce5ba..3d3efc2 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -163,7 +163,10 @@ #endif
 				bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 			mapping->backing_dev_info = bdi;
 		}
-		inode->i_private = 0;
+		inode->i_private = NULL;
+#ifdef CONFIG_STACK_FS
+		inode->i_stacked_inode = NULL;
+#endif
 		inode->i_mapping = mapping;
 	}
 	return inode;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6cd7004..306a028 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -578,6 +578,9 @@ #endif
 	atomic_t		i_writecount;
 	void			*i_security;
 	void			*i_private; /* fs or device private pointer */
+#ifdef CONFIG_STACK_FS
+	struct inode		*i_stacked_inode; /* stackable fs support */
+#endif
 #ifdef __NEED_I_SIZE_ORDERED
 	seqcount_t		i_size_seqcount;
 #endif

       reply	other threads:[~2006-08-07 16:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20060805140237.2226a9dc.akpm@osdl.org>
     [not found] ` <20060807161939.GC2950@us.ibm.com>
2006-08-07 16:31   ` Michael Halcrow [this message]
2006-08-07 17:21     ` ecryptfs Josef Sipek
2006-08-07 22:47       ` ecryptfs Michael Halcrow
2006-08-08  0:13         ` ecryptfs Shaya Potter
2006-08-08 14:31           ` ecryptfs Michael Halcrow
2006-08-08 15:10             ` ecryptfs Shaya Potter

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=20060807163115.GA4028@us.ibm.com \
    --to=mhalcrow@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@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.