@@ -798,7 +798,7 @@ static int complete_walk(struct nameidata *nd)
798
798
return status ;
799
799
}
800
800
801
- static void set_root (struct nameidata * nd )
801
+ static int set_root (struct nameidata * nd )
802
802
{
803
803
struct fs_struct * fs = current -> fs ;
804
804
@@ -814,6 +814,7 @@ static void set_root(struct nameidata *nd)
814
814
get_fs_root (fs , & nd -> root );
815
815
nd -> flags |= LOOKUP_ROOT_GRABBED ;
816
816
}
817
+ return 0 ;
817
818
}
818
819
819
820
static void path_put_conditional (struct path * path , struct nameidata * nd )
@@ -837,6 +838,11 @@ static inline void path_to_nameidata(const struct path *path,
837
838
838
839
static int nd_jump_root (struct nameidata * nd )
839
840
{
841
+ if (!nd -> root .mnt ) {
842
+ int error = set_root (nd );
843
+ if (error )
844
+ return error ;
845
+ }
840
846
if (nd -> flags & LOOKUP_RCU ) {
841
847
struct dentry * d ;
842
848
nd -> path = nd -> root ;
@@ -1084,10 +1090,9 @@ const char *get_link(struct nameidata *nd)
1084
1090
return res ;
1085
1091
}
1086
1092
if (* res == '/' ) {
1087
- if (!nd -> root .mnt )
1088
- set_root (nd );
1089
- if (unlikely (nd_jump_root (nd )))
1090
- return ERR_PTR (- ECHILD );
1093
+ error = nd_jump_root (nd );
1094
+ if (unlikely (error ))
1095
+ return ERR_PTR (error );
1091
1096
while (unlikely (* ++ res == '/' ))
1092
1097
;
1093
1098
}
@@ -1700,8 +1705,13 @@ static inline int may_lookup(struct nameidata *nd)
1700
1705
static inline int handle_dots (struct nameidata * nd , int type )
1701
1706
{
1702
1707
if (type == LAST_DOTDOT ) {
1703
- if (!nd -> root .mnt )
1704
- set_root (nd );
1708
+ int error = 0 ;
1709
+
1710
+ if (!nd -> root .mnt ) {
1711
+ error = set_root (nd );
1712
+ if (error )
1713
+ return error ;
1714
+ }
1705
1715
if (nd -> flags & LOOKUP_RCU ) {
1706
1716
return follow_dotdot_rcu (nd );
1707
1717
} else
@@ -2159,6 +2169,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
2159
2169
/* must be paired with terminate_walk() */
2160
2170
static const char * path_init (struct nameidata * nd , unsigned flags )
2161
2171
{
2172
+ int error ;
2162
2173
const char * s = nd -> name -> name ;
2163
2174
2164
2175
if (!* s )
@@ -2191,11 +2202,13 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
2191
2202
nd -> path .dentry = NULL ;
2192
2203
2193
2204
nd -> m_seq = read_seqbegin (& mount_lock );
2205
+
2206
+ /* Figure out the starting path and root (if needed). */
2194
2207
if (* s == '/' ) {
2195
- set_root (nd );
2196
- if (likely (! nd_jump_root ( nd ) ))
2197
- return s ;
2198
- return ERR_PTR ( - ECHILD ) ;
2208
+ error = nd_jump_root (nd );
2209
+ if (unlikely ( error ))
2210
+ return ERR_PTR ( error ) ;
2211
+ return s ;
2199
2212
} else if (nd -> dfd == AT_FDCWD ) {
2200
2213
if (flags & LOOKUP_RCU ) {
2201
2214
struct fs_struct * fs = current -> fs ;
0 commit comments