Skip to contentSkip to conversation

eCryptfs: convert f_op->write() to vfs_write()

PATCH In review Michael Halcrow 2 participants 7 messages Jan 18, 2007 – Jan 19, 2007 Ecrypt file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/5 eCryptfs: convert f_op->write() to vfs_write()

Quoted 6 lines · Andrew Morton
Quoted 2 lines · On Tue, 9 Jan 2007 16:22:55 -0600 Michael Halcrow <[email protected]> wrote:

+ lower_file->f_op->write(lower_file, (char __user *)page_virt,
+ PAGE_CACHE_SIZE, &lower_file->f_pos);

Quoted 8 lines

hm. sys_write() takes a local copy of f_pos and writes that back into the struct file.It does this so that two concurrent write() callers don't make a mess of f_pos, and of the file contents.

Perhaps ecryptfs should be calling vfs_write()?

That way we'd also get the fsnotify notifications, which ecryptfs presently appears to have subverted.

Convert direct calls to f_op->write() into calls to vfs_write().

---

 fs/ecryptfs/crypto.c |   27 ++++++++++++++++++++++-----
 fs/ecryptfs/inode.c  |    2 +-
 2 files changed, 23 insertions(+), 6 deletions(-)

b91d05b02335e38e18ffb87de6127b80bfe66dd7

fs/ecryptfs/crypto.c +22 -5
index 8fbc38c..fbb62c8 100644
@@ -1346,24 +1346,41 @@ int ecryptfs_write_metadata_to_contents(
 	mm_segment_t oldfs;
 	int current_header_page;
 	int header_pages;
+	ssize_t size;
+	int rc = 0;
 
 	lower_file->f_pos = 0;
 	oldfs = get_fs();
 	set_fs(get_ds());
-	lower_file->f_op->write(lower_file, (char __user *)page_virt,
-				PAGE_CACHE_SIZE, &lower_file->f_pos);
+	size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE,
+			 &lower_file->f_pos);
+	if (size < 0) {
+		rc = (int)size;
+		printk(KERN_ERR "Error attempting to write lower page; "
+		       "rc = [%d]\n", rc);
+		set_fs(oldfs);
+		goto out;
+	}
 	header_pages = ((crypt_stat->header_extent_size
 			 * crypt_stat->num_header_extents_at_front)
 			/ PAGE_CACHE_SIZE);
 	memset(page_virt, 0, PAGE_CACHE_SIZE);
 	current_header_page = 1;
 	while (current_header_page < header_pages) {
-		lower_file->f_op->write(lower_file, (char __user *)page_virt,
-					PAGE_CACHE_SIZE, &lower_file->f_pos);
+		size = vfs_write(lower_file, (char __user *)page_virt,
+				 PAGE_CACHE_SIZE, &lower_file->f_pos);
+		if (size < 0) {
+			rc = (int)size;
+			printk(KERN_ERR "Error attempting to write lower page; "
+			       "rc = [%d]\n", rc);
+			set_fs(oldfs);
+			goto out;
+		}
 		current_header_page++;
 	}
 	set_fs(oldfs);
-	return 0;
+out:
+	return rc;
 }
 
 int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
fs/ecryptfs/inode.c +1 -1
index bbc1b4f..7d33917 100644
@@ -201,7 +201,7 @@ static int ecryptfs_initialize_file(stru
 			lower_dentry->d_name.name);
 	inode = ecryptfs_dentry->d_inode;
 	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
-	lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
+	lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR;
 #if BITS_PER_LONG != 32
 	lower_flags |= O_LARGEFILE;
 #endif
Signature · 1 line
1.3.3
#1 lore raw

PATCH 2/5 eCryptfs: convert kmap() to kmap_atomic()

Quoted 9 lines · Andrew Morton
Quoted 1 line · On Tue, 9 Jan 2007 16:23:37 -0600 Michael Halcrow <[email protected]> wrote:

+ page_virt = (char *)kmap(page);

Do we _have_ to use kmap here? It's slow and theoretically deadlocky. kmap_atomic() is much preferred.

Can the other kmap() calls in ecryptfs be converted?

Replace kmap() with kmap_atomic(). Reduce the number of kmaps and the amount of time that kmaps are held.

---

 fs/ecryptfs/crypto.c          |    8 +--
 fs/ecryptfs/ecryptfs_kernel.h |    4 -
 fs/ecryptfs/mmap.c            |  121 ++++++++++++-----------------------------
 3 files changed, 39 insertions(+), 94 deletions(-)

fd04da707b2164272acc05a56ff4b71786aad011

fs/ecryptfs/crypto.c +4 -4
index fbb62c8..ac4ea8d 100644
@@ -429,10 +429,10 @@ static int ecryptfs_read_in_page(struct 
 			goto out;
 		}
 	} else {
-		rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL,
-						      lower_inode,
-						      lower_page_idx);
-		if (rc) {
+		*lower_page = grab_cache_page(lower_inode->i_mapping,
+					      lower_page_idx);
+		if (!(*lower_page)) {
+			rc = -EINVAL;
 			ecryptfs_printk(
 				KERN_ERR, "Error attempting to grab and map "
 				"lower page with index [0x%.16x]; rc = [%d]\n",
fs/ecryptfs/ecryptfs_kernel.h +0 -4
index 859d31b..0e38d0d 100644
@@ -527,10 +527,6 @@ int ecryptfs_copy_page_to_lower(struct p
 				struct file *lower_file);
 int ecryptfs_do_readpage(struct file *file, struct page *page,
 			 pgoff_t lower_page_index);
-int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
-				     char **lower_virt,
-				     struct inode *lower_inode,
-				     unsigned long lower_page_index);
 int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
 					      struct inode *lower_inode,
 					      struct writeback_control *wbc);
fs/ecryptfs/mmap.c +35 -86

238 lines not on this page · raw message

Signature · 1 line
1.3.3
#2 lore raw

Re: [PATCH 2/5] eCryptfs: convert kmap() to kmap_atomic()

fs/ecryptfs/mmap.c int ecryptfs_do_readpage(struct file *fi · line 238

Quoted 2 lines · Michael Halcrow
fs/ecryptfs/mmap.c +2 -0
+       page_data = (char *)kmap_atomic(page, KM_USER0);
+       lower_page_data = (char *)kmap_atomic(lower_page, KM_USER1);

Drop 'em redundant casts, please.

#3 lore raw

Re: [PATCH 2/5 (try 2)] eCryptfs: convert kmap() to kmap_atomic()

Quoted 5 lines · Pekka Enberg

Review

Quoted 2 lines · Michael Halcrow
(quoted diff) +2 -0
+       page_data = (char *)kmap_atomic(page, KM_USER0);
+       lower_page_data = (char *)kmap_atomic(lower_page, KM_USER1);

Drop 'em redundant casts, please.

Replace kmap() with kmap_atomic(). Reduce the amount of time that mappings are held.

---

 fs/ecryptfs/crypto.c          |    8 +--
 fs/ecryptfs/ecryptfs_kernel.h |    4 -
 fs/ecryptfs/mmap.c            |  121 ++++++++++++-----------------------------
 3 files changed, 39 insertions(+), 94 deletions(-)

ff2dcd23fe6bd000049987b2bf98ada70755f114

fs/ecryptfs/crypto.c +4 -4
index fbb62c8..ac4ea8d 100644
@@ -429,10 +429,10 @@ static int ecryptfs_read_in_page(struct 
 			goto out;
 		}
 	} else {
-		rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL,
-						      lower_inode,
-						      lower_page_idx);
-		if (rc) {
+		*lower_page = grab_cache_page(lower_inode->i_mapping,
+					      lower_page_idx);
+		if (!(*lower_page)) {
+			rc = -EINVAL;
 			ecryptfs_printk(
 				KERN_ERR, "Error attempting to grab and map "
 				"lower page with index [0x%.16x]; rc = [%d]\n",
fs/ecryptfs/ecryptfs_kernel.h +0 -4
index 859d31b..0e38d0d 100644
@@ -527,10 +527,6 @@ int ecryptfs_copy_page_to_lower(struct p
 				struct file *lower_file);
 int ecryptfs_do_readpage(struct file *file, struct page *page,
 			 pgoff_t lower_page_index);
-int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
-				     char **lower_virt,
-				     struct inode *lower_inode,
-				     unsigned long lower_page_index);
 int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
 					      struct inode *lower_inode,
 					      struct writeback_control *wbc);
fs/ecryptfs/mmap.c +35 -86

238 lines not on this page · raw message

Signature · 1 line
1.3.3
#4 lore raw

PATCH 3/5 eCryptfs: open-code flag checking and manipulation

In reply to Michael Halcrow

Open-code flag checking and manipulation.

---

 fs/ecryptfs/crypto.c          |   37 +++++++++++++++----------------------
 fs/ecryptfs/debug.c           |    6 +++---
 fs/ecryptfs/ecryptfs_kernel.h |    3 ---
 fs/ecryptfs/file.c            |   17 +++++++----------
 fs/ecryptfs/inode.c           |   14 ++++++--------
 fs/ecryptfs/keystore.c        |   32 ++++++++++++++------------------
 fs/ecryptfs/mmap.c            |    8 ++++----
 7 files changed, 49 insertions(+), 68 deletions(-)

3cb9652018a1be5ae400bb9bb105bb5685fbc302

fs/ecryptfs/crypto.c +15 -22
index ac4ea8d..e03113c 100644
@@ -207,7 +207,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs
 	mutex_init(&crypt_stat->cs_mutex);
 	mutex_init(&crypt_stat->cs_tfm_mutex);
 	mutex_init(&crypt_stat->cs_hash_tfm_mutex);
-	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
+	crypt_stat->flags |= ECRYPTFS_STRUCT_INITIALIZED;
 }
 
 /**
@@ -305,8 +305,7 @@ static int encrypt_scatterlist(struct ec
 	int rc = 0;
 
 	BUG_ON(!crypt_stat || !crypt_stat->tfm
-	       || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-				       ECRYPTFS_STRUCT_INITIALIZED));
+	       || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
 				crypt_stat->key_size);
@@ -485,7 +484,7 @@ #define ECRYPTFS_PAGE_STATE_WRITTEN   3
 	lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host);
 	inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host);
 	crypt_stat = &inode_info->crypt_stat;
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+	if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
 		rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode,
 						 ctx->param.lower_file);
 		if (rc)
@@ -617,7 +616,7 @@ int ecryptfs_decrypt_page(struct file *f
 	crypt_stat = &(ecryptfs_inode_to_private(
 			       page->mapping->host)->crypt_stat);
 	lower_inode = ecryptfs_inode_to_lower(page->mapping->host);
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+	if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
 		rc = ecryptfs_do_readpage(file, page, page->index);
 		if (rc)
 			ecryptfs_printk(KERN_ERR, "Error attempting to copy "
@@ -884,7 +883,7 @@ int ecryptfs_compute_root_iv(struct ecry
 
 	BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE);
 	BUG_ON(crypt_stat->iv_bytes <= 0);
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID)) {
+	if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
 		rc = -EINVAL;
 		ecryptfs_printk(KERN_WARNING, "Session key not valid; "
 				"cannot generate root IV\n");
@@ -901,8 +900,7 @@ int ecryptfs_compute_root_iv(struct ecry
 out:
 	if (rc) {
 		memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes);
-		ECRYPTFS_SET_FLAG(crypt_stat->flags,
-				  ECRYPTFS_SECURITY_WARNING);
+		crypt_stat->flags |= ECRYPTFS_SECURITY_WARNING;
 	}
 	return rc;
 }
@@ -910,7 +908,7 @@ out:
 static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
 {
 	get_random_bytes(crypt_stat->key, crypt_stat->key_size);
-	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	crypt_stat->flags |= ECRYPTFS_KEY_VALID;
 	ecryptfs_compute_root_iv(crypt_stat);
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
@@ -950,7 +948,7 @@ static void ecryptfs_set_default_crypt_s
 	ecryptfs_set_default_sizes(crypt_stat);
 	strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
 	crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
-	ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	crypt_stat->flags &= ~(ECRYPTFS_KEY_VALID);
 	crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
 	crypt_stat->mount_crypt_stat = mount_crypt_stat;
 }
@@ -990,8 +988,8 @@ int ecryptfs_new_file_context(struct den
 	if (mount_crypt_stat->global_auth_tok) {
 		ecryptfs_printk(KERN_DEBUG, "Initializing context for new "
 				"file using mount_crypt_stat\n");
-		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
-		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+		crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
+		crypt_stat->flags |= ECRYPTFS_KEY_VALID;
 		ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
 							      mount_crypt_stat);
 		memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++],
@@ -1076,11 +1074,9 @@ static int ecryptfs_process_flags(struct
 	for (i = 0; i < ((sizeof(ecryptfs_flag_map)
 			  / sizeof(struct ecryptfs_flag_map_elem))); i++)
 		if (flags & ecryptfs_flag_map[i].file_flag) {
-			ECRYPTFS_SET_FLAG(crypt_stat->flags,
-					  ecryptfs_flag_map[i].local_flag);
+			crypt_stat->flags |= ecryptfs_flag_map[i].local_flag;
 		} else
-			ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
-					    ecryptfs_flag_map[i].local_flag);
+			crypt_stat->flags &= ~(ecryptfs_flag_map[i].local_flag);
 	/* Version is in top 8 bits of the 32-bit flag vector */
 	crypt_stat->file_version = ((flags >> 24) & 0xFF);
 	(*bytes_read) = 4;
@@ -1117,8 +1113,7 @@ write_ecryptfs_flags(char *page_virt, st
 
 	for (i = 0; i < ((sizeof(ecryptfs_flag_map)
 			  / sizeof(struct ecryptfs_flag_map_elem))); i++)
-		if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-					ecryptfs_flag_map[i].local_flag))
+		if (crypt_stat->flags & ecryptfs_flag_map[i].local_flag)
 			flags |= ecryptfs_flag_map[i].file_flag;
 	/* Version is in top 8 bits of the 32-bit flag vector */
 	flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000);
@@ -1416,10 +1411,8 @@ int ecryptfs_write_metadata(struct dentr
 
 	crypt_stat = &ecryptfs_inode_to_private(
 		ecryptfs_dentry->d_inode)->crypt_stat;
-	if (likely(ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-				       ECRYPTFS_ENCRYPTED))) {
-		if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-					 ECRYPTFS_KEY_VALID)) {
+	if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
+		if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
 			ecryptfs_printk(KERN_DEBUG, "Key is "
 					"invalid; bailing out\n");
 			rc = -EINVAL;
fs/ecryptfs/debug.c +3 -3
index 61f8e89..434c7ef 100644
@@ -36,7 +36,7 @@ void ecryptfs_dump_auth_tok(struct ecryp
 
 	ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n",
 			auth_tok);
-	if (ECRYPTFS_CHECK_FLAG(auth_tok->flags, ECRYPTFS_PRIVATE_KEY)) {
+	if (auth_tok->flags & ECRYPTFS_PRIVATE_KEY) {
 		ecryptfs_printk(KERN_DEBUG, " * private key type\n");
 		ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT "
 				"IN ECRYPTFS VERSION 0.1)\n");
@@ -46,8 +46,8 @@ void ecryptfs_dump_auth_tok(struct ecryp
 				ECRYPTFS_SALT_SIZE);
 		salt[ECRYPTFS_SALT_SIZE * 2] = '\0';
 		ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt);
-		if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
-					ECRYPTFS_PERSISTENT_PASSWORD)) {
+		if (auth_tok->token.password.flags &
+		    ECRYPTFS_PERSISTENT_PASSWORD) {
 			ecryptfs_printk(KERN_DEBUG, " * persistent\n");
 		}
 		memcpy(sig, auth_tok->token.password.signature,
fs/ecryptfs/ecryptfs_kernel.h +0 -3
index 0e38d0d..046f0c3 100644
@@ -94,9 +94,6 @@ #define RFC2440_CIPHER_AES_256 0x09
 #define RFC2440_CIPHER_TWOFISH 0x0a
 #define RFC2440_CIPHER_CAST_6 0x0b
 
-#define ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag))
-#define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag))
-#define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag))
 #define RFC2440_CIPHER_RSA 0x01
 
 /**
fs/ecryptfs/file.c +7 -10
index 652ed77..bd969ad 100644
@@ -273,11 +273,11 @@ static int ecryptfs_open(struct inode *i
 	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
 	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
 	mutex_lock(&crypt_stat->cs_mutex);
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) {
+	if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
 		ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
 		/* Policy code enabled in future release */
-		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED);
-		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		crypt_stat->flags |= ECRYPTFS_POLICY_APPLIED;
+		crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
 	}
 	mutex_unlock(&crypt_stat->cs_mutex);
 	lower_flags = file->f_flags;
@@ -297,15 +297,13 @@ static int ecryptfs_open(struct inode *i
 	lower_inode = lower_dentry->d_inode;
 	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
 		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
-		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
 		rc = 0;
 		goto out;
 	}
 	mutex_lock(&crypt_stat->cs_mutex);
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-				 ECRYPTFS_POLICY_APPLIED)
-	    || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
-				    ECRYPTFS_KEY_VALID)) {
+	if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
+	    || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
 		rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file);
 		if (rc) {
 			ecryptfs_printk(KERN_DEBUG,
@@ -320,9 +318,8 @@ static int ecryptfs_open(struct inode *i
 				mutex_unlock(&crypt_stat->cs_mutex);
 				goto out_puts;
 			}
-			ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
-					    ECRYPTFS_ENCRYPTED);
 			rc = 0;
+			crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
 			mutex_unlock(&crypt_stat->cs_mutex);
 			goto out;
 		}
fs/ecryptfs/inode.c +6 -8
index 7d33917..9135718 100644
@@ -161,9 +161,8 @@ static int grow_file(struct dentry *ecry
 	ecryptfs_set_file_lower(&fake_file, lower_file);
 	rc = ecryptfs_fill_zeros(&fake_file, 1);
 	if (rc) {
-		ECRYPTFS_SET_FLAG(
-			ecryptfs_inode_to_private(inode)->crypt_stat.flags,
-			ECRYPTFS_SECURITY_WARNING);
+		ecryptfs_inode_to_private(inode)->crypt_stat.flags |=
+			ECRYPTFS_SECURITY_WARNING;
 		ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros "
 				"in file; rc = [%d]\n", rc);
 		goto out;
@@ -172,8 +171,7 @@ static int grow_file(struct dentry *ecry
 	ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, inode,
 					      ecryptfs_dentry,
 					      ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
-	ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags,
-			  ECRYPTFS_NEW_FILE);
+	ecryptfs_inode_to_private(inode)->crypt_stat.flags |= ECRYPTFS_NEW_FILE;
 out:
 	return rc;
 }
@@ -216,10 +214,10 @@ #endif
 	lower_inode = lower_dentry->d_inode;
 	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
 		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
-		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
 		goto out_fput;
 	}
-	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+	crypt_stat->flags |= ECRYPTFS_NEW_FILE;
 	ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
 	rc = ecryptfs_new_file_context(ecryptfs_dentry);
 	if (rc) {
@@ -373,7 +371,7 @@ static struct dentry *ecryptfs_lookup(st
 		goto out_dput;
 	}
 	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
-	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
+	if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
 		ecryptfs_set_default_sizes(crypt_stat);
 	rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
 						      nd->mnt);
fs/ecryptfs/keystore.c +14 -18
index cd9c091..81156e9 100644
@@ -606,13 +606,13 @@ parse_tag_1_packet(struct ecryptfs_crypt
 	(*new_auth_tok)->session_key.flags |=
 		ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
 	(*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY;
-	ECRYPTFS_SET_FLAG((*new_auth_tok)->flags, ECRYPTFS_PRIVATE_KEY);
+	(*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY;
 	/* TODO: Why are we setting this flag here? Don't we want the
 	 * userspace to decrypt the session key? */
-	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
-			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
-	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
-			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
+	(*new_auth_tok)->session_key.flags &=
+		~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
+	(*new_auth_tok)->session_key.flags &=
+		~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
 	list_add(&auth_tok_list_item->list, auth_tok_list);
 	goto out;
 out_free:
@@ -792,10 +792,10 @@ parse_tag_3_packet(struct ecryptfs_crypt
 	(*new_auth_tok)->token_type = ECRYPTFS_PASSWORD;
 	/* TODO: Parametarize; we might actually want userspace to
 	 * decrypt the session key. */
-	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
-			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
-	ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
-			    ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
+	(*new_auth_tok)->session_key.flags &=
+			    ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
+	(*new_auth_tok)->session_key.flags &=
+			    ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
 	list_add(&auth_tok_list_item->list, auth_tok_list);
 	goto out;
 out_free:
@@ -940,8 +940,7 @@ static int decrypt_session_key(struct ec
 	int rc = 0;
 
 	password_s_ptr = &auth_tok->token.password;
-	if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
-				ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET))
+	if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)
 		ecryptfs_printk(KERN_DEBUG, "Session key encryption key "
 				"set; skipping key generation\n");
 	ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])"
@@ -1023,7 +1022,7 @@ static int decrypt_session_key(struct ec
 	auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY;
 	memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
 	       auth_tok->session_key.decrypted_key_size);
-	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+	crypt_stat->flags |= ECRYPTFS_KEY_VALID;
 	ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
 	if (ecryptfs_verbosity > 0)
 		ecryptfs_dump_hex(crypt_stat->key,
@@ -1126,8 +1125,7 @@ int ecryptfs_parse_packet_set(struct ecr
 					sig_tmp_space, tag_11_contents_size);
 			new_auth_tok->token.password.signature[
 				ECRYPTFS_PASSWORD_SIG_SIZE] = '\0';
-			ECRYPTFS_SET_FLAG(crypt_stat->flags,
-					  ECRYPTFS_ENCRYPTED);
+			crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
 			break;
 		case ECRYPTFS_TAG_1_PACKET_TYPE:
 			rc = parse_tag_1_packet(crypt_stat,
@@ -1141,8 +1139,7 @@ int ecryptfs_parse_packet_set(struct ecr
 				goto out_wipe_list;
 			}
 			i += packet_size;
-			ECRYPTFS_SET_FLAG(crypt_stat->flags,
-					  ECRYPTFS_ENCRYPTED);
+			crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
 			break;
 		case ECRYPTFS_TAG_11_PACKET_TYPE:
 			ecryptfs_printk(KERN_WARNING, "Invalid packet set "
@@ -1208,8 +1205,7 @@ int ecryptfs_parse_packet_set(struct ecr
 	}
 leave_list:
 	rc = -ENOTSUPP;
-	if ((ECRYPTFS_CHECK_FLAG(candidate_auth_tok->flags,
-			         ECRYPTFS_PRIVATE_KEY))) {
+	if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
 		memcpy(&(candidate_auth_tok->token.private_key),
 		       &(chosen_auth_tok->token.private_key),
 		       sizeof(struct ecryptfs_private_key));
fs/ecryptfs/mmap.c +4 -4
index 6f167f1..2a7ba51 100644
@@ -295,8 +295,8 @@ static int ecryptfs_readpage(struct file
 	crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
 			->crypt_stat;
 	if (!crypt_stat
-	    || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)
-	    || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+	    || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
+	    || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
 		ecryptfs_printk(KERN_DEBUG,
 				"Passing through unencrypted page\n");
 		rc = ecryptfs_do_readpage(file, page, page->index);
@@ -657,10 +657,10 @@ static int ecryptfs_commit_write(struct 
 	mutex_lock(&lower_inode->i_mutex);
 	crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
 				->crypt_stat;
-	if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+	if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
 		ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
 			"crypt_stat at memory location [%p]\n", crypt_stat);
-		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+		crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE);
 	} else
 		ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
 	ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
Signature · 1 line
1.3.3
#5 lore raw

PATCH 4/5 eCryptfs: add flush_dcache_page() calls

In reply to Michael Halcrow
Quoted 7 lines · Andrew Morton

Review

Quoted 2 lines · On Tue, 9 Jan 2007 16:23:37 -0600 Michael Halcrow <[email protected]> wrote:
(quoted diff) +2 -0
+                                   set_header_info(page_virt, crypt_stat);
+                           }

The kernel must always run flush_dcache_page() after modifying a pagecache page by hand. Please review all of ecryptfs for this.

Call flush_dcache_page() after modifying a pagecache by hand.

---

 fs/ecryptfs/mmap.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

b77b1e2cbda1dfa6cc0925bca790701261771c43

fs/ecryptfs/mmap.c +6 -0
index 2a7ba51..59ec097 100644
@@ -238,7 +238,9 @@ int ecryptfs_do_readpage(struct file *fi
 	lower_page_data = (char *)kmap_atomic(lower_page, KM_USER1);
 	memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
 	kunmap_atomic(lower_page_data, KM_USER1);
+	flush_dcache_page(lower_page);
 	kunmap_atomic(page_data, KM_USER0);
+	flush_dcache_page(page);
 	rc = 0;
 out:
 	if (likely(lower_page))
@@ -322,6 +324,7 @@ static int ecryptfs_readpage(struct file
 					set_header_info(page_virt, crypt_stat);
 				}
 				kunmap_atomic(page_virt, KM_USER0);
+				flush_dcache_page(page);
 				if (rc) {
 					printk(KERN_ERR "Error reading xattr "
 					       "region\n");
@@ -382,6 +385,7 @@ static int fill_zeros_to_end_of_page(str
 	memset((page_virt + end_byte_in_page), 0,
 	       (PAGE_CACHE_SIZE - end_byte_in_page));
 	kunmap_atomic(page_virt, KM_USER0);
+	flush_dcache_page(page);
 out:
 	return 0;
 }
@@ -456,6 +460,7 @@ static int ecryptfs_write_inode_size_to_
 	header_virt = kmap_atomic(header_page, KM_USER0);
 	memcpy(header_virt, &file_size, sizeof(u64));
 	kunmap_atomic(header_virt, KM_USER0);
+	flush_dcache_page(header_page);
 	rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8);
 	if (rc < 0)
 		ecryptfs_printk(KERN_ERR, "Error commiting header page "
@@ -742,6 +747,7 @@ int write_zeros(struct file *file, pgoff
 	tmp_page_virt = kmap_atomic(tmp_page, KM_USER0);
 	memset(((char *)tmp_page_virt + start), 0, num_zeros);
 	kunmap_atomic(tmp_page_virt, KM_USER0);
+	flush_dcache_page(tmp_page);
 	rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros);
 	if (rc < 0) {
 		ecryptfs_printk(KERN_ERR, "Error attempting to write zero's "
Signature · 1 line
1.3.3
#6 lore raw

PATCH 5/5 eCryptfs: convert lookup_one_len() to lookup_one_len_nd()

In reply to Michael Halcrow

Call the new lookup_one_len_nd() rather than lookup_one_len(). This fixes an oops when stacked on NFS.

Note that there are still some issues with eCryptfs on NFS having to do with directory deletion (I'm not getting an oops, just an -EBUSY).

---
 fs/ecryptfs/inode.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
fs/ecryptfs/inode.c +8 -2
index 9135718..cf02a66 100644
@@ -283,7 +283,9 @@ static struct dentry *ecryptfs_lookup(st
 	int rc = 0;
 	struct dentry *lower_dir_dentry;
 	struct dentry *lower_dentry;
+	struct dentry *dentry_save;
 	struct vfsmount *lower_mnt;
+	struct vfsmount *mnt_save;
 	char *encoded_name;
 	unsigned int encoded_namelen;
 	struct ecryptfs_crypt_stat *crypt_stat = NULL;
@@ -311,9 +313,13 @@ static struct dentry *ecryptfs_lookup(st
 	}
 	ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
 			"= [%d]\n", encoded_name, encoded_namelen);
-	lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
-				      encoded_namelen - 1);
+	dentry_save = nd->dentry;
+	mnt_save = nd->mnt;
+	lower_dentry = lookup_one_len_nd(encoded_name, lower_dir_dentry,
+					 (encoded_namelen - 1), nd);
 	kfree(encoded_name);
+	nd->mnt = mnt_save;
+	nd->dentry = dentry_save;
 	if (IS_ERR(lower_dentry)) {
 		ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
 		rc = PTR_ERR(lower_dentry);
Signature · 1 line
1.4.2.4