From: Andrew Deason Date: Thu, 9 Sep 2010 19:10:01 +0000 (-0500) Subject: namei: Do not remove n_voldir1 X-Git-Tag: upstream/1.8.0_pre1^2~4843 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=f2df207274c65b4fa8c24419150e9084a4d17fca;p=packages%2Fo%2Fopenafs.git namei: Do not remove n_voldir1 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 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index 692a58536..b250a53fe 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -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; }