@@ -2758,7 +2758,8 @@ static int filename_parentat(int dfd, struct filename *name,
27582758}
27592759
27602760/* does lookup, returns the object with parent locked */
2761- static struct dentry * __kern_path_locked (int dfd , struct filename * name , struct path * path )
2761+ static struct dentry * __start_removing_path (int dfd , struct filename * name ,
2762+ struct path * path )
27622763{
27632764 struct path parent_path __free (path_put ) = {};
27642765 struct dentry * d ;
@@ -2770,15 +2771,26 @@ static struct dentry *__kern_path_locked(int dfd, struct filename *name, struct
27702771 return ERR_PTR (error );
27712772 if (unlikely (type != LAST_NORM ))
27722773 return ERR_PTR (- EINVAL );
2774+ /* don't fail immediately if it's r/o, at least try to report other errors */
2775+ error = mnt_want_write (parent_path .mnt );
27732776 inode_lock_nested (parent_path .dentry -> d_inode , I_MUTEX_PARENT );
27742777 d = lookup_one_qstr_excl (& last , parent_path .dentry , 0 );
2775- if (IS_ERR (d )) {
2776- inode_unlock ( parent_path . dentry -> d_inode ) ;
2777- return d ;
2778- }
2778+ if (IS_ERR (d ))
2779+ goto unlock ;
2780+ if ( error )
2781+ goto fail ;
27792782 path -> dentry = no_free_ptr (parent_path .dentry );
27802783 path -> mnt = no_free_ptr (parent_path .mnt );
27812784 return d ;
2785+
2786+ fail :
2787+ dput (d );
2788+ d = ERR_PTR (error );
2789+ unlock :
2790+ inode_unlock (parent_path .dentry -> d_inode );
2791+ if (!error )
2792+ mnt_drop_write (parent_path .mnt );
2793+ return d ;
27822794}
27832795
27842796/**
@@ -2816,24 +2828,26 @@ struct dentry *kern_path_parent(const char *name, struct path *path)
28162828 return d ;
28172829}
28182830
2819- struct dentry * kern_path_locked (const char * name , struct path * path )
2831+ struct dentry * start_removing_path (const char * name , struct path * path )
28202832{
28212833 struct filename * filename = getname_kernel (name );
2822- struct dentry * res = __kern_path_locked (AT_FDCWD , filename , path );
2834+ struct dentry * res = __start_removing_path (AT_FDCWD , filename , path );
28232835
28242836 putname (filename );
28252837 return res ;
28262838}
28272839
2828- struct dentry * user_path_locked_at (int dfd , const char __user * name , struct path * path )
2840+ struct dentry * start_removing_user_path_at (int dfd ,
2841+ const char __user * name ,
2842+ struct path * path )
28292843{
28302844 struct filename * filename = getname (name );
2831- struct dentry * res = __kern_path_locked (dfd , filename , path );
2845+ struct dentry * res = __start_removing_path (dfd , filename , path );
28322846
28332847 putname (filename );
28342848 return res ;
28352849}
2836- EXPORT_SYMBOL (user_path_locked_at );
2850+ EXPORT_SYMBOL (start_removing_user_path_at );
28372851
28382852int kern_path (const char * name , unsigned int flags , struct path * path )
28392853{
@@ -4223,37 +4237,38 @@ static struct dentry *filename_create(int dfd, struct filename *name,
42234237 return dentry ;
42244238}
42254239
4226- struct dentry * kern_path_create (int dfd , const char * pathname ,
4227- struct path * path , unsigned int lookup_flags )
4240+ struct dentry * start_creating_path (int dfd , const char * pathname ,
4241+ struct path * path , unsigned int lookup_flags )
42284242{
42294243 struct filename * filename = getname_kernel (pathname );
42304244 struct dentry * res = filename_create (dfd , filename , path , lookup_flags );
42314245
42324246 putname (filename );
42334247 return res ;
42344248}
4235- EXPORT_SYMBOL (kern_path_create );
4249+ EXPORT_SYMBOL (start_creating_path );
42364250
4237- void done_path_create (struct path * path , struct dentry * dentry )
4251+ void end_creating_path (struct path * path , struct dentry * dentry )
42384252{
42394253 if (!IS_ERR (dentry ))
42404254 dput (dentry );
42414255 inode_unlock (path -> dentry -> d_inode );
42424256 mnt_drop_write (path -> mnt );
42434257 path_put (path );
42444258}
4245- EXPORT_SYMBOL (done_path_create );
4259+ EXPORT_SYMBOL (end_creating_path );
42464260
4247- inline struct dentry * user_path_create (int dfd , const char __user * pathname ,
4248- struct path * path , unsigned int lookup_flags )
4261+ inline struct dentry * start_creating_user_path (
4262+ int dfd , const char __user * pathname ,
4263+ struct path * path , unsigned int lookup_flags )
42494264{
42504265 struct filename * filename = getname (pathname );
42514266 struct dentry * res = filename_create (dfd , filename , path , lookup_flags );
42524267
42534268 putname (filename );
42544269 return res ;
42554270}
4256- EXPORT_SYMBOL (user_path_create );
4271+ EXPORT_SYMBOL (start_creating_user_path );
42574272
42584273/**
42594274 * vfs_mknod - create device node or file
@@ -4361,7 +4376,7 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
43614376 break ;
43624377 }
43634378out2 :
4364- done_path_create (& path , dentry );
4379+ end_creating_path (& path , dentry );
43654380 if (retry_estale (error , lookup_flags )) {
43664381 lookup_flags |= LOOKUP_REVAL ;
43674382 goto retry ;
@@ -4465,7 +4480,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
44654480 if (IS_ERR (dentry ))
44664481 error = PTR_ERR (dentry );
44674482 }
4468- done_path_create (& path , dentry );
4483+ end_creating_path (& path , dentry );
44694484 if (retry_estale (error , lookup_flags )) {
44704485 lookup_flags |= LOOKUP_REVAL ;
44714486 goto retry ;
@@ -4819,7 +4834,7 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
48194834 if (!error )
48204835 error = vfs_symlink (mnt_idmap (path .mnt ), path .dentry -> d_inode ,
48214836 dentry , from -> name );
4822- done_path_create (& path , dentry );
4837+ end_creating_path (& path , dentry );
48234838 if (retry_estale (error , lookup_flags )) {
48244839 lookup_flags |= LOOKUP_REVAL ;
48254840 goto retry ;
@@ -4988,7 +5003,7 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
49885003 error = vfs_link (old_path .dentry , idmap , new_path .dentry -> d_inode ,
49895004 new_dentry , & delegated_inode );
49905005out_dput :
4991- done_path_create (& new_path , new_dentry );
5006+ end_creating_path (& new_path , new_dentry );
49925007 if (delegated_inode ) {
49935008 error = break_deleg_wait (& delegated_inode );
49945009 if (!error ) {
0 commit comments