1818
1919struct ovl_lookup_data {
2020 struct super_block * sb ;
21- struct vfsmount * mnt ;
21+ const struct ovl_layer * layer ;
2222 struct qstr name ;
2323 bool is_dir ;
2424 bool opaque ;
25+ bool xwhiteouts ;
2526 bool stop ;
2627 bool last ;
2728 char * redirect ;
@@ -201,17 +202,13 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
201202 return real ;
202203}
203204
204- static bool ovl_is_opaquedir (struct ovl_fs * ofs , const struct path * path )
205- {
206- return ovl_path_check_dir_xattr (ofs , path , OVL_XATTR_OPAQUE );
207- }
208-
209205static struct dentry * ovl_lookup_positive_unlocked (struct ovl_lookup_data * d ,
210206 const char * name ,
211207 struct dentry * base , int len ,
212208 bool drop_negative )
213209{
214- struct dentry * ret = lookup_one_unlocked (mnt_idmap (d -> mnt ), name , base , len );
210+ struct dentry * ret = lookup_one_unlocked (mnt_idmap (d -> layer -> mnt ), name ,
211+ base , len );
215212
216213 if (!IS_ERR (ret ) && d_flags_negative (smp_load_acquire (& ret -> d_flags ))) {
217214 if (drop_negative && ret -> d_lockref .count == 1 ) {
@@ -232,10 +229,13 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
232229 size_t prelen , const char * post ,
233230 struct dentry * * ret , bool drop_negative )
234231{
232+ struct ovl_fs * ofs = OVL_FS (d -> sb );
235233 struct dentry * this ;
236234 struct path path ;
237235 int err ;
238236 bool last_element = !post [0 ];
237+ bool is_upper = d -> layer -> idx == 0 ;
238+ char val ;
239239
240240 this = ovl_lookup_positive_unlocked (d , name , base , namelen , drop_negative );
241241 if (IS_ERR (this )) {
@@ -253,8 +253,8 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
253253 }
254254
255255 path .dentry = this ;
256- path .mnt = d -> mnt ;
257- if (ovl_path_is_whiteout (OVL_FS ( d -> sb ) , & path )) {
256+ path .mnt = d -> layer -> mnt ;
257+ if (ovl_path_is_whiteout (ofs , & path )) {
258258 d -> stop = d -> opaque = true;
259259 goto put_and_out ;
260260 }
@@ -272,7 +272,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
272272 d -> stop = true;
273273 goto put_and_out ;
274274 }
275- err = ovl_check_metacopy_xattr (OVL_FS ( d -> sb ) , & path , NULL );
275+ err = ovl_check_metacopy_xattr (ofs , & path , NULL );
276276 if (err < 0 )
277277 goto out_err ;
278278
@@ -292,7 +292,12 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
292292 if (d -> last )
293293 goto out ;
294294
295- if (ovl_is_opaquedir (OVL_FS (d -> sb ), & path )) {
295+ /* overlay.opaque=x means xwhiteouts directory */
296+ val = ovl_get_opaquedir_val (ofs , & path );
297+ if (last_element && !is_upper && val == 'x' ) {
298+ d -> xwhiteouts = true;
299+ ovl_layer_set_xwhiteouts (ofs , d -> layer );
300+ } else if (val == 'y' ) {
296301 d -> stop = true;
297302 if (last_element )
298303 d -> opaque = true;
@@ -863,21 +868,25 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
863868 * Returns next layer in stack starting from top.
864869 * Returns -1 if this is the last layer.
865870 */
866- int ovl_path_next (int idx , struct dentry * dentry , struct path * path )
871+ int ovl_path_next (int idx , struct dentry * dentry , struct path * path ,
872+ const struct ovl_layer * * layer )
867873{
868874 struct ovl_entry * oe = OVL_E (dentry );
869875 struct ovl_path * lowerstack = ovl_lowerstack (oe );
870876
871877 BUG_ON (idx < 0 );
872878 if (idx == 0 ) {
873879 ovl_path_upper (dentry , path );
874- if (path -> dentry )
880+ if (path -> dentry ) {
881+ * layer = & OVL_FS (dentry -> d_sb )-> layers [0 ];
875882 return ovl_numlower (oe ) ? 1 : -1 ;
883+ }
876884 idx ++ ;
877885 }
878886 BUG_ON (idx > ovl_numlower (oe ));
879887 path -> dentry = lowerstack [idx - 1 ].dentry ;
880- path -> mnt = lowerstack [idx - 1 ].layer -> mnt ;
888+ * layer = lowerstack [idx - 1 ].layer ;
889+ path -> mnt = (* layer )-> mnt ;
881890
882891 return (idx < ovl_numlower (oe )) ? idx + 1 : -1 ;
883892}
@@ -1055,7 +1064,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
10551064 old_cred = ovl_override_creds (dentry -> d_sb );
10561065 upperdir = ovl_dentry_upper (dentry -> d_parent );
10571066 if (upperdir ) {
1058- d .mnt = ovl_upper_mnt ( ofs ) ;
1067+ d .layer = & ofs -> layers [ 0 ] ;
10591068 err = ovl_lookup_layer (upperdir , & d , & upperdentry , true);
10601069 if (err )
10611070 goto out ;
@@ -1111,7 +1120,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
11111120 else if (d .is_dir || !ofs -> numdatalayer )
11121121 d .last = lower .layer -> idx == ovl_numlower (roe );
11131122
1114- d .mnt = lower .layer -> mnt ;
1123+ d .layer = lower .layer ;
11151124 err = ovl_lookup_layer (lower .dentry , & d , & this , false);
11161125 if (err )
11171126 goto out_put ;
@@ -1278,6 +1287,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
12781287
12791288 if (upperopaque )
12801289 ovl_dentry_set_opaque (dentry );
1290+ if (d .xwhiteouts )
1291+ ovl_dentry_set_xwhiteouts (dentry );
12811292
12821293 if (upperdentry )
12831294 ovl_dentry_set_upper_alias (dentry );
0 commit comments