[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Remove Utility- need guidance
From: |
Jim Meyering |
Subject: |
Re: Remove Utility- need guidance |
Date: |
Fri, 10 Mar 2006 22:51:25 +0100 |
vineet chadha <address@hidden> wrote:
> I a grad at Univ of Florida and working to develop an application
> (copy-on-write) for my research. When working on it, I found remove
> utility "circular directory test" little intriguing. Here is the reason:
>
> Modern operating system put the in-core inode into free list and
> sometimes re-allocates inode immediately to NEXT creation of file system
> object. remove UTILITY heavily works on assumption that
> directory-to-be-deleted is of single thread and not being modified by
> other user or prcoess. Sepcifically, I will give you as example of my
> copy-on-write implementation. i have been trying to replicate a directory
> hierarchy from main server to a dummy server called as shadow server
> dynamically. Now if I issue "rm -rf", due to certain restrictions my
> implementation starts replicating file ( untill it is already done so) in
> shadow server and subsequetnly delete it and update state of corresponding
> dir in a hash table. Point is that during is process of remove, directory
> is also being changed (as being replicated). Since, OS is allocating
> inodes, almost most of time, remove fails on circular directory structure
> as OS has reallocated the inode to newly replicated file object in same
> diretory hierachy. So, probabiity of matching inode in state buffer
> (stored as power of two) is almost certain.
>
> I confirmed this phenomenon ( though not conistently ) through running two
> scripts (one creating 10000 dir hierachy and other deleting it. I tried
> nearly 10 times and it failed 2 times (even though it is completely
> different dir) .
> I am thinking to work on a patch for the same. Please comment on issue.
Thank you very much for tracking that down and reporting it!
I reproduced the problem like this:
(mkdir x && cd x && perl -e 'while (1) { mkdir int rand 9999 }') &
pid=$!
sleep 3; rm -rf x
kill $pid
Here's the output I got, using ReiserFS3[*] on linux-2.6.15 with
the latest version of GNU rm:
rm: WARNING: Circular directory structure.
This almost certainly means that you have a corrupted file system.
NOTIFY YOUR SYSTEM MANAGER.
The following directory is part of the cycle:
`x'
[Exit 1]
[*] I tried a few times using ext3, xfs, and tmpfs, but the above
did not trigger the failure. Different inode-reuse policy, I suppose.
--------------------
Here's a fix for the CVS trunk (it'll also go onto the b5 branch,
from which coreutils-5.95 will come).
2006-03-10 Jim Meyering <address@hidden>
* src/remove.c (AD_pop_and_chdir): Fix a bug whereby a user with
write access to a directory being removed could cause the removal
of that directory to fail with an erroneous diagnostic about a
directory cycle. Reported by Vineet Chadha.
Index: remove.c
===================================================================
RCS file: /fetish/cu/src/remove.c,v
retrieving revision 1.146
diff -u -p -r1.146 remove.c
--- remove.c 12 Feb 2006 07:55:38 -0000 1.146
+++ remove.c 10 Mar 2006 21:21:22 -0000
@@ -391,7 +391,9 @@ ds_free (Dirstack_state *ds)
static void
AD_pop_and_chdir (DIR **dirp, Dirstack_state *ds, char **prev_dir)
{
- enum RM_status old_status = AD_stack_top(ds)->status;
+ struct AD_ent *leaf_dir_ent = AD_stack_top(ds);
+ struct dev_ino leaf_dev_ino = leaf_dir_ent->dev_ino;
+ enum RM_status old_status = leaf_dir_ent->status;
struct AD_ent *top;
/* Get the name of the current (but soon to be `previous') directory
@@ -402,6 +404,16 @@ AD_pop_and_chdir (DIR **dirp, Dirstack_s
pop_dir (ds);
top = AD_stack_top (ds);
+ /* If the directory we're about to leave (and try to rmdir)
+ is the one whose dev_ino is being used to detect a cycle,
+ reset cycle_check_state.dev_ino to that of the parent.
+ Otherwise, once that directory is removed, its dev_ino
+ could be reused in the creation (by some other process)
+ of a directory that this rm process would encounter,
+ which would result in a false-positive cycle indication. */
+ if (SAME_INODE (ds->cycle_check_state.dev_ino, leaf_dev_ino))
+ ds->cycle_check_state.dev_ino = top->dev_ino;
+
/* Propagate any failure to parent. */
UPDATE_STATUS (top->status, old_status);
- Re: Remove Utility- need guidance,
Jim Meyering <=