@@ -191,16 +191,36 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
191
191
return ovl_check_dir_xattr (dentry , OVL_XATTR_OPAQUE );
192
192
}
193
193
194
+ static struct dentry * ovl_lookup_positive_unlocked (const char * name ,
195
+ struct dentry * base , int len ,
196
+ bool drop_negative )
197
+ {
198
+ struct dentry * ret = lookup_one_len_unlocked (name , base , len );
199
+
200
+ if (!IS_ERR (ret ) && d_flags_negative (smp_load_acquire (& ret -> d_flags ))) {
201
+ if (drop_negative && ret -> d_lockref .count == 1 ) {
202
+ spin_lock (& ret -> d_lock );
203
+ /* Recheck condition under lock */
204
+ if (d_is_negative (ret ) && ret -> d_lockref .count == 1 )
205
+ __d_drop (ret );
206
+ spin_unlock (& ret -> d_lock );
207
+ }
208
+ dput (ret );
209
+ ret = ERR_PTR (- ENOENT );
210
+ }
211
+ return ret ;
212
+ }
213
+
194
214
static int ovl_lookup_single (struct dentry * base , struct ovl_lookup_data * d ,
195
215
const char * name , unsigned int namelen ,
196
216
size_t prelen , const char * post ,
197
- struct dentry * * ret )
217
+ struct dentry * * ret , bool drop_negative )
198
218
{
199
219
struct dentry * this ;
200
220
int err ;
201
221
bool last_element = !post [0 ];
202
222
203
- this = lookup_positive_unlocked (name , base , namelen );
223
+ this = ovl_lookup_positive_unlocked (name , base , namelen , drop_negative );
204
224
if (IS_ERR (this )) {
205
225
err = PTR_ERR (this );
206
226
this = NULL ;
@@ -276,7 +296,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
276
296
}
277
297
278
298
static int ovl_lookup_layer (struct dentry * base , struct ovl_lookup_data * d ,
279
- struct dentry * * ret )
299
+ struct dentry * * ret , bool drop_negative )
280
300
{
281
301
/* Counting down from the end, since the prefix can change */
282
302
size_t rem = d -> name .len - 1 ;
@@ -285,7 +305,7 @@ static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
285
305
286
306
if (d -> name .name [0 ] != '/' )
287
307
return ovl_lookup_single (base , d , d -> name .name , d -> name .len ,
288
- 0 , "" , ret );
308
+ 0 , "" , ret , drop_negative );
289
309
290
310
while (!IS_ERR_OR_NULL (base ) && d_can_lookup (base )) {
291
311
const char * s = d -> name .name + d -> name .len - rem ;
@@ -298,7 +318,8 @@ static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
298
318
return - EIO ;
299
319
300
320
err = ovl_lookup_single (base , d , s , thislen ,
301
- d -> name .len - rem , next , & base );
321
+ d -> name .len - rem , next , & base ,
322
+ drop_negative );
302
323
dput (dentry );
303
324
if (err )
304
325
return err ;
@@ -830,7 +851,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
830
851
old_cred = ovl_override_creds (dentry -> d_sb );
831
852
upperdir = ovl_dentry_upper (dentry -> d_parent );
832
853
if (upperdir ) {
833
- err = ovl_lookup_layer (upperdir , & d , & upperdentry );
854
+ err = ovl_lookup_layer (upperdir , & d , & upperdentry , true );
834
855
if (err )
835
856
goto out ;
836
857
@@ -888,7 +909,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
888
909
else
889
910
d .last = lower .layer -> idx == roe -> numlower ;
890
911
891
- err = ovl_lookup_layer (lower .dentry , & d , & this );
912
+ err = ovl_lookup_layer (lower .dentry , & d , & this , false );
892
913
if (err )
893
914
goto out_put ;
894
915
0 commit comments