Skip to content

Commit 5ccf920

Browse files
author
Tyler Hicks
committed
eCryptfs: Cleanup inode initialization code
The eCryptfs inode get, initialization, and dentry interposition code has two separate paths. One is for when dentry interposition is needed after doing things like a mkdir in the lower filesystem and the other is needed after a lookup. Unlocking new inodes and doing a d_add() needs to happen at different times, depending on which type of dentry interposing is being done. This patch cleans up the inode get and initialization code paths and splits them up so that the locking and d_add() differences mentioned above can be handled appropriately in a later patch. Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com> Tested-by: David <david@unsolicited.net>
1 parent c4f7907 commit 5ccf920

File tree

2 files changed

+69
-68
lines changed

2 files changed

+69
-68
lines changed

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,6 @@ struct ecryptfs_open_req {
628628
struct inode *ecryptfs_get_inode(struct inode *lower_inode,
629629
struct super_block *sb);
630630
void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
631-
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
632-
struct dentry *lower_dentry,
633-
struct inode *ecryptfs_dir_inode);
634631
int ecryptfs_decode_and_decrypt_filename(char **decrypted_name,
635632
size_t *decrypted_name_size,
636633
struct dentry *ecryptfs_dentry,

fs/ecryptfs/inode.c

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -58,85 +58,87 @@ static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
5858
return 0;
5959
}
6060

61-
static int ecryptfs_inode_set(struct inode *inode, void *lower_inode)
61+
static int ecryptfs_inode_set(struct inode *inode, void *opaque)
6262
{
63-
ecryptfs_set_inode_lower(inode, (struct inode *)lower_inode);
64-
inode->i_ino = ((struct inode *)lower_inode)->i_ino;
63+
struct inode *lower_inode = opaque;
64+
65+
ecryptfs_set_inode_lower(inode, lower_inode);
66+
fsstack_copy_attr_all(inode, lower_inode);
67+
/* i_size will be overwritten for encrypted regular files */
68+
fsstack_copy_inode_size(inode, lower_inode);
69+
inode->i_ino = lower_inode->i_ino;
6570
inode->i_version++;
66-
inode->i_op = &ecryptfs_main_iops;
67-
inode->i_fop = &ecryptfs_main_fops;
6871
inode->i_mapping->a_ops = &ecryptfs_aops;
72+
73+
if (S_ISLNK(inode->i_mode))
74+
inode->i_op = &ecryptfs_symlink_iops;
75+
else if (S_ISDIR(inode->i_mode))
76+
inode->i_op = &ecryptfs_dir_iops;
77+
else
78+
inode->i_op = &ecryptfs_main_iops;
79+
80+
if (S_ISDIR(inode->i_mode))
81+
inode->i_fop = &ecryptfs_dir_fops;
82+
else if (special_file(inode->i_mode))
83+
init_special_inode(inode, inode->i_mode, inode->i_rdev);
84+
else
85+
inode->i_fop = &ecryptfs_main_fops;
86+
6987
return 0;
7088
}
7189

72-
struct inode *ecryptfs_get_inode(struct inode *lower_inode,
73-
struct super_block *sb)
90+
static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
91+
struct super_block *sb)
7492
{
7593
struct inode *inode;
76-
int rc = 0;
7794

78-
if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) {
79-
rc = -EXDEV;
80-
goto out;
81-
}
82-
if (!igrab(lower_inode)) {
83-
rc = -ESTALE;
84-
goto out;
85-
}
95+
if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb))
96+
return ERR_PTR(-EXDEV);
97+
if (!igrab(lower_inode))
98+
return ERR_PTR(-ESTALE);
8699
inode = iget5_locked(sb, (unsigned long)lower_inode,
87100
ecryptfs_inode_test, ecryptfs_inode_set,
88101
lower_inode);
89102
if (!inode) {
90-
rc = -EACCES;
91103
iput(lower_inode);
92-
goto out;
104+
return ERR_PTR(-EACCES);
93105
}
94-
if (inode->i_state & I_NEW)
95-
unlock_new_inode(inode);
96-
else
106+
if (!(inode->i_state & I_NEW))
97107
iput(lower_inode);
98-
if (S_ISLNK(lower_inode->i_mode))
99-
inode->i_op = &ecryptfs_symlink_iops;
100-
else if (S_ISDIR(lower_inode->i_mode))
101-
inode->i_op = &ecryptfs_dir_iops;
102-
if (S_ISDIR(lower_inode->i_mode))
103-
inode->i_fop = &ecryptfs_dir_fops;
104-
if (special_file(lower_inode->i_mode))
105-
init_special_inode(inode, lower_inode->i_mode,
106-
lower_inode->i_rdev);
107-
fsstack_copy_attr_all(inode, lower_inode);
108-
/* This size will be overwritten for real files w/ headers and
109-
* other metadata */
110-
fsstack_copy_inode_size(inode, lower_inode);
108+
109+
return inode;
110+
}
111+
112+
struct inode *ecryptfs_get_inode(struct inode *lower_inode,
113+
struct super_block *sb)
114+
{
115+
struct inode *inode = __ecryptfs_get_inode(lower_inode, sb);
116+
117+
if (!IS_ERR(inode) && (inode->i_state & I_NEW))
118+
unlock_new_inode(inode);
119+
111120
return inode;
112-
out:
113-
return ERR_PTR(rc);
114121
}
115122

116-
#define ECRYPTFS_INTERPOSE_FLAG_D_ADD 0x00000001
117123
/**
118124
* ecryptfs_interpose
119125
* @lower_dentry: Existing dentry in the lower filesystem
120126
* @dentry: ecryptfs' dentry
121127
* @sb: ecryptfs's super_block
122-
* @flags: flags to govern behavior of interpose procedure
123128
*
124129
* Interposes upper and lower dentries.
125130
*
126131
* Returns zero on success; non-zero otherwise
127132
*/
128133
static int ecryptfs_interpose(struct dentry *lower_dentry,
129-
struct dentry *dentry, struct super_block *sb,
130-
u32 flags)
134+
struct dentry *dentry, struct super_block *sb)
131135
{
132-
struct inode *lower_inode = lower_dentry->d_inode;
133-
struct inode *inode = ecryptfs_get_inode(lower_inode, sb);
136+
struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb);
137+
134138
if (IS_ERR(inode))
135139
return PTR_ERR(inode);
136-
if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD)
137-
d_add(dentry, inode);
138-
else
139-
d_instantiate(dentry, inode);
140+
d_instantiate(dentry, inode);
141+
140142
return 0;
141143
}
142144

@@ -218,7 +220,7 @@ ecryptfs_do_create(struct inode *directory_inode,
218220
goto out_lock;
219221
}
220222
rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
221-
directory_inode->i_sb, 0);
223+
directory_inode->i_sb);
222224
if (rc) {
223225
ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n");
224226
goto out_lock;
@@ -305,15 +307,15 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
305307
}
306308

307309
/**
308-
* ecryptfs_lookup_and_interpose_lower - Perform a lookup
310+
* ecryptfs_lookup_interpose - Dentry interposition for a lookup
309311
*/
310-
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
311-
struct dentry *lower_dentry,
312-
struct inode *ecryptfs_dir_inode)
312+
static int ecryptfs_lookup_interpose(struct dentry *ecryptfs_dentry,
313+
struct dentry *lower_dentry,
314+
struct inode *ecryptfs_dir_inode)
313315
{
314316
struct dentry *lower_dir_dentry;
315317
struct vfsmount *lower_mnt;
316-
struct inode *lower_inode;
318+
struct inode *inode, *lower_inode;
317319
struct ecryptfs_crypt_stat *crypt_stat;
318320
char *page_virt = NULL;
319321
int put_lower = 0, rc = 0;
@@ -341,14 +343,16 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
341343
d_add(ecryptfs_dentry, NULL);
342344
goto out;
343345
}
344-
rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
345-
ecryptfs_dir_inode->i_sb,
346-
ECRYPTFS_INTERPOSE_FLAG_D_ADD);
347-
if (rc) {
346+
inode = __ecryptfs_get_inode(lower_inode, ecryptfs_dir_inode->i_sb);
347+
if (IS_ERR(inode)) {
348+
rc = PTR_ERR(inode);
348349
printk(KERN_ERR "%s: Error interposing; rc = [%d]\n",
349350
__func__, rc);
350351
goto out;
351352
}
353+
if (inode->i_state & I_NEW)
354+
unlock_new_inode(inode);
355+
d_add(ecryptfs_dentry, inode);
352356
if (S_ISDIR(lower_inode->i_mode))
353357
goto out;
354358
if (S_ISLNK(lower_inode->i_mode))
@@ -442,12 +446,12 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
442446
goto out_d_drop;
443447
}
444448
if (lower_dentry->d_inode)
445-
goto lookup_and_interpose;
449+
goto interpose;
446450
mount_crypt_stat = &ecryptfs_superblock_to_private(
447451
ecryptfs_dentry->d_sb)->mount_crypt_stat;
448452
if (!(mount_crypt_stat
449453
&& (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)))
450-
goto lookup_and_interpose;
454+
goto interpose;
451455
dput(lower_dentry);
452456
rc = ecryptfs_encrypt_and_encode_filename(
453457
&encrypted_and_encoded_name, &encrypted_and_encoded_name_size,
@@ -470,9 +474,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
470474
encrypted_and_encoded_name);
471475
goto out_d_drop;
472476
}
473-
lookup_and_interpose:
474-
rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry,
475-
ecryptfs_dir_inode);
477+
interpose:
478+
rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry,
479+
ecryptfs_dir_inode);
476480
goto out;
477481
out_d_drop:
478482
d_drop(ecryptfs_dentry);
@@ -500,7 +504,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
500504
lower_new_dentry);
501505
if (rc || !lower_new_dentry->d_inode)
502506
goto out_lock;
503-
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
507+
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
504508
if (rc)
505509
goto out_lock;
506510
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
@@ -567,7 +571,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
567571
kfree(encoded_symname);
568572
if (rc || !lower_dentry->d_inode)
569573
goto out_lock;
570-
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
574+
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
571575
if (rc)
572576
goto out_lock;
573577
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
@@ -591,7 +595,7 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
591595
rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
592596
if (rc || !lower_dentry->d_inode)
593597
goto out;
594-
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
598+
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
595599
if (rc)
596600
goto out;
597601
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
@@ -639,7 +643,7 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
639643
rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
640644
if (rc || !lower_dentry->d_inode)
641645
goto out;
642-
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
646+
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
643647
if (rc)
644648
goto out;
645649
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);

0 commit comments

Comments
 (0)