+ ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock.patch added to -mm tree

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

 



The patch titled

     ecryptfs: associate vfsmount with dentry rather than superblock

has been added to the -mm tree.  Its filename is

     ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: ecryptfs: associate vfsmount with dentry rather than superblock
From: Michael Halcrow <mhalcrow@xxxxxxxxxx>

Associate vfsmount with dentry rather than superblock. Update
nameidata handling to preserve dentry and vfsmount on calls to lower
filesystem.

Signed-off-by: Michael Halcrow <mhalcrow@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 fs/ecryptfs/crypto.c          |    5 +-
 fs/ecryptfs/dentry.c          |   18 +++++----
 fs/ecryptfs/ecryptfs_kernel.h |   19 ++++++++-
 fs/ecryptfs/file.c            |    5 +-
 fs/ecryptfs/inode.c           |   63 ++++++++++++++++++--------------
 fs/ecryptfs/main.c            |    4 +-
 fs/ecryptfs/super.c           |   19 +++------
 7 files changed, 78 insertions(+), 55 deletions(-)

diff -puN fs/ecryptfs/crypto.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/crypto.c
--- a/fs/ecryptfs/crypto.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/crypto.c
@@ -1141,14 +1141,13 @@ int ecryptfs_cipher_code_to_string(char 
  * Returns zero on success; non-zero otherwise
  */
 int ecryptfs_read_header_region(char *data, struct dentry *dentry,
-				struct nameidata *nd)
+				struct vfsmount *mnt)
 {
-	struct vfsmount *mnt;
 	struct file *file;
 	mm_segment_t oldfs;
 	int rc;
 
-	mnt = mntget(nd->mnt);
+	mnt = mntget(mnt);
 	file = dentry_open(dentry, mnt, O_RDONLY);
 	if (IS_ERR(file)) {
 		ecryptfs_printk(KERN_DEBUG, "Error opening file to "
diff -puN fs/ecryptfs/dentry.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/dentry.c
--- a/fs/ecryptfs/dentry.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/dentry.c
@@ -41,17 +41,21 @@
  */
 static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	struct dentry *dentry_save;
+	struct vfsmount *vfsmount_save;
 	int rc = 1;
-	struct dentry *lower_dentry;
-	struct nameidata lower_nd;
 
-	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
 		goto out;
-	memcpy(&lower_nd, nd, sizeof(struct nameidata));
-	lower_nd.dentry = lower_dentry;
-	lower_nd.mnt = ecryptfs_superblock_to_private(dentry->d_sb)->lower_mnt;
-	rc = lower_dentry->d_op->d_revalidate(lower_dentry, &lower_nd);
+	dentry_save = nd->dentry;
+	vfsmount_save = nd->mnt;
+	nd->dentry = lower_dentry;
+	nd->mnt = lower_mnt;
+	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
+	nd->dentry = dentry_save;
+	nd->mnt = vfsmount_save;
 out:
 	return rc;
 }
diff -puN fs/ecryptfs/ecryptfs_kernel.h~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/ecryptfs_kernel.h
--- a/fs/ecryptfs/ecryptfs_kernel.h~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/ecryptfs_kernel.h
@@ -216,9 +216,11 @@ struct ecryptfs_inode_info {
 	struct ecryptfs_crypt_stat crypt_stat;
 };
 
-/* dentry private data. */
+/* dentry private data. Each dentry must keep track of a lower
+ * vfsmount too. */
 struct ecryptfs_dentry_info {
 	struct dentry *wdi_dentry;
+	struct vfsmount *lower_mnt;
 	struct ecryptfs_crypt_stat *crypt_stat;
 };
 
@@ -243,7 +245,6 @@ struct ecryptfs_mount_crypt_stat {
 /* superblock private data. */
 struct ecryptfs_sb_info {
 	struct super_block *wsi_sb;
-	struct vfsmount *lower_mnt;
 	struct ecryptfs_mount_crypt_stat mount_crypt_stat;
 };
 
@@ -362,6 +363,18 @@ ecryptfs_set_dentry_lower(struct dentry 
 		lower_dentry;
 }
 
+static inline struct vfsmount *
+ecryptfs_dentry_to_lower_mnt(struct dentry *dentry)
+{
+	return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt;
+}
+
+static inline void
+ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt)
+{
+	((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt =
+		lower_mnt;
+}
 
 #define ecryptfs_printk(type, fmt, arg...) \
         __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg);
@@ -445,7 +458,7 @@ int ecryptfs_read_headers(struct dentry 
 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
 int contains_ecryptfs_marker(char *data);
 int ecryptfs_read_header_region(char *data, struct dentry *dentry,
-				struct nameidata *nd);
+				struct vfsmount *mnt);
 u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
 int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code);
 void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat);
diff -puN fs/ecryptfs/file.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/file.c
--- a/fs/ecryptfs/file.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/file.c
@@ -117,8 +117,7 @@ static ssize_t ecryptfs_read_update_atim
 		rc = wait_on_sync_kiocb(iocb);
 	if (rc >= 0) {
 		lower_dentry = ecryptfs_dentry_to_lower(file->f_dentry);
-		lower_vfsmount = ecryptfs_superblock_to_private(
-			file->f_dentry->d_inode->i_sb)->lower_mnt;
+		lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_dentry);
 		touch_atime(lower_vfsmount, lower_dentry);
 	}
 	return rc;
@@ -246,7 +245,7 @@ static int ecryptfs_open(struct inode *i
 		lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
 	if (file->f_flags & O_APPEND)
 		lower_flags &= ~O_APPEND;
-	lower_mnt = ecryptfs_superblock_to_private(inode->i_sb)->lower_mnt;
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
 	mntget(lower_mnt);
 	/* Corresponding fput() in ecryptfs_release() */
 	lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
diff -puN fs/ecryptfs/inode.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/inode.c
--- a/fs/ecryptfs/inode.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/inode.c
@@ -101,7 +101,7 @@ void ecryptfs_copy_attr_all(struct inode
  * @lower_dentry: New file's dentry in the lower fs
  * @ecryptfs_dentry: New file's dentry in ecryptfs
  * @mode: The mode of the new file
- * @nd: nameidata of ecryptfs' parent's dentry & vfsmnt
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
  *
  * Creates the file in the lower file system.
  *
@@ -109,18 +109,22 @@ void ecryptfs_copy_attr_all(struct inode
  */
 static int
 ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
-				struct dentry *lower_dentry,
-				struct dentry *ecryptfs_dentry, int mode,
+				struct dentry *dentry, int mode,
 				struct nameidata *nd)
 {
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	struct dentry *dentry_save;
+	struct vfsmount *vfsmount_save;
 	int rc;
-	struct nameidata lower_nd;
 
-	memcpy(&lower_nd, nd, sizeof(struct nameidata));
-	lower_nd.dentry = lower_dentry;
-	lower_nd.mnt = ecryptfs_superblock_to_private(
-		ecryptfs_dentry->d_sb)->lower_mnt;
-	rc = vfs_create(lower_dir_inode, lower_dentry, mode, &lower_nd);
+	dentry_save = nd->dentry;
+	vfsmount_save = nd->mnt;
+	nd->dentry = lower_dentry;
+	nd->mnt = lower_mnt;
+	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
+	nd->dentry = dentry_save;
+	nd->mnt = vfsmount_save;
 	return rc;
 }
 
@@ -129,7 +133,7 @@ ecryptfs_create_underlying_file(struct i
  * @directory_inode: inode of the new file's dentry's parent in ecryptfs
  * @ecryptfs_dentry: New file's dentry in ecryptfs
  * @mode: The mode of the new file
- * @nd: nameidata of ecryptfs' parent's dentry & vfsmnt
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
  *
  * Creates the underlying file and the eCryptfs inode which will link to
  * it. It will also update the eCryptfs directory inode to mimic the
@@ -155,8 +159,7 @@ ecryptfs_do_create(struct inode *directo
 		goto out;
 	}
 	rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
-					     lower_dentry, ecryptfs_dentry,
-					     mode, nd);
+					     ecryptfs_dentry, mode, nd);
 	if (unlikely(rc)) {
 		ecryptfs_printk(KERN_ERR,
 				"Failure to create underlying file\n");
@@ -248,7 +251,7 @@ static int ecryptfs_initialize_file(stru
 #if BITS_PER_LONG != 32
 	lower_flags |= O_LARGEFILE;
 #endif
-	lower_mnt = ecryptfs_superblock_to_private(inode->i_sb)->lower_mnt;
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
 	mntget(lower_mnt);
 	/* Corresponding fput() at end of this function */
 	lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
@@ -332,6 +335,7 @@ static struct dentry *ecryptfs_lookup(st
 	int rc = 0;
 	struct dentry *lower_dir_dentry;
 	struct dentry *lower_dentry;
+	struct vfsmount *lower_mnt;
 	struct dentry *tlower_dentry = NULL;
 	char *encoded_name;
 	unsigned int encoded_namelen;
@@ -358,6 +362,7 @@ static struct dentry *ecryptfs_lookup(st
 	lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
 				      encoded_namelen - 1);
 	kfree(encoded_name);
+	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
 	if (IS_ERR(lower_dentry)) {
 		ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
 		rc = PTR_ERR(lower_dentry);
@@ -379,6 +384,7 @@ static struct dentry *ecryptfs_lookup(st
 		goto out_dput;
 	}
 	ecryptfs_set_dentry_lower(dentry, lower_dentry);
+	ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);
 	if (!lower_dentry->d_inode) {
 		/* We want to add because we couldn't find in lower */
 		d_add(dentry, NULL);
@@ -419,7 +425,7 @@ static struct dentry *ecryptfs_lookup(st
 		goto out_dput;
 	}
 	memset(page_virt, 0, PAGE_CACHE_SIZE);
-	rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd);
+	rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
 	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
 	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
 		ecryptfs_set_default_sizes(crypt_stat);
@@ -801,6 +807,7 @@ int ecryptfs_truncate(struct dentry *den
 	int rc = 0;
 	struct inode *inode = dentry->d_inode;
 	struct dentry *lower_dentry;
+	struct vfsmount *lower_mnt;
 	struct file fake_ecryptfs_file, *lower_file = NULL;
 	struct ecryptfs_crypt_stat *crypt_stat;
 	loff_t i_size = i_size_read(inode);
@@ -826,10 +833,9 @@ int ecryptfs_truncate(struct dentry *den
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	/* This dget & mntget is released through fput at out_fput: */
 	dget(lower_dentry);
-	mntget(ecryptfs_superblock_to_private(inode->i_sb)->lower_mnt);
-	lower_file = dentry_open(
-		lower_dentry,
-		ecryptfs_superblock_to_private(inode->i_sb)->lower_mnt, O_RDWR);
+	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+	mntget(lower_mnt);
+	lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
 	if (unlikely(IS_ERR(lower_file))) {
 		rc = PTR_ERR(lower_file);
 		goto out_free;
@@ -885,15 +891,20 @@ out:
 static int
 ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-	struct inode *lower_inode;
-	int rc = 0;
+	int rc;
 
-	lower_inode = ecryptfs_inode_to_lower(inode);
-	if (nd)
-		ecryptfs_printk(KERN_DEBUG, "nd->dentry = [%p]\n",
-				nd->dentry);
-	rc = permission(lower_inode, mask, nd);
-	return rc;
+        if (nd) {
+		struct vfsmount *vfsmnt_save = nd->mnt;
+		struct dentry *dentry_save = nd->dentry;
+
+		nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
+		nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
+		rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
+		nd->mnt = vfsmnt_save;
+		nd->dentry = dentry_save;
+        } else
+		rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
+        return rc;
 }
 
 /**
diff -puN fs/ecryptfs/main.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/main.c
--- a/fs/ecryptfs/main.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/main.c
@@ -452,6 +452,7 @@ static int ecryptfs_read_super(struct su
 	int rc;
 	struct nameidata nd;
 	struct dentry *lower_root;
+	struct vfsmount *lower_mnt;
 
 	memset(&nd, 0, sizeof(struct nameidata));
 	rc = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
@@ -460,16 +461,17 @@ static int ecryptfs_read_super(struct su
 		goto out_free;
 	}
 	lower_root = nd.dentry;
-	ecryptfs_superblock_to_private(sb)->lower_mnt = nd.mnt;
 	if (!lower_root->d_inode) {
 		ecryptfs_printk(KERN_WARNING,
 				"No directory to interpose on\n");
 		rc = -ENOENT;
 		goto out_free;
 	}
+	lower_mnt = nd.mnt;
 	ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
 	sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
 	ecryptfs_set_dentry_lower(sb->s_root, lower_root);
+	ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
 	if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0)))
 		goto out_free;
 	rc = 0;
diff -puN fs/ecryptfs/super.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock fs/ecryptfs/super.c
--- a/fs/ecryptfs/super.c~ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock
+++ a/fs/ecryptfs/super.c
@@ -108,7 +108,6 @@ static void ecryptfs_put_super(struct su
 {
 	struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
 
-	mntput(sb_info->lower_mnt);
 	ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat);
 	kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
 	ecryptfs_set_superblock_private(sb, NULL);
@@ -152,10 +151,10 @@ static void ecryptfs_clear_inode(struct 
  */
 static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags)
 {
-	struct vfsmount *lower_mnt;
+	struct vfsmount *lower_mnt =
+		ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root);
 	struct super_block *lower_sb;
 
-	lower_mnt = ecryptfs_superblock_to_private(vfsmnt->mnt_sb)->lower_mnt;
 	lower_sb = lower_mnt->mnt_sb;
 	if (lower_sb->s_op->umount_begin)
 		lower_sb->s_op->umount_begin(lower_mnt, flags);
@@ -170,22 +169,18 @@ static void ecryptfs_umount_begin(struct
 static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
 {
 	struct super_block *sb = mnt->mnt_sb;
-	struct dentry *lower_root_dentry;
-	struct ecryptfs_sb_info *sb_info;
-	struct vfsmount *lower_mount;
-	int rc = 0;
-	char *tmp_page = NULL;
+	struct dentry *lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root);
+	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(sb->s_root);
+	char *tmp_page;
 	char *path;
+	int rc = 0;
 
 	tmp_page = (char *)__get_free_page(GFP_KERNEL);
 	if (!tmp_page) {
 		rc = -ENOMEM;
 		goto out;
 	}
-	lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root);
-	sb_info = ecryptfs_superblock_to_private(sb);
-	lower_mount = sb_info->lower_mnt;
-	path = d_path(lower_root_dentry, lower_mount, tmp_page, PAGE_SIZE);
+	path = d_path(lower_root_dentry, lower_mnt, tmp_page, PAGE_SIZE);
 	if (IS_ERR(path)) {
 		rc = PTR_ERR(path);
 		goto out;
_

Patches currently in -mm which might be from mhalcrow@xxxxxxxxxx are

lsm-remove-bsd-secure-level-security-module.patch
ecryptfs-fs-makefile-and-fs-kconfig.patch
ecryptfs-documentation.patch
ecryptfs-makefile.patch
ecryptfs-main-module-functions.patch
ecryptfs-header-declarations.patch
ecryptfs-superblock-operations.patch
ecryptfs-dentry-operations.patch
ecryptfs-file-operations.patch
ecryptfs-inode-operations.patch
ecryptfs-mmap-operations.patch
ecryptfs-mmap-operations-fix.patch
ecryptfs-keystore.patch
ecryptfs-crypto-functions.patch
fs-ecryptfs-possible-cleanups.patch
ecryptfs-debug-functions.patch
ecryptfs-alpha-build-fix.patch
ecryptfs-convert-assert-to-bug_on.patch
ecryptfs-remove-pointless-bug_ons.patch
ecryptfs-remove-unnecessary-null-checks.patch
ecryptfs-rewrite-ecryptfs_fsync.patch
ecryptfs-overhaul-file-locking.patch
ecryptfs-dont-muck-with-the-existing-nameidata-structures.patch
ecryptfs-asm-scatterlisth-linux-scatterlisth.patch
ecryptfs-support-for-larger-maximum-key-size.patch
ecryptfs-add-codes-for-additional-ciphers.patch
ecryptfs-unencrypted-key-size-based-on-encrypted-key-size.patch
ecryptfs-packet-and-key-management-update-for-variable-key-size.patch
ecryptfs-add-ecryptfs_-prefix-to-mount-options-key-size-parameter.patch
ecryptfs-set-the-key-size-from-the-default-for-the-mount.patch
ecryptfs-check-for-weak-keys.patch
ecryptfs-add-define-values-for-cipher-codes-from-rfc2440-openpgp.patch
ecryptfs-convert-bits-to-bytes.patch
ecryptfs-more-elegant-aes-key-size-manipulation.patch
ecryptfs-more-intelligent-use-of-tfm-objects.patch
ecryptfs-remove-debugging-cruft.patch
ecryptfs-get_sb_dev-fix.patch
ecryptfs-validate-minimum-header-extent-size.patch
ecryptfs-validate-body-size.patch
ecryptfs-validate-packet-length-prior-to-parsing-add-comments.patch
ecryptfs-use-the-passed-in-max-value-as-the-upper-bound.patch
ecryptfs-change-the-maximum-size-check-when-writing-header.patch
ecryptfs-print-the-actual-option-that-is-problematic.patch
ecryptfs-add-a-maintainers-entry.patch
ecryptfs-partial-signed-integer-to-size_t-conversion-updated-ii.patch
ecryptfs-fix-printk-format-warnings.patch
ecryptfs-associate-vfsmount-with-dentry-rather-than-superblock.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux