]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
namei: Do not remove n_voldir1
authorAndrew Deason <adeason@sinenomine.net>
Thu, 9 Sep 2010 19:10:01 +0000 (14:10 -0500)
committerDerrick Brashear <shadow@dementia.org>
Thu, 9 Sep 2010 20:28:58 +0000 (13:28 -0700)
When removing data directories in namei_RemoveDataDirectories, do not
remove the n_voldir1 directory (directory X in /vicepa/AFSIDat/X).
Removing this directory can race against the creation of an entirely
unrelated volume, causing the create op to fail (since it tries to
create a directory in a directory that no longer exists).

We don't currently have the necessary locking to make this safe, and
since the overhead of n_voldir1 existing is pretty negligible, just
leave it there. Also add some comments briefly justifying this.

Note that other similar races probably exist for directories under
n_voldir1, but they would only be between volumes in the same VG, and
so are much less likely to occur.

Change-Id: I5eac894cdbdb3fd1d74d8a0fc226df03686ceeef
Reviewed-on: http://gerrit.openafs.org/2727
Tested-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
src/vol/namei_ops.c

index 692a58536c0ca90c37437279c8d6a46c532f171c..b250a53fef91d266c614b57cf6ce8942dbcd93a3 100644 (file)
@@ -416,7 +416,7 @@ namei_RemoveDataDirectories(namei_t * name)
     char pbuf[MAXPATHLEN], *path = pbuf;
     int prefixlen = strlen(name->n_base), err = 0;
     int vollen = strlen(name->n_voldir1);
-    int code, code2;
+    int code;
 
     strlcpy(path, name->n_path, sizeof(pbuf));
 
@@ -426,16 +426,12 @@ namei_RemoveDataDirectories(namei_t * name)
     /* now delete all dirs upto path */
     code = delTree(pbuf, path, &err);
 
-    /* We deleted everything under /n_base/n_voldir1/n_voldir2 if we could,
-     * but now try to rmdir /n_base/n_voldir1 if we can. delTree modified
-     * pbuf, so just reconstruct /n_base/n_voldir1 from scratch oureslves. */
-    afs_snprintf(pbuf, sizeof(pbuf)-1, "%s/%s", name->n_base, name->n_voldir1);
-    pbuf[sizeof(pbuf)-1] = '\0';
-
-    code2 = rmdir(pbuf);
-    if (!code) {
-       code = code2;
-    }
+    /* We've now deleted everything under /n_base/n_voldir1/n_voldir2 that
+     * we could. Do not delete /n_base/n_voldir1, since doing such might
+     * interrupt another thread trying to create a volume. We could introduce
+     * some locking to make this safe (or only remove it for whole-partition
+     * salvages), but by not deleting it we only leave behind a maximum of
+     * 256 empty directories. So at least for now, don't bother. */
 
     return code;
 }