Skip to content

Commit b28866f

Browse files
committed
Merge branch 'work.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull exryptfs updates from Al Viro: "The interesting part here is (ecryptfs) lock_parent() fixes - its treatment of ->d_parent had been very wrong. The rest is trivial cleanups" * 'work.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: ecryptfs: ecryptfs_dentry_info->crypt_stat is never used ecryptfs: get rid of unused accessors ecryptfs: saner API for lock_parent() ecryptfs: get rid of pointless dget/dput in ->symlink() and ->link()
2 parents 17ae69a + 9d786be commit b28866f

File tree

2 files changed

+75
-105
lines changed

2 files changed

+75
-105
lines changed

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,7 @@ struct ecryptfs_inode_info {
262262
* vfsmount too. */
263263
struct ecryptfs_dentry_info {
264264
struct path lower_path;
265-
union {
266-
struct ecryptfs_crypt_stat *crypt_stat;
267-
struct rcu_head rcu;
268-
};
265+
struct rcu_head rcu;
269266
};
270267

271268
/**
@@ -496,12 +493,6 @@ ecryptfs_set_superblock_lower(struct super_block *sb,
496493
((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb = lower_sb;
497494
}
498495

499-
static inline struct ecryptfs_dentry_info *
500-
ecryptfs_dentry_to_private(struct dentry *dentry)
501-
{
502-
return (struct ecryptfs_dentry_info *)dentry->d_fsdata;
503-
}
504-
505496
static inline void
506497
ecryptfs_set_dentry_private(struct dentry *dentry,
507498
struct ecryptfs_dentry_info *dentry_info)
@@ -515,12 +506,6 @@ ecryptfs_dentry_to_lower(struct dentry *dentry)
515506
return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry;
516507
}
517508

518-
static inline struct vfsmount *
519-
ecryptfs_dentry_to_lower_mnt(struct dentry *dentry)
520-
{
521-
return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.mnt;
522-
}
523-
524509
static inline struct path *
525510
ecryptfs_dentry_to_lower_path(struct dentry *dentry)
526511
{

fs/ecryptfs/inode.c

Lines changed: 74 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@
2222
#include <asm/unaligned.h>
2323
#include "ecryptfs_kernel.h"
2424

25-
static struct dentry *lock_parent(struct dentry *dentry)
25+
static int lock_parent(struct dentry *dentry,
26+
struct dentry **lower_dentry,
27+
struct inode **lower_dir)
2628
{
27-
struct dentry *dir;
29+
struct dentry *lower_dir_dentry;
2830

29-
dir = dget_parent(dentry);
30-
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
31-
return dir;
32-
}
31+
lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
32+
*lower_dir = d_inode(lower_dir_dentry);
33+
*lower_dentry = ecryptfs_dentry_to_lower(dentry);
3334

34-
static void unlock_dir(struct dentry *dir)
35-
{
36-
inode_unlock(d_inode(dir));
37-
dput(dir);
35+
inode_lock_nested(*lower_dir, I_MUTEX_PARENT);
36+
return (*lower_dentry)->d_parent == lower_dir_dentry ? 0 : -EINVAL;
3837
}
3938

4039
static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
@@ -128,32 +127,29 @@ static int ecryptfs_interpose(struct dentry *lower_dentry,
128127
static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
129128
struct inode *inode)
130129
{
131-
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
132-
struct dentry *lower_dir_dentry;
133-
struct inode *lower_dir_inode;
130+
struct dentry *lower_dentry;
131+
struct inode *lower_dir;
134132
int rc;
135133

136-
lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
137-
lower_dir_inode = d_inode(lower_dir_dentry);
138-
inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
134+
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
139135
dget(lower_dentry); // don't even try to make the lower negative
140-
if (lower_dentry->d_parent != lower_dir_dentry)
141-
rc = -EINVAL;
142-
else if (d_unhashed(lower_dentry))
143-
rc = -EINVAL;
144-
else
145-
rc = vfs_unlink(&init_user_ns, lower_dir_inode, lower_dentry,
146-
NULL);
136+
if (!rc) {
137+
if (d_unhashed(lower_dentry))
138+
rc = -EINVAL;
139+
else
140+
rc = vfs_unlink(&init_user_ns, lower_dir, lower_dentry,
141+
NULL);
142+
}
147143
if (rc) {
148144
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
149145
goto out_unlock;
150146
}
151-
fsstack_copy_attr_times(dir, lower_dir_inode);
147+
fsstack_copy_attr_times(dir, lower_dir);
152148
set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
153149
inode->i_ctime = dir->i_ctime;
154150
out_unlock:
155151
dput(lower_dentry);
156-
inode_unlock(lower_dir_inode);
152+
inode_unlock(lower_dir);
157153
if (!rc)
158154
d_drop(dentry);
159155
return rc;
@@ -177,13 +173,13 @@ ecryptfs_do_create(struct inode *directory_inode,
177173
{
178174
int rc;
179175
struct dentry *lower_dentry;
180-
struct dentry *lower_dir_dentry;
176+
struct inode *lower_dir;
181177
struct inode *inode;
182178

183-
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
184-
lower_dir_dentry = lock_parent(lower_dentry);
185-
rc = vfs_create(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
186-
mode, true);
179+
rc = lock_parent(ecryptfs_dentry, &lower_dentry, &lower_dir);
180+
if (!rc)
181+
rc = vfs_create(&init_user_ns, lower_dir,
182+
lower_dentry, mode, true);
187183
if (rc) {
188184
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
189185
"rc = [%d]\n", __func__, rc);
@@ -193,14 +189,13 @@ ecryptfs_do_create(struct inode *directory_inode,
193189
inode = __ecryptfs_get_inode(d_inode(lower_dentry),
194190
directory_inode->i_sb);
195191
if (IS_ERR(inode)) {
196-
vfs_unlink(&init_user_ns, d_inode(lower_dir_dentry),
197-
lower_dentry, NULL);
192+
vfs_unlink(&init_user_ns, lower_dir, lower_dentry, NULL);
198193
goto out_lock;
199194
}
200-
fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry));
201-
fsstack_copy_inode_size(directory_inode, d_inode(lower_dir_dentry));
195+
fsstack_copy_attr_times(directory_inode, lower_dir);
196+
fsstack_copy_inode_size(directory_inode, lower_dir);
202197
out_lock:
203-
unlock_dir(lower_dir_dentry);
198+
inode_unlock(lower_dir);
204199
return inode;
205200
}
206201

@@ -431,32 +426,28 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
431426
{
432427
struct dentry *lower_old_dentry;
433428
struct dentry *lower_new_dentry;
434-
struct dentry *lower_dir_dentry;
429+
struct inode *lower_dir;
435430
u64 file_size_save;
436431
int rc;
437432

438433
file_size_save = i_size_read(d_inode(old_dentry));
439434
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
440-
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
441-
dget(lower_old_dentry);
442-
dget(lower_new_dentry);
443-
lower_dir_dentry = lock_parent(lower_new_dentry);
444-
rc = vfs_link(lower_old_dentry, &init_user_ns,
445-
d_inode(lower_dir_dentry), lower_new_dentry, NULL);
435+
rc = lock_parent(new_dentry, &lower_new_dentry, &lower_dir);
436+
if (!rc)
437+
rc = vfs_link(lower_old_dentry, &init_user_ns, lower_dir,
438+
lower_new_dentry, NULL);
446439
if (rc || d_really_is_negative(lower_new_dentry))
447440
goto out_lock;
448441
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
449442
if (rc)
450443
goto out_lock;
451-
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
452-
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
444+
fsstack_copy_attr_times(dir, lower_dir);
445+
fsstack_copy_inode_size(dir, lower_dir);
453446
set_nlink(d_inode(old_dentry),
454447
ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink);
455448
i_size_write(d_inode(new_dentry), file_size_save);
456449
out_lock:
457-
unlock_dir(lower_dir_dentry);
458-
dput(lower_new_dentry);
459-
dput(lower_old_dentry);
450+
inode_unlock(lower_dir);
460451
return rc;
461452
}
462453

@@ -471,14 +462,14 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
471462
{
472463
int rc;
473464
struct dentry *lower_dentry;
474-
struct dentry *lower_dir_dentry;
465+
struct inode *lower_dir;
475466
char *encoded_symname;
476467
size_t encoded_symlen;
477468
struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
478469

479-
lower_dentry = ecryptfs_dentry_to_lower(dentry);
480-
dget(lower_dentry);
481-
lower_dir_dentry = lock_parent(lower_dentry);
470+
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
471+
if (rc)
472+
goto out_lock;
482473
mount_crypt_stat = &ecryptfs_superblock_to_private(
483474
dir->i_sb)->mount_crypt_stat;
484475
rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname,
@@ -487,19 +478,18 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
487478
strlen(symname));
488479
if (rc)
489480
goto out_lock;
490-
rc = vfs_symlink(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
481+
rc = vfs_symlink(&init_user_ns, lower_dir, lower_dentry,
491482
encoded_symname);
492483
kfree(encoded_symname);
493484
if (rc || d_really_is_negative(lower_dentry))
494485
goto out_lock;
495486
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
496487
if (rc)
497488
goto out_lock;
498-
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
499-
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
489+
fsstack_copy_attr_times(dir, lower_dir);
490+
fsstack_copy_inode_size(dir, lower_dir);
500491
out_lock:
501-
unlock_dir(lower_dir_dentry);
502-
dput(lower_dentry);
492+
inode_unlock(lower_dir);
503493
if (d_really_is_negative(dentry))
504494
d_drop(dentry);
505495
return rc;
@@ -510,22 +500,22 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
510500
{
511501
int rc;
512502
struct dentry *lower_dentry;
513-
struct dentry *lower_dir_dentry;
503+
struct inode *lower_dir;
514504

515-
lower_dentry = ecryptfs_dentry_to_lower(dentry);
516-
lower_dir_dentry = lock_parent(lower_dentry);
517-
rc = vfs_mkdir(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
518-
mode);
505+
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
506+
if (!rc)
507+
rc = vfs_mkdir(&init_user_ns, lower_dir,
508+
lower_dentry, mode);
519509
if (rc || d_really_is_negative(lower_dentry))
520510
goto out;
521511
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
522512
if (rc)
523513
goto out;
524-
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
525-
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
526-
set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
514+
fsstack_copy_attr_times(dir, lower_dir);
515+
fsstack_copy_inode_size(dir, lower_dir);
516+
set_nlink(dir, lower_dir->i_nlink);
527517
out:
528-
unlock_dir(lower_dir_dentry);
518+
inode_unlock(lower_dir);
529519
if (d_really_is_negative(dentry))
530520
d_drop(dentry);
531521
return rc;
@@ -534,29 +524,24 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
534524
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
535525
{
536526
struct dentry *lower_dentry;
537-
struct dentry *lower_dir_dentry;
538-
struct inode *lower_dir_inode;
527+
struct inode *lower_dir;
539528
int rc;
540529

541-
lower_dentry = ecryptfs_dentry_to_lower(dentry);
542-
lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
543-
lower_dir_inode = d_inode(lower_dir_dentry);
544-
545-
inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
530+
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
546531
dget(lower_dentry); // don't even try to make the lower negative
547-
if (lower_dentry->d_parent != lower_dir_dentry)
548-
rc = -EINVAL;
549-
else if (d_unhashed(lower_dentry))
550-
rc = -EINVAL;
551-
else
552-
rc = vfs_rmdir(&init_user_ns, lower_dir_inode, lower_dentry);
532+
if (!rc) {
533+
if (d_unhashed(lower_dentry))
534+
rc = -EINVAL;
535+
else
536+
rc = vfs_rmdir(&init_user_ns, lower_dir, lower_dentry);
537+
}
553538
if (!rc) {
554539
clear_nlink(d_inode(dentry));
555-
fsstack_copy_attr_times(dir, lower_dir_inode);
556-
set_nlink(dir, lower_dir_inode->i_nlink);
540+
fsstack_copy_attr_times(dir, lower_dir);
541+
set_nlink(dir, lower_dir->i_nlink);
557542
}
558543
dput(lower_dentry);
559-
inode_unlock(lower_dir_inode);
544+
inode_unlock(lower_dir);
560545
if (!rc)
561546
d_drop(dentry);
562547
return rc;
@@ -568,21 +553,21 @@ ecryptfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
568553
{
569554
int rc;
570555
struct dentry *lower_dentry;
571-
struct dentry *lower_dir_dentry;
556+
struct inode *lower_dir;
572557

573-
lower_dentry = ecryptfs_dentry_to_lower(dentry);
574-
lower_dir_dentry = lock_parent(lower_dentry);
575-
rc = vfs_mknod(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
576-
mode, dev);
558+
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
559+
if (!rc)
560+
rc = vfs_mknod(&init_user_ns, lower_dir,
561+
lower_dentry, mode, dev);
577562
if (rc || d_really_is_negative(lower_dentry))
578563
goto out;
579564
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
580565
if (rc)
581566
goto out;
582-
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
583-
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
567+
fsstack_copy_attr_times(dir, lower_dir);
568+
fsstack_copy_inode_size(dir, lower_dir);
584569
out:
585-
unlock_dir(lower_dir_dentry);
570+
inode_unlock(lower_dir);
586571
if (d_really_is_negative(dentry))
587572
d_drop(dentry);
588573
return rc;

0 commit comments

Comments
 (0)