21
21
#include <asm/unaligned.h>
22
22
#include "ecryptfs_kernel.h"
23
23
24
- static struct dentry * lock_parent (struct dentry * dentry )
24
+ static int lock_parent (struct dentry * dentry ,
25
+ struct dentry * * lower_dentry ,
26
+ struct inode * * lower_dir )
25
27
{
26
- struct dentry * dir ;
28
+ struct dentry * lower_dir_dentry ;
27
29
28
- dir = dget_parent (dentry );
29
- inode_lock_nested (d_inode (dir ), I_MUTEX_PARENT );
30
- return dir ;
31
- }
30
+ lower_dir_dentry = ecryptfs_dentry_to_lower (dentry -> d_parent );
31
+ * lower_dir = d_inode (lower_dir_dentry );
32
+ * lower_dentry = ecryptfs_dentry_to_lower (dentry );
32
33
33
- static void unlock_dir (struct dentry * dir )
34
- {
35
- inode_unlock (d_inode (dir ));
36
- dput (dir );
34
+ inode_lock_nested (* lower_dir , I_MUTEX_PARENT );
35
+ return (* lower_dentry )-> d_parent == lower_dir_dentry ? 0 : - EINVAL ;
37
36
}
38
37
39
38
static int ecryptfs_inode_test (struct inode * inode , void * lower_inode )
@@ -127,32 +126,29 @@ static int ecryptfs_interpose(struct dentry *lower_dentry,
127
126
static int ecryptfs_do_unlink (struct inode * dir , struct dentry * dentry ,
128
127
struct inode * inode )
129
128
{
130
- struct dentry * lower_dentry = ecryptfs_dentry_to_lower (dentry );
131
- struct dentry * lower_dir_dentry ;
132
- struct inode * lower_dir_inode ;
129
+ struct dentry * lower_dentry ;
130
+ struct inode * lower_dir ;
133
131
int rc ;
134
132
135
- lower_dir_dentry = ecryptfs_dentry_to_lower (dentry -> d_parent );
136
- lower_dir_inode = d_inode (lower_dir_dentry );
137
- inode_lock_nested (lower_dir_inode , I_MUTEX_PARENT );
133
+ rc = lock_parent (dentry , & lower_dentry , & lower_dir );
138
134
dget (lower_dentry ); // don't even try to make the lower negative
139
- if (lower_dentry -> d_parent != lower_dir_dentry )
140
- rc = - EINVAL ;
141
- else if ( d_unhashed ( lower_dentry ))
142
- rc = - EINVAL ;
143
- else
144
- rc = vfs_unlink ( & init_user_ns , lower_dir_inode , lower_dentry ,
145
- NULL );
135
+ if (! rc ) {
136
+ if ( d_unhashed ( lower_dentry ))
137
+ rc = - EINVAL ;
138
+ else
139
+ rc = vfs_unlink ( & init_user_ns , lower_dir , lower_dentry ,
140
+ NULL );
141
+ }
146
142
if (rc ) {
147
143
printk (KERN_ERR "Error in vfs_unlink; rc = [%d]\n" , rc );
148
144
goto out_unlock ;
149
145
}
150
- fsstack_copy_attr_times (dir , lower_dir_inode );
146
+ fsstack_copy_attr_times (dir , lower_dir );
151
147
set_nlink (inode , ecryptfs_inode_to_lower (inode )-> i_nlink );
152
148
inode -> i_ctime = dir -> i_ctime ;
153
149
out_unlock :
154
150
dput (lower_dentry );
155
- inode_unlock (lower_dir_inode );
151
+ inode_unlock (lower_dir );
156
152
if (!rc )
157
153
d_drop (dentry );
158
154
return rc ;
@@ -176,13 +172,13 @@ ecryptfs_do_create(struct inode *directory_inode,
176
172
{
177
173
int rc ;
178
174
struct dentry * lower_dentry ;
179
- struct dentry * lower_dir_dentry ;
175
+ struct inode * lower_dir ;
180
176
struct inode * inode ;
181
177
182
- lower_dentry = ecryptfs_dentry_to_lower (ecryptfs_dentry );
183
- lower_dir_dentry = lock_parent ( lower_dentry );
184
- rc = vfs_create (& init_user_ns , d_inode ( lower_dir_dentry ), lower_dentry ,
185
- mode , true);
178
+ rc = lock_parent (ecryptfs_dentry , & lower_dentry , & lower_dir );
179
+ if (! rc )
180
+ rc = vfs_create (& init_user_ns , lower_dir ,
181
+ lower_dentry , mode , true);
186
182
if (rc ) {
187
183
printk (KERN_ERR "%s: Failure to create dentry in lower fs; "
188
184
"rc = [%d]\n" , __func__ , rc );
@@ -192,14 +188,13 @@ ecryptfs_do_create(struct inode *directory_inode,
192
188
inode = __ecryptfs_get_inode (d_inode (lower_dentry ),
193
189
directory_inode -> i_sb );
194
190
if (IS_ERR (inode )) {
195
- vfs_unlink (& init_user_ns , d_inode (lower_dir_dentry ),
196
- lower_dentry , NULL );
191
+ vfs_unlink (& init_user_ns , lower_dir , lower_dentry , NULL );
197
192
goto out_lock ;
198
193
}
199
- fsstack_copy_attr_times (directory_inode , d_inode ( lower_dir_dentry ) );
200
- fsstack_copy_inode_size (directory_inode , d_inode ( lower_dir_dentry ) );
194
+ fsstack_copy_attr_times (directory_inode , lower_dir );
195
+ fsstack_copy_inode_size (directory_inode , lower_dir );
201
196
out_lock :
202
- unlock_dir ( lower_dir_dentry );
197
+ inode_unlock ( lower_dir );
203
198
return inode ;
204
199
}
205
200
@@ -430,28 +425,28 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
430
425
{
431
426
struct dentry * lower_old_dentry ;
432
427
struct dentry * lower_new_dentry ;
433
- struct dentry * lower_dir_dentry ;
428
+ struct inode * lower_dir ;
434
429
u64 file_size_save ;
435
430
int rc ;
436
431
437
432
file_size_save = i_size_read (d_inode (old_dentry ));
438
433
lower_old_dentry = ecryptfs_dentry_to_lower (old_dentry );
439
- lower_new_dentry = ecryptfs_dentry_to_lower (new_dentry );
440
- lower_dir_dentry = lock_parent ( lower_new_dentry );
441
- rc = vfs_link (lower_old_dentry , & init_user_ns ,
442
- d_inode ( lower_dir_dentry ), lower_new_dentry , NULL );
434
+ rc = lock_parent (new_dentry , & lower_new_dentry , & lower_dir );
435
+ if (! rc )
436
+ rc = vfs_link (lower_old_dentry , & init_user_ns , lower_dir ,
437
+ lower_new_dentry , NULL );
443
438
if (rc || d_really_is_negative (lower_new_dentry ))
444
439
goto out_lock ;
445
440
rc = ecryptfs_interpose (lower_new_dentry , new_dentry , dir -> i_sb );
446
441
if (rc )
447
442
goto out_lock ;
448
- fsstack_copy_attr_times (dir , d_inode ( lower_dir_dentry ) );
449
- fsstack_copy_inode_size (dir , d_inode ( lower_dir_dentry ) );
443
+ fsstack_copy_attr_times (dir , lower_dir );
444
+ fsstack_copy_inode_size (dir , lower_dir );
450
445
set_nlink (d_inode (old_dentry ),
451
446
ecryptfs_inode_to_lower (d_inode (old_dentry ))-> i_nlink );
452
447
i_size_write (d_inode (new_dentry ), file_size_save );
453
448
out_lock :
454
- unlock_dir ( lower_dir_dentry );
449
+ inode_unlock ( lower_dir );
455
450
return rc ;
456
451
}
457
452
@@ -466,13 +461,14 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
466
461
{
467
462
int rc ;
468
463
struct dentry * lower_dentry ;
469
- struct dentry * lower_dir_dentry ;
464
+ struct inode * lower_dir ;
470
465
char * encoded_symname ;
471
466
size_t encoded_symlen ;
472
467
struct ecryptfs_mount_crypt_stat * mount_crypt_stat = NULL ;
473
468
474
- lower_dentry = ecryptfs_dentry_to_lower (dentry );
475
- lower_dir_dentry = lock_parent (lower_dentry );
469
+ rc = lock_parent (dentry , & lower_dentry , & lower_dir );
470
+ if (rc )
471
+ goto out_lock ;
476
472
mount_crypt_stat = & ecryptfs_superblock_to_private (
477
473
dir -> i_sb )-> mount_crypt_stat ;
478
474
rc = ecryptfs_encrypt_and_encode_filename (& encoded_symname ,
@@ -481,18 +477,18 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
481
477
strlen (symname ));
482
478
if (rc )
483
479
goto out_lock ;
484
- rc = vfs_symlink (& init_user_ns , d_inode ( lower_dir_dentry ) , lower_dentry ,
480
+ rc = vfs_symlink (& init_user_ns , lower_dir , lower_dentry ,
485
481
encoded_symname );
486
482
kfree (encoded_symname );
487
483
if (rc || d_really_is_negative (lower_dentry ))
488
484
goto out_lock ;
489
485
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
490
486
if (rc )
491
487
goto out_lock ;
492
- fsstack_copy_attr_times (dir , d_inode ( lower_dir_dentry ) );
493
- fsstack_copy_inode_size (dir , d_inode ( lower_dir_dentry ) );
488
+ fsstack_copy_attr_times (dir , lower_dir );
489
+ fsstack_copy_inode_size (dir , lower_dir );
494
490
out_lock :
495
- unlock_dir ( lower_dir_dentry );
491
+ inode_unlock ( lower_dir );
496
492
if (d_really_is_negative (dentry ))
497
493
d_drop (dentry );
498
494
return rc ;
@@ -503,22 +499,22 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
503
499
{
504
500
int rc ;
505
501
struct dentry * lower_dentry ;
506
- struct dentry * lower_dir_dentry ;
502
+ struct inode * lower_dir ;
507
503
508
- lower_dentry = ecryptfs_dentry_to_lower (dentry );
509
- lower_dir_dentry = lock_parent ( lower_dentry );
510
- rc = vfs_mkdir (& init_user_ns , d_inode ( lower_dir_dentry ), lower_dentry ,
511
- mode );
504
+ rc = lock_parent (dentry , & lower_dentry , & lower_dir );
505
+ if (! rc )
506
+ rc = vfs_mkdir (& init_user_ns , lower_dir ,
507
+ lower_dentry , mode );
512
508
if (rc || d_really_is_negative (lower_dentry ))
513
509
goto out ;
514
510
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
515
511
if (rc )
516
512
goto out ;
517
- fsstack_copy_attr_times (dir , d_inode ( lower_dir_dentry ) );
518
- fsstack_copy_inode_size (dir , d_inode ( lower_dir_dentry ) );
519
- set_nlink (dir , d_inode ( lower_dir_dentry ) -> i_nlink );
513
+ fsstack_copy_attr_times (dir , lower_dir );
514
+ fsstack_copy_inode_size (dir , lower_dir );
515
+ set_nlink (dir , lower_dir -> i_nlink );
520
516
out :
521
- unlock_dir ( lower_dir_dentry );
517
+ inode_unlock ( lower_dir );
522
518
if (d_really_is_negative (dentry ))
523
519
d_drop (dentry );
524
520
return rc ;
@@ -527,29 +523,24 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
527
523
static int ecryptfs_rmdir (struct inode * dir , struct dentry * dentry )
528
524
{
529
525
struct dentry * lower_dentry ;
530
- struct dentry * lower_dir_dentry ;
531
- struct inode * lower_dir_inode ;
526
+ struct inode * lower_dir ;
532
527
int rc ;
533
528
534
- lower_dentry = ecryptfs_dentry_to_lower (dentry );
535
- lower_dir_dentry = ecryptfs_dentry_to_lower (dentry -> d_parent );
536
- lower_dir_inode = d_inode (lower_dir_dentry );
537
-
538
- inode_lock_nested (lower_dir_inode , I_MUTEX_PARENT );
529
+ rc = lock_parent (dentry , & lower_dentry , & lower_dir );
539
530
dget (lower_dentry ); // don't even try to make the lower negative
540
- if (lower_dentry -> d_parent != lower_dir_dentry )
541
- rc = - EINVAL ;
542
- else if ( d_unhashed ( lower_dentry ))
543
- rc = - EINVAL ;
544
- else
545
- rc = vfs_rmdir ( & init_user_ns , lower_dir_inode , lower_dentry );
531
+ if (! rc ) {
532
+ if ( d_unhashed ( lower_dentry ))
533
+ rc = - EINVAL ;
534
+ else
535
+ rc = vfs_rmdir ( & init_user_ns , lower_dir , lower_dentry );
536
+ }
546
537
if (!rc ) {
547
538
clear_nlink (d_inode (dentry ));
548
- fsstack_copy_attr_times (dir , lower_dir_inode );
549
- set_nlink (dir , lower_dir_inode -> i_nlink );
539
+ fsstack_copy_attr_times (dir , lower_dir );
540
+ set_nlink (dir , lower_dir -> i_nlink );
550
541
}
551
542
dput (lower_dentry );
552
- inode_unlock (lower_dir_inode );
543
+ inode_unlock (lower_dir );
553
544
if (!rc )
554
545
d_drop (dentry );
555
546
return rc ;
@@ -561,21 +552,21 @@ ecryptfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
561
552
{
562
553
int rc ;
563
554
struct dentry * lower_dentry ;
564
- struct dentry * lower_dir_dentry ;
555
+ struct inode * lower_dir ;
565
556
566
- lower_dentry = ecryptfs_dentry_to_lower (dentry );
567
- lower_dir_dentry = lock_parent ( lower_dentry );
568
- rc = vfs_mknod (& init_user_ns , d_inode ( lower_dir_dentry ), lower_dentry ,
569
- mode , dev );
557
+ rc = lock_parent (dentry , & lower_dentry , & lower_dir );
558
+ if (! rc )
559
+ rc = vfs_mknod (& init_user_ns , lower_dir ,
560
+ lower_dentry , mode , dev );
570
561
if (rc || d_really_is_negative (lower_dentry ))
571
562
goto out ;
572
563
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
573
564
if (rc )
574
565
goto out ;
575
- fsstack_copy_attr_times (dir , d_inode ( lower_dir_dentry ) );
576
- fsstack_copy_inode_size (dir , d_inode ( lower_dir_dentry ) );
566
+ fsstack_copy_attr_times (dir , lower_dir );
567
+ fsstack_copy_inode_size (dir , lower_dir );
577
568
out :
578
- unlock_dir ( lower_dir_dentry );
569
+ inode_unlock ( lower_dir );
579
570
if (d_really_is_negative (dentry ))
580
571
d_drop (dentry );
581
572
return rc ;
0 commit comments