Re: ecryptfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



***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
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux