22
22
#include <asm/unaligned.h>
23
23
#include "ecryptfs_kernel.h"
24
24
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 )
26
28
{
27
- struct dentry * dir ;
29
+ struct dentry * lower_dir_dentry ;
28
30
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 );
33
34
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 ;
38
37
}
39
38
40
39
static int ecryptfs_inode_test (struct inode * inode , void * lower_inode )
@@ -128,32 +127,29 @@ static int ecryptfs_interpose(struct dentry *lower_dentry,
128
127
static int ecryptfs_do_unlink (struct inode * dir , struct dentry * dentry ,
129
128
struct inode * inode )
130
129
{
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 ;
134
132
int rc ;
135
133
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 );
139
135
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
+ }
147
143
if (rc ) {
148
144
printk (KERN_ERR "Error in vfs_unlink; rc = [%d]\n" , rc );
149
145
goto out_unlock ;
150
146
}
151
- fsstack_copy_attr_times (dir , lower_dir_inode );
147
+ fsstack_copy_attr_times (dir , lower_dir );
152
148
set_nlink (inode , ecryptfs_inode_to_lower (inode )-> i_nlink );
153
149
inode -> i_ctime = dir -> i_ctime ;
154
150
out_unlock :
155
151
dput (lower_dentry );
156
- inode_unlock (lower_dir_inode );
152
+ inode_unlock (lower_dir );
157
153
if (!rc )
158
154
d_drop (dentry );
159
155
return rc ;
@@ -177,13 +173,13 @@ ecryptfs_do_create(struct inode *directory_inode,
177
173
{
178
174
int rc ;
179
175
struct dentry * lower_dentry ;
180
- struct dentry * lower_dir_dentry ;
176
+ struct inode * lower_dir ;
181
177
struct inode * inode ;
182
178
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);
187
183
if (rc ) {
188
184
printk (KERN_ERR "%s: Failure to create dentry in lower fs; "
189
185
"rc = [%d]\n" , __func__ , rc );
@@ -193,14 +189,13 @@ ecryptfs_do_create(struct inode *directory_inode,
193
189
inode = __ecryptfs_get_inode (d_inode (lower_dentry ),
194
190
directory_inode -> i_sb );
195
191
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 );
198
193
goto out_lock ;
199
194
}
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 );
202
197
out_lock :
203
- unlock_dir ( lower_dir_dentry );
198
+ inode_unlock ( lower_dir );
204
199
return inode ;
205
200
}
206
201
@@ -431,32 +426,28 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
431
426
{
432
427
struct dentry * lower_old_dentry ;
433
428
struct dentry * lower_new_dentry ;
434
- struct dentry * lower_dir_dentry ;
429
+ struct inode * lower_dir ;
435
430
u64 file_size_save ;
436
431
int rc ;
437
432
438
433
file_size_save = i_size_read (d_inode (old_dentry ));
439
434
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 );
446
439
if (rc || d_really_is_negative (lower_new_dentry ))
447
440
goto out_lock ;
448
441
rc = ecryptfs_interpose (lower_new_dentry , new_dentry , dir -> i_sb );
449
442
if (rc )
450
443
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 );
453
446
set_nlink (d_inode (old_dentry ),
454
447
ecryptfs_inode_to_lower (d_inode (old_dentry ))-> i_nlink );
455
448
i_size_write (d_inode (new_dentry ), file_size_save );
456
449
out_lock :
457
- unlock_dir (lower_dir_dentry );
458
- dput (lower_new_dentry );
459
- dput (lower_old_dentry );
450
+ inode_unlock (lower_dir );
460
451
return rc ;
461
452
}
462
453
@@ -471,14 +462,14 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
471
462
{
472
463
int rc ;
473
464
struct dentry * lower_dentry ;
474
- struct dentry * lower_dir_dentry ;
465
+ struct inode * lower_dir ;
475
466
char * encoded_symname ;
476
467
size_t encoded_symlen ;
477
468
struct ecryptfs_mount_crypt_stat * mount_crypt_stat = NULL ;
478
469
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 ;
482
473
mount_crypt_stat = & ecryptfs_superblock_to_private (
483
474
dir -> i_sb )-> mount_crypt_stat ;
484
475
rc = ecryptfs_encrypt_and_encode_filename (& encoded_symname ,
@@ -487,19 +478,18 @@ static int ecryptfs_symlink(struct user_namespace *mnt_userns,
487
478
strlen (symname ));
488
479
if (rc )
489
480
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 ,
491
482
encoded_symname );
492
483
kfree (encoded_symname );
493
484
if (rc || d_really_is_negative (lower_dentry ))
494
485
goto out_lock ;
495
486
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
496
487
if (rc )
497
488
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 );
500
491
out_lock :
501
- unlock_dir (lower_dir_dentry );
502
- dput (lower_dentry );
492
+ inode_unlock (lower_dir );
503
493
if (d_really_is_negative (dentry ))
504
494
d_drop (dentry );
505
495
return rc ;
@@ -510,22 +500,22 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
510
500
{
511
501
int rc ;
512
502
struct dentry * lower_dentry ;
513
- struct dentry * lower_dir_dentry ;
503
+ struct inode * lower_dir ;
514
504
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 );
519
509
if (rc || d_really_is_negative (lower_dentry ))
520
510
goto out ;
521
511
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
522
512
if (rc )
523
513
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 );
527
517
out :
528
- unlock_dir ( lower_dir_dentry );
518
+ inode_unlock ( lower_dir );
529
519
if (d_really_is_negative (dentry ))
530
520
d_drop (dentry );
531
521
return rc ;
@@ -534,29 +524,24 @@ static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
534
524
static int ecryptfs_rmdir (struct inode * dir , struct dentry * dentry )
535
525
{
536
526
struct dentry * lower_dentry ;
537
- struct dentry * lower_dir_dentry ;
538
- struct inode * lower_dir_inode ;
527
+ struct inode * lower_dir ;
539
528
int rc ;
540
529
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 );
546
531
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
+ }
553
538
if (!rc ) {
554
539
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 );
557
542
}
558
543
dput (lower_dentry );
559
- inode_unlock (lower_dir_inode );
544
+ inode_unlock (lower_dir );
560
545
if (!rc )
561
546
d_drop (dentry );
562
547
return rc ;
@@ -568,21 +553,21 @@ ecryptfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
568
553
{
569
554
int rc ;
570
555
struct dentry * lower_dentry ;
571
- struct dentry * lower_dir_dentry ;
556
+ struct inode * lower_dir ;
572
557
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 );
577
562
if (rc || d_really_is_negative (lower_dentry ))
578
563
goto out ;
579
564
rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
580
565
if (rc )
581
566
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 );
584
569
out :
585
- unlock_dir ( lower_dir_dentry );
570
+ inode_unlock ( lower_dir );
586
571
if (d_really_is_negative (dentry ))
587
572
d_drop (dentry );
588
573
return rc ;
0 commit comments