diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2006-10-31 01:07:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-31 11:07:01 -0500 |
commit | 7ff1d74f5670329ac4b5959a675f8698ba95be20 (patch) | |
tree | 1084427fcd0b979c8434315050033dd356623cf3 | |
parent | 8bba066f4e3854755a303cee37ea37bd080a46b3 (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.c | 24 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 4 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 44 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 33 |
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) | |||
1191 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | 1191 | int 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; |
1217 | out: | 1217 | out: |
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, | |||
482 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | 482 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); |
483 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | 483 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); |
484 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | 484 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); |
485 | int ecryptfs_open_lower_file(struct file **lower_file, | ||
486 | struct dentry *lower_dentry, | ||
487 | struct vfsmount *lower_mnt, int flags); | ||
488 | int 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 | ||
199 | struct kmem_cache *ecryptfs_file_info_cache; | 199 | struct kmem_cache *ecryptfs_file_info_cache; |
200 | 200 | ||
201 | int 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 | } | ||
218 | out: | ||
219 | return rc; | ||
220 | } | ||
221 | |||
222 | int 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; | 375 | out: |
376 | return rc; | ||
349 | } | 377 | } |
350 | 378 | ||
351 | static int | 379 | static 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); |
287 | out_fput: | 275 | out_fput: |
288 | fput(lower_file); | 276 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
277 | printk(KERN_ERR "Error closing lower_file\n"); | ||
289 | out: | 278 | out: |
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); |
881 | out_fput: | 869 | out_fput: |
882 | fput(lower_file); | 870 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
871 | printk(KERN_ERR "Error closing lower_file\n"); | ||
883 | out_free: | 872 | out_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, |