@@ -191,13 +191,6 @@ mod remove_dir_all_xat {
191
191
}
192
192
Ok ( ( ) )
193
193
}
194
-
195
- fn is_open ( & self ) -> bool {
196
- match self {
197
- LazyReadDir :: OpenReadDir ( _, _) => true ,
198
- _ => false ,
199
- }
200
- }
201
194
}
202
195
203
196
impl AsFd for LazyReadDir < ' _ > {
@@ -314,9 +307,27 @@ mod remove_dir_all_xat {
314
307
let parent_readdir = match readdir_cache. pop_back ( ) {
315
308
Some ( readdir) => readdir,
316
309
None => {
317
- // cache is empty - reopen parent
310
+ // cache is empty - reopen parent and grandparent fd
311
+
318
312
let parent_readdir = current_readdir. get_parent ( ) ?;
319
313
parent_component. verify_dev_ino ( parent_readdir. as_fd ( ) ) ?;
314
+
315
+ // We are about to delete the now empty "child directory".
316
+ // To make sure the that the child directory was not moved somewhere
317
+ // else and that the parent just happens to have the same reused
318
+ // (dev, inode) pair, that we found descending, we verify the
319
+ // grandparent directory (dev, inode) as well.
320
+ let grandparent_readdir = parent_readdir. get_parent ( ) ?;
321
+ if let Some ( grandparent_component) = path_components. last ( ) {
322
+ grandparent_component
323
+ . verify_dev_ino ( grandparent_readdir. as_fd ( ) ) ?;
324
+ readdir_cache. push_back ( grandparent_readdir) ;
325
+ } else {
326
+ // verify parent of the deletion root directory
327
+ root_parent_component
328
+ . verify_dev_ino ( grandparent_readdir. as_fd ( ) ) ?;
329
+ }
330
+
320
331
parent_readdir
321
332
}
322
333
} ;
@@ -332,25 +343,6 @@ mod remove_dir_all_xat {
332
343
333
344
current_path_component = parent_component;
334
345
current_readdir = parent_readdir;
335
-
336
- // Let "child directory" be the directory that was just deleted and "parent directory"
337
- // the parent of "child directory" which is now referred to in current_*.
338
- // If we don't have readdir open for the parent directory that means we got the file
339
- // descriptor via openat(dirfd, ".."). To make sure the that the child directory
340
- // was not moved somewhere else and the parent just happens to have the same reused
341
- // (dev, inode) pair, that we found descending, we check the parent directory
342
- // (dev, inode) as well.
343
- if !current_readdir. is_open ( ) && readdir_cache. is_empty ( ) {
344
- if let Some ( parent_component) = path_components. last ( ) {
345
- let parent_readdir = current_readdir. get_parent ( ) ?;
346
- parent_component. verify_dev_ino ( parent_readdir. as_fd ( ) ) ?;
347
- readdir_cache. push_back ( parent_readdir) ;
348
- } else {
349
- // verify parent of the deletion root directory
350
- let parent_readdir = current_readdir. get_parent ( ) ?;
351
- root_parent_component. verify_dev_ino ( parent_readdir. as_fd ( ) ) ?;
352
- }
353
- }
354
346
}
355
347
None => break ,
356
348
}
0 commit comments