aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2006-10-31 01:07:19 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-31 11:07:01 -0500
commit7ff1d74f5670329ac4b5959a675f8698ba95be20 (patch)
tree1084427fcd0b979c8434315050033dd356623cf3
parent8bba066f4e3854755a303cee37ea37bd080a46b3 (diff)
[PATCH] eCryptfs: Consolidate lower dentry_open's
Opens on lower dentry objects happen in several places in eCryptfs, and they all involve the same steps (dget, mntget, dentry_open). This patch consolidates the lower open events into a single function call. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/ecryptfs/crypto.c24
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h4
-rw-r--r--fs/ecryptfs/file.c44
-rw-r--r--fs/ecryptfs/inode.c33
4 files changed, 63 insertions, 42 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 2a1b6aa1a4a1..f49f105394b7 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1191,28 +1191,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
1191int ecryptfs_read_header_region(char *data, struct dentry *dentry, 1191int ecryptfs_read_header_region(char *data, struct dentry *dentry,
1192 struct vfsmount *mnt) 1192 struct vfsmount *mnt)
1193{ 1193{
1194 struct file *file; 1194 struct file *lower_file;
1195 mm_segment_t oldfs; 1195 mm_segment_t oldfs;
1196 int rc; 1196 int rc;
1197 1197
1198 mnt = mntget(mnt); 1198 if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
1199 file = dentry_open(dentry, mnt, O_RDONLY); 1199 O_RDONLY))) {
1200 if (IS_ERR(file)) { 1200 printk(KERN_ERR
1201 ecryptfs_printk(KERN_DEBUG, "Error opening file to " 1201 "Error opening lower_file to read header region\n");
1202 "read header region\n");
1203 mntput(mnt);
1204 rc = PTR_ERR(file);
1205 goto out; 1202 goto out;
1206 } 1203 }
1207 file->f_pos = 0; 1204 lower_file->f_pos = 0;
1208 oldfs = get_fs(); 1205 oldfs = get_fs();
1209 set_fs(get_ds()); 1206 set_fs(get_ds());
1210 /* For releases 0.1 and 0.2, all of the header information 1207 /* For releases 0.1 and 0.2, all of the header information
1211 * fits in the first data extent-sized region. */ 1208 * fits in the first data extent-sized region. */
1212 rc = file->f_op->read(file, (char __user *)data, 1209 rc = lower_file->f_op->read(lower_file, (char __user *)data,
1213 ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos); 1210 ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
1214 set_fs(oldfs); 1211 set_fs(oldfs);
1215 fput(file); 1212 if ((rc = ecryptfs_close_lower_file(lower_file))) {
1213 printk(KERN_ERR "Error closing lower_file\n");
1214 goto out;
1215 }
1216 rc = 0; 1216 rc = 0;
1217out: 1217out:
1218 return rc; 1218 return rc;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 199fcda50e1b..f992533d1692 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -482,5 +482,9 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
482int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); 482int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
483int ecryptfs_inode_set(struct inode *inode, void *lower_inode); 483int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
484void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); 484void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
485int ecryptfs_open_lower_file(struct file **lower_file,
486 struct dentry *lower_dentry,
487 struct vfsmount *lower_mnt, int flags);
488int ecryptfs_close_lower_file(struct file *lower_file);
485 489
486#endif /* #ifndef ECRYPTFS_KERNEL_H */ 490#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index c8550c9f9cd2..a92ef05eff8f 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -198,6 +198,33 @@ retry:
198 198
199struct kmem_cache *ecryptfs_file_info_cache; 199struct kmem_cache *ecryptfs_file_info_cache;
200 200
201int ecryptfs_open_lower_file(struct file **lower_file,
202 struct dentry *lower_dentry,
203 struct vfsmount *lower_mnt, int flags)
204{
205 int rc = 0;
206
207 dget(lower_dentry);
208 mntget(lower_mnt);
209 *lower_file = dentry_open(lower_dentry, lower_mnt, flags);
210 if (IS_ERR(*lower_file)) {
211 printk(KERN_ERR "Error opening lower file for lower_dentry "
212 "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
213 lower_dentry, lower_mnt, flags);
214 rc = PTR_ERR(*lower_file);
215 *lower_file = NULL;
216 goto out;
217 }
218out:
219 return rc;
220}
221
222int ecryptfs_close_lower_file(struct file *lower_file)
223{
224 fput(lower_file);
225 return 0;
226}
227
201/** 228/**
202 * ecryptfs_open 229 * ecryptfs_open
203 * @inode: inode speciying file to open 230 * @inode: inode speciying file to open
@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
244 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); 271 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
245 } 272 }
246 mutex_unlock(&crypt_stat->cs_mutex); 273 mutex_unlock(&crypt_stat->cs_mutex);
247 /* This mntget & dget is undone via fput when the file is released */
248 dget(lower_dentry);
249 lower_flags = file->f_flags; 274 lower_flags = file->f_flags;
250 if ((lower_flags & O_ACCMODE) == O_WRONLY) 275 if ((lower_flags & O_ACCMODE) == O_WRONLY)
251 lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; 276 lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
252 if (file->f_flags & O_APPEND) 277 if (file->f_flags & O_APPEND)
253 lower_flags &= ~O_APPEND; 278 lower_flags &= ~O_APPEND;
254 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); 279 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
255 mntget(lower_mnt);
256 /* Corresponding fput() in ecryptfs_release() */ 280 /* Corresponding fput() in ecryptfs_release() */
257 lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); 281 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
258 if (IS_ERR(lower_file)) { 282 lower_flags))) {
259 rc = PTR_ERR(lower_file);
260 ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); 283 ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
261 goto out_puts; 284 goto out_puts;
262 } 285 }
@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
341 struct file *lower_file = ecryptfs_file_to_lower(file); 364 struct file *lower_file = ecryptfs_file_to_lower(file);
342 struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); 365 struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
343 struct inode *lower_inode = ecryptfs_inode_to_lower(inode); 366 struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
367 int rc;
344 368
345 fput(lower_file); 369 if ((rc = ecryptfs_close_lower_file(lower_file))) {
370 printk(KERN_ERR "Error closing lower_file\n");
371 goto out;
372 }
346 inode->i_blocks = lower_inode->i_blocks; 373 inode->i_blocks = lower_inode->i_blocks;
347 kmem_cache_free(ecryptfs_file_info_cache, file_info); 374 kmem_cache_free(ecryptfs_file_info_cache, file_info);
348 return 0; 375out:
376 return rc;
349} 377}
350 378
351static int 379static int
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index efdd2b7b62d7..2f2c6cf972f7 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
231 int lower_flags; 231 int lower_flags;
232 struct ecryptfs_crypt_stat *crypt_stat; 232 struct ecryptfs_crypt_stat *crypt_stat;
233 struct dentry *lower_dentry; 233 struct dentry *lower_dentry;
234 struct dentry *tlower_dentry = NULL;
235 struct file *lower_file; 234 struct file *lower_file;
236 struct inode *inode, *lower_inode; 235 struct inode *inode, *lower_inode;
237 struct vfsmount *lower_mnt; 236 struct vfsmount *lower_mnt;
@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
241 lower_dentry->d_name.name); 240 lower_dentry->d_name.name);
242 inode = ecryptfs_dentry->d_inode; 241 inode = ecryptfs_dentry->d_inode;
243 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 242 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
244 tlower_dentry = dget(lower_dentry);
245 if (!tlower_dentry) {
246 rc = -ENOMEM;
247 ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
248 goto out;
249 }
250 lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; 243 lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
251#if BITS_PER_LONG != 32 244#if BITS_PER_LONG != 32
252 lower_flags |= O_LARGEFILE; 245 lower_flags |= O_LARGEFILE;
253#endif 246#endif
254 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); 247 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
255 mntget(lower_mnt);
256 /* Corresponding fput() at end of this function */ 248 /* Corresponding fput() at end of this function */
257 lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); 249 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
258 if (IS_ERR(lower_file)) { 250 lower_flags))) {
259 rc = PTR_ERR(lower_file);
260 ecryptfs_printk(KERN_ERR, 251 ecryptfs_printk(KERN_ERR,
261 "Error opening dentry; rc = [%i]\n", rc); 252 "Error opening dentry; rc = [%i]\n", rc);
262 goto out; 253 goto out;
263 } 254 }
264 /* fput(lower_file) should handle the puts if we do this */ 255 lower_inode = lower_dentry->d_inode;
265 lower_file->f_dentry = tlower_dentry;
266 lower_file->f_vfsmnt = lower_mnt;
267 lower_inode = tlower_dentry->d_inode;
268 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { 256 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
269 ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); 257 ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
270 ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); 258 ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
285 } 273 }
286 rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); 274 rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
287out_fput: 275out_fput:
288 fput(lower_file); 276 if ((rc = ecryptfs_close_lower_file(lower_file)))
277 printk(KERN_ERR "Error closing lower_file\n");
289out: 278out:
290 return rc; 279 return rc;
291} 280}
@@ -832,12 +821,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
832 } 821 }
833 lower_dentry = ecryptfs_dentry_to_lower(dentry); 822 lower_dentry = ecryptfs_dentry_to_lower(dentry);
834 /* This dget & mntget is released through fput at out_fput: */ 823 /* This dget & mntget is released through fput at out_fput: */
835 dget(lower_dentry);
836 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); 824 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
837 mntget(lower_mnt); 825 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
838 lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); 826 O_RDWR))) {
839 if (unlikely(IS_ERR(lower_file))) { 827 ecryptfs_printk(KERN_ERR,
840 rc = PTR_ERR(lower_file); 828 "Error opening dentry; rc = [%i]\n", rc);
841 goto out_free; 829 goto out_free;
842 } 830 }
843 ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); 831 ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
@@ -879,7 +867,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
879 = CURRENT_TIME; 867 = CURRENT_TIME;
880 mark_inode_dirty_sync(inode); 868 mark_inode_dirty_sync(inode);
881out_fput: 869out_fput:
882 fput(lower_file); 870 if ((rc = ecryptfs_close_lower_file(lower_file)))
871 printk(KERN_ERR "Error closing lower_file\n");
883out_free: 872out_free:
884 if (ecryptfs_file_to_private(&fake_ecryptfs_file)) 873 if (ecryptfs_file_to_private(&fake_ecryptfs_file))
885 kmem_cache_free(ecryptfs_file_info_cache, 874 kmem_cache_free(ecryptfs_file_info_cache,