2424#include <linux/unaligned.h>
2525#include "ecryptfs_kernel.h"
2626
27- static int lock_parent (struct dentry * dentry ,
28- struct dentry * * lower_dentry ,
29- struct inode * * lower_dir )
27+ static struct dentry * ecryptfs_start_creating_dentry (struct dentry * dentry )
3028{
31- struct dentry * lower_dir_dentry ;
29+ struct dentry * parent = dget_parent (dentry );
30+ struct dentry * ret ;
3231
33- lower_dir_dentry = ecryptfs_dentry_to_lower (dentry -> d_parent );
34- * lower_dir = d_inode (lower_dir_dentry );
35- * lower_dentry = ecryptfs_dentry_to_lower (dentry );
32+ ret = start_creating_dentry (ecryptfs_dentry_to_lower (parent ),
33+ ecryptfs_dentry_to_lower (dentry ));
34+ dput (parent );
35+ return ret ;
36+ }
3637
37- inode_lock_nested (* lower_dir , I_MUTEX_PARENT );
38- return (* lower_dentry )-> d_parent == lower_dir_dentry ? 0 : - EINVAL ;
38+ static struct dentry * ecryptfs_start_removing_dentry (struct dentry * dentry )
39+ {
40+ struct dentry * parent = dget_parent (dentry );
41+ struct dentry * ret ;
42+
43+ ret = start_removing_dentry (ecryptfs_dentry_to_lower (parent ),
44+ ecryptfs_dentry_to_lower (dentry ));
45+ dput (parent );
46+ return ret ;
3947}
4048
4149static int ecryptfs_inode_test (struct inode * inode , void * lower_inode )
@@ -141,15 +149,12 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
141149 struct inode * lower_dir ;
142150 int rc ;
143151
144- rc = lock_parent (dentry , & lower_dentry , & lower_dir );
145- dget (lower_dentry ); // don't even try to make the lower negative
146- if (!rc ) {
147- if (d_unhashed (lower_dentry ))
148- rc = - EINVAL ;
149- else
150- rc = vfs_unlink (& nop_mnt_idmap , lower_dir , lower_dentry ,
151- NULL );
152- }
152+ lower_dentry = ecryptfs_start_removing_dentry (dentry );
153+ if (IS_ERR (lower_dentry ))
154+ return PTR_ERR (lower_dentry );
155+
156+ lower_dir = lower_dentry -> d_parent -> d_inode ;
157+ rc = vfs_unlink (& nop_mnt_idmap , lower_dir , lower_dentry , NULL );
153158 if (rc ) {
154159 printk (KERN_ERR "Error in vfs_unlink; rc = [%d]\n" , rc );
155160 goto out_unlock ;
@@ -158,8 +163,7 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
158163 set_nlink (inode , ecryptfs_inode_to_lower (inode )-> i_nlink );
159164 inode_set_ctime_to_ts (inode , inode_get_ctime (dir ));
160165out_unlock :
161- dput (lower_dentry );
162- inode_unlock (lower_dir );
166+ end_removing (lower_dentry );
163167 if (!rc )
164168 d_drop (dentry );
165169 return rc ;
@@ -186,10 +190,12 @@ ecryptfs_do_create(struct inode *directory_inode,
186190 struct inode * lower_dir ;
187191 struct inode * inode ;
188192
189- rc = lock_parent (ecryptfs_dentry , & lower_dentry , & lower_dir );
190- if (!rc )
191- rc = vfs_create (& nop_mnt_idmap , lower_dir ,
192- lower_dentry , mode , true);
193+ lower_dentry = ecryptfs_start_creating_dentry (ecryptfs_dentry );
194+ if (IS_ERR (lower_dentry ))
195+ return ERR_CAST (lower_dentry );
196+ lower_dir = lower_dentry -> d_parent -> d_inode ;
197+ rc = vfs_create (& nop_mnt_idmap , lower_dir ,
198+ lower_dentry , mode , true);
193199 if (rc ) {
194200 printk (KERN_ERR "%s: Failure to create dentry in lower fs; "
195201 "rc = [%d]\n" , __func__ , rc );
@@ -205,7 +211,7 @@ ecryptfs_do_create(struct inode *directory_inode,
205211 fsstack_copy_attr_times (directory_inode , lower_dir );
206212 fsstack_copy_inode_size (directory_inode , lower_dir );
207213out_lock :
208- inode_unlock ( lower_dir );
214+ end_creating ( lower_dentry , NULL );
209215 return inode ;
210216}
211217
@@ -433,10 +439,12 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
433439
434440 file_size_save = i_size_read (d_inode (old_dentry ));
435441 lower_old_dentry = ecryptfs_dentry_to_lower (old_dentry );
436- rc = lock_parent (new_dentry , & lower_new_dentry , & lower_dir );
437- if (!rc )
438- rc = vfs_link (lower_old_dentry , & nop_mnt_idmap , lower_dir ,
439- lower_new_dentry , NULL );
442+ lower_new_dentry = ecryptfs_start_creating_dentry (new_dentry );
443+ if (IS_ERR (lower_new_dentry ))
444+ return PTR_ERR (lower_new_dentry );
445+ lower_dir = lower_new_dentry -> d_parent -> d_inode ;
446+ rc = vfs_link (lower_old_dentry , & nop_mnt_idmap , lower_dir ,
447+ lower_new_dentry , NULL );
440448 if (rc || d_really_is_negative (lower_new_dentry ))
441449 goto out_lock ;
442450 rc = ecryptfs_interpose (lower_new_dentry , new_dentry , dir -> i_sb );
@@ -448,7 +456,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
448456 ecryptfs_inode_to_lower (d_inode (old_dentry ))-> i_nlink );
449457 i_size_write (d_inode (new_dentry ), file_size_save );
450458out_lock :
451- inode_unlock ( lower_dir );
459+ end_creating ( lower_new_dentry , NULL );
452460 return rc ;
453461}
454462
@@ -468,9 +476,11 @@ static int ecryptfs_symlink(struct mnt_idmap *idmap,
468476 size_t encoded_symlen ;
469477 struct ecryptfs_mount_crypt_stat * mount_crypt_stat = NULL ;
470478
471- rc = lock_parent (dentry , & lower_dentry , & lower_dir );
472- if (rc )
473- goto out_lock ;
479+ lower_dentry = ecryptfs_start_creating_dentry (dentry );
480+ if (IS_ERR (lower_dentry ))
481+ return PTR_ERR (lower_dentry );
482+ lower_dir = lower_dentry -> d_parent -> d_inode ;
483+
474484 mount_crypt_stat = & ecryptfs_superblock_to_private (
475485 dir -> i_sb )-> mount_crypt_stat ;
476486 rc = ecryptfs_encrypt_and_encode_filename (& encoded_symname ,
@@ -490,7 +500,7 @@ static int ecryptfs_symlink(struct mnt_idmap *idmap,
490500 fsstack_copy_attr_times (dir , lower_dir );
491501 fsstack_copy_inode_size (dir , lower_dir );
492502out_lock :
493- inode_unlock ( lower_dir );
503+ end_creating ( lower_dentry , NULL );
494504 if (d_really_is_negative (dentry ))
495505 d_drop (dentry );
496506 return rc ;
@@ -501,12 +511,14 @@ static struct dentry *ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
501511{
502512 int rc ;
503513 struct dentry * lower_dentry ;
514+ struct dentry * lower_dir_dentry ;
504515 struct inode * lower_dir ;
505516
506- rc = lock_parent (dentry , & lower_dentry , & lower_dir );
507- if (rc )
508- goto out ;
509-
517+ lower_dentry = ecryptfs_start_creating_dentry (dentry );
518+ if (IS_ERR (lower_dentry ))
519+ return lower_dentry ;
520+ lower_dir_dentry = dget (lower_dentry -> d_parent );
521+ lower_dir = lower_dir_dentry -> d_inode ;
510522 lower_dentry = vfs_mkdir (& nop_mnt_idmap , lower_dir ,
511523 lower_dentry , mode );
512524 rc = PTR_ERR (lower_dentry );
@@ -522,7 +534,7 @@ static struct dentry *ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
522534 fsstack_copy_inode_size (dir , lower_dir );
523535 set_nlink (dir , lower_dir -> i_nlink );
524536out :
525- inode_unlock ( lower_dir );
537+ end_creating ( lower_dentry , lower_dir_dentry );
526538 if (d_really_is_negative (dentry ))
527539 d_drop (dentry );
528540 return ERR_PTR (rc );
@@ -534,21 +546,18 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
534546 struct inode * lower_dir ;
535547 int rc ;
536548
537- rc = lock_parent (dentry , & lower_dentry , & lower_dir );
538- dget (lower_dentry ); // don't even try to make the lower negative
539- if (!rc ) {
540- if (d_unhashed (lower_dentry ))
541- rc = - EINVAL ;
542- else
543- rc = vfs_rmdir (& nop_mnt_idmap , lower_dir , lower_dentry );
544- }
549+ lower_dentry = ecryptfs_start_removing_dentry (dentry );
550+ if (IS_ERR (lower_dentry ))
551+ return PTR_ERR (lower_dentry );
552+ lower_dir = lower_dentry -> d_parent -> d_inode ;
553+
554+ rc = vfs_rmdir (& nop_mnt_idmap , lower_dir , lower_dentry );
545555 if (!rc ) {
546556 clear_nlink (d_inode (dentry ));
547557 fsstack_copy_attr_times (dir , lower_dir );
548558 set_nlink (dir , lower_dir -> i_nlink );
549559 }
550- dput (lower_dentry );
551- inode_unlock (lower_dir );
560+ end_removing (lower_dentry );
552561 if (!rc )
553562 d_drop (dentry );
554563 return rc ;
@@ -562,10 +571,12 @@ ecryptfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
562571 struct dentry * lower_dentry ;
563572 struct inode * lower_dir ;
564573
565- rc = lock_parent (dentry , & lower_dentry , & lower_dir );
566- if (!rc )
567- rc = vfs_mknod (& nop_mnt_idmap , lower_dir ,
568- lower_dentry , mode , dev );
574+ lower_dentry = ecryptfs_start_creating_dentry (dentry );
575+ if (IS_ERR (lower_dentry ))
576+ return PTR_ERR (lower_dentry );
577+ lower_dir = lower_dentry -> d_parent -> d_inode ;
578+
579+ rc = vfs_mknod (& nop_mnt_idmap , lower_dir , lower_dentry , mode , dev );
569580 if (rc || d_really_is_negative (lower_dentry ))
570581 goto out ;
571582 rc = ecryptfs_interpose (lower_dentry , dentry , dir -> i_sb );
@@ -574,7 +585,7 @@ ecryptfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
574585 fsstack_copy_attr_times (dir , lower_dir );
575586 fsstack_copy_inode_size (dir , lower_dir );
576587out :
577- inode_unlock ( lower_dir );
588+ end_removing ( lower_dentry );
578589 if (d_really_is_negative (dentry ))
579590 d_drop (dentry );
580591 return rc ;
@@ -590,7 +601,6 @@ ecryptfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
590601 struct dentry * lower_new_dentry ;
591602 struct dentry * lower_old_dir_dentry ;
592603 struct dentry * lower_new_dir_dentry ;
593- struct dentry * trap ;
594604 struct inode * target_inode ;
595605 struct renamedata rd = {};
596606
@@ -605,31 +615,13 @@ ecryptfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
605615
606616 target_inode = d_inode (new_dentry );
607617
608- trap = lock_rename (lower_old_dir_dentry , lower_new_dir_dentry );
609- if (IS_ERR (trap ))
610- return PTR_ERR (trap );
611- dget (lower_new_dentry );
612- rc = - EINVAL ;
613- if (lower_old_dentry -> d_parent != lower_old_dir_dentry )
614- goto out_lock ;
615- if (lower_new_dentry -> d_parent != lower_new_dir_dentry )
616- goto out_lock ;
617- if (d_unhashed (lower_old_dentry ) || d_unhashed (lower_new_dentry ))
618- goto out_lock ;
619- /* source should not be ancestor of target */
620- if (trap == lower_old_dentry )
621- goto out_lock ;
622- /* target should not be ancestor of source */
623- if (trap == lower_new_dentry ) {
624- rc = - ENOTEMPTY ;
625- goto out_lock ;
626- }
618+ rd .mnt_idmap = & nop_mnt_idmap ;
619+ rd .old_parent = lower_old_dir_dentry ;
620+ rd .new_parent = lower_new_dir_dentry ;
621+ rc = start_renaming_two_dentries (& rd , lower_old_dentry , lower_new_dentry );
622+ if (rc )
623+ return rc ;
627624
628- rd .mnt_idmap = & nop_mnt_idmap ;
629- rd .old_parent = lower_old_dir_dentry ;
630- rd .old_dentry = lower_old_dentry ;
631- rd .new_parent = lower_new_dir_dentry ;
632- rd .new_dentry = lower_new_dentry ;
633625 rc = vfs_rename (& rd );
634626 if (rc )
635627 goto out_lock ;
@@ -640,8 +632,7 @@ ecryptfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
640632 if (new_dir != old_dir )
641633 fsstack_copy_attr_all (old_dir , d_inode (lower_old_dir_dentry ));
642634out_lock :
643- dput (lower_new_dentry );
644- unlock_rename (lower_old_dir_dentry , lower_new_dir_dentry );
635+ end_renaming (& rd );
645636 return rc ;
646637}
647638
0 commit comments