Skip to content

Commit cd2e49e

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6: eCryptfs: Flush dirty pages in setattr eCryptfs: Handle failed metadata read in lookup eCryptfs: Add reference counting to lower files eCryptfs: dput dentries returned from dget_parent eCryptfs: Remove extra d_delete in ecryptfs_rmdir
2 parents 71e9e6a + 5be79de commit cd2e49e

File tree

7 files changed

+128
-79
lines changed

7 files changed

+128
-79
lines changed

fs/ecryptfs/crypto.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
14521452
crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
14531453
}
14541454

1455+
void ecryptfs_i_size_init(const char *page_virt, struct inode *inode)
1456+
{
1457+
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
1458+
struct ecryptfs_crypt_stat *crypt_stat;
1459+
u64 file_size;
1460+
1461+
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
1462+
mount_crypt_stat =
1463+
&ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
1464+
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
1465+
file_size = i_size_read(ecryptfs_inode_to_lower(inode));
1466+
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
1467+
file_size += crypt_stat->metadata_size;
1468+
} else
1469+
file_size = get_unaligned_be64(page_virt);
1470+
i_size_write(inode, (loff_t)file_size);
1471+
crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED;
1472+
}
1473+
14551474
/**
14561475
* ecryptfs_read_headers_virt
14571476
* @page_virt: The virtual address into which to read the headers
@@ -1482,6 +1501,8 @@ static int ecryptfs_read_headers_virt(char *page_virt,
14821501
rc = -EINVAL;
14831502
goto out;
14841503
}
1504+
if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED))
1505+
ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
14851506
offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
14861507
rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
14871508
&bytes_read);

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ struct ecryptfs_crypt_stat {
269269
#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800
270270
#define ECRYPTFS_ENCFN_USE_FEK 0x00001000
271271
#define ECRYPTFS_UNLINK_SIGS 0x00002000
272+
#define ECRYPTFS_I_SIZE_INITIALIZED 0x00004000
272273
u32 flags;
273274
unsigned int file_version;
274275
size_t iv_bytes;
@@ -295,6 +296,8 @@ struct ecryptfs_crypt_stat {
295296
struct ecryptfs_inode_info {
296297
struct inode vfs_inode;
297298
struct inode *wii_inode;
299+
struct mutex lower_file_mutex;
300+
atomic_t lower_file_count;
298301
struct file *lower_file;
299302
struct ecryptfs_crypt_stat crypt_stat;
300303
};
@@ -626,6 +629,7 @@ struct ecryptfs_open_req {
626629
int ecryptfs_interpose(struct dentry *hidden_dentry,
627630
struct dentry *this_dentry, struct super_block *sb,
628631
u32 flags);
632+
void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
629633
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
630634
struct dentry *lower_dentry,
631635
struct inode *ecryptfs_dir_inode);
@@ -757,7 +761,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
757761
struct dentry *lower_dentry,
758762
struct vfsmount *lower_mnt,
759763
const struct cred *cred);
760-
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
764+
int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry);
765+
void ecryptfs_put_lower_file(struct inode *inode);
761766
int
762767
ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
763768
size_t *packet_size,

fs/ecryptfs/file.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,20 +191,20 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
191191
| ECRYPTFS_ENCRYPTED);
192192
}
193193
mutex_unlock(&crypt_stat->cs_mutex);
194-
rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
194+
rc = ecryptfs_get_lower_file(ecryptfs_dentry);
195195
if (rc) {
196196
printk(KERN_ERR "%s: Error attempting to initialize "
197-
"the persistent file for the dentry with name "
197+
"the lower file for the dentry with name "
198198
"[%s]; rc = [%d]\n", __func__,
199199
ecryptfs_dentry->d_name.name, rc);
200200
goto out_free;
201201
}
202202
if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE)
203203
== O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) {
204204
rc = -EPERM;
205-
printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
205+
printk(KERN_WARNING "%s: Lower file is RO; eCryptfs "
206206
"file must hence be opened RO\n", __func__);
207-
goto out_free;
207+
goto out_put;
208208
}
209209
ecryptfs_set_file_lower(
210210
file, ecryptfs_inode_to_private(inode)->lower_file);
@@ -232,10 +232,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
232232
"Plaintext passthrough mode is not "
233233
"enabled; returning -EIO\n");
234234
mutex_unlock(&crypt_stat->cs_mutex);
235-
goto out_free;
235+
goto out_put;
236236
}
237237
rc = 0;
238-
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
238+
crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
239+
| ECRYPTFS_ENCRYPTED);
239240
mutex_unlock(&crypt_stat->cs_mutex);
240241
goto out;
241242
}
@@ -245,6 +246,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
245246
"[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino,
246247
(unsigned long long)i_size_read(inode));
247248
goto out;
249+
out_put:
250+
ecryptfs_put_lower_file(inode);
248251
out_free:
249252
kmem_cache_free(ecryptfs_file_info_cache,
250253
ecryptfs_file_to_private(file));
@@ -254,17 +257,13 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
254257

255258
static int ecryptfs_flush(struct file *file, fl_owner_t td)
256259
{
257-
int rc = 0;
258-
struct file *lower_file = NULL;
259-
260-
lower_file = ecryptfs_file_to_lower(file);
261-
if (lower_file->f_op && lower_file->f_op->flush)
262-
rc = lower_file->f_op->flush(lower_file, td);
263-
return rc;
260+
return file->f_mode & FMODE_WRITE
261+
? filemap_write_and_wait(file->f_mapping) : 0;
264262
}
265263

266264
static int ecryptfs_release(struct inode *inode, struct file *file)
267265
{
266+
ecryptfs_put_lower_file(inode);
268267
kmem_cache_free(ecryptfs_file_info_cache,
269268
ecryptfs_file_to_private(file));
270269
return 0;

fs/ecryptfs/inode.c

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,18 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
168168
"context; rc = [%d]\n", rc);
169169
goto out;
170170
}
171-
rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
171+
rc = ecryptfs_get_lower_file(ecryptfs_dentry);
172172
if (rc) {
173173
printk(KERN_ERR "%s: Error attempting to initialize "
174-
"the persistent file for the dentry with name "
174+
"the lower file for the dentry with name "
175175
"[%s]; rc = [%d]\n", __func__,
176176
ecryptfs_dentry->d_name.name, rc);
177177
goto out;
178178
}
179179
rc = ecryptfs_write_metadata(ecryptfs_dentry);
180-
if (rc) {
180+
if (rc)
181181
printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
182-
goto out;
183-
}
182+
ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
184183
out:
185184
return rc;
186185
}
@@ -226,11 +225,9 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
226225
struct dentry *lower_dir_dentry;
227226
struct vfsmount *lower_mnt;
228227
struct inode *lower_inode;
229-
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
230228
struct ecryptfs_crypt_stat *crypt_stat;
231229
char *page_virt = NULL;
232-
u64 file_size;
233-
int rc = 0;
230+
int put_lower = 0, rc = 0;
234231

235232
lower_dir_dentry = lower_dentry->d_parent;
236233
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(
@@ -277,14 +274,15 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
277274
rc = -ENOMEM;
278275
goto out;
279276
}
280-
rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
277+
rc = ecryptfs_get_lower_file(ecryptfs_dentry);
281278
if (rc) {
282279
printk(KERN_ERR "%s: Error attempting to initialize "
283-
"the persistent file for the dentry with name "
280+
"the lower file for the dentry with name "
284281
"[%s]; rc = [%d]\n", __func__,
285282
ecryptfs_dentry->d_name.name, rc);
286283
goto out_free_kmem;
287284
}
285+
put_lower = 1;
288286
crypt_stat = &ecryptfs_inode_to_private(
289287
ecryptfs_dentry->d_inode)->crypt_stat;
290288
/* TODO: lock for crypt_stat comparison */
@@ -302,18 +300,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
302300
}
303301
crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
304302
}
305-
mount_crypt_stat = &ecryptfs_superblock_to_private(
306-
ecryptfs_dentry->d_sb)->mount_crypt_stat;
307-
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
308-
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
309-
file_size = (crypt_stat->metadata_size
310-
+ i_size_read(lower_dentry->d_inode));
311-
else
312-
file_size = i_size_read(lower_dentry->d_inode);
313-
} else {
314-
file_size = get_unaligned_be64(page_virt);
315-
}
316-
i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size);
303+
ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
317304
out_free_kmem:
318305
kmem_cache_free(ecryptfs_header_cache_2, page_virt);
319306
goto out;
@@ -322,6 +309,8 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
322309
mntput(lower_mnt);
323310
d_drop(ecryptfs_dentry);
324311
out:
312+
if (put_lower)
313+
ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
325314
return rc;
326315
}
327316

@@ -538,8 +527,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
538527
dget(lower_dentry);
539528
rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
540529
dput(lower_dentry);
541-
if (!rc)
542-
d_delete(lower_dentry);
543530
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
544531
dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
545532
unlock_dir(lower_dir_dentry);
@@ -610,8 +597,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
610597
fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
611598
out_lock:
612599
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
613-
dput(lower_new_dentry->d_parent);
614-
dput(lower_old_dentry->d_parent);
600+
dput(lower_new_dir_dentry);
601+
dput(lower_old_dir_dentry);
615602
dput(lower_new_dentry);
616603
dput(lower_old_dentry);
617604
return rc;
@@ -759,8 +746,11 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
759746

760747
if (unlikely((ia->ia_size == i_size))) {
761748
lower_ia->ia_valid &= ~ATTR_SIZE;
762-
goto out;
749+
return 0;
763750
}
751+
rc = ecryptfs_get_lower_file(dentry);
752+
if (rc)
753+
return rc;
764754
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
765755
/* Switch on growing or shrinking file */
766756
if (ia->ia_size > i_size) {
@@ -838,6 +828,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
838828
lower_ia->ia_valid &= ~ATTR_SIZE;
839829
}
840830
out:
831+
ecryptfs_put_lower_file(inode);
841832
return rc;
842833
}
843834

@@ -913,7 +904,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
913904

914905
mount_crypt_stat = &ecryptfs_superblock_to_private(
915906
dentry->d_sb)->mount_crypt_stat;
907+
rc = ecryptfs_get_lower_file(dentry);
908+
if (rc) {
909+
mutex_unlock(&crypt_stat->cs_mutex);
910+
goto out;
911+
}
916912
rc = ecryptfs_read_metadata(dentry);
913+
ecryptfs_put_lower_file(inode);
917914
if (rc) {
918915
if (!(mount_crypt_stat->flags
919916
& ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
@@ -927,10 +924,17 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
927924
goto out;
928925
}
929926
rc = 0;
930-
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
927+
crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
928+
| ECRYPTFS_ENCRYPTED);
931929
}
932930
}
933931
mutex_unlock(&crypt_stat->cs_mutex);
932+
if (S_ISREG(inode->i_mode)) {
933+
rc = filemap_write_and_wait(inode->i_mapping);
934+
if (rc)
935+
goto out;
936+
fsstack_copy_attr_all(inode, lower_inode);
937+
}
934938
memcpy(&lower_ia, ia, sizeof(lower_ia));
935939
if (ia->ia_valid & ATTR_FILE)
936940
lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);

fs/ecryptfs/kthread.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static struct task_struct *ecryptfs_kthread;
4444
* @ignored: ignored
4545
*
4646
* The eCryptfs kernel thread that has the responsibility of getting
47-
* the lower persistent file with RW permissions.
47+
* the lower file with RW permissions.
4848
*
4949
* Returns zero on success; non-zero otherwise
5050
*/
@@ -141,8 +141,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
141141
int rc = 0;
142142

143143
/* Corresponding dput() and mntput() are done when the
144-
* persistent file is fput() when the eCryptfs inode is
145-
* destroyed. */
144+
* lower file is fput() when all eCryptfs files for the inode are
145+
* released. */
146146
dget(lower_dentry);
147147
mntget(lower_mnt);
148148
flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;

0 commit comments

Comments
 (0)