* races, getcwd vs rename
@ 2016-10-07 13:48 Andrew Perepechko
0 siblings, 0 replies; only message in thread
From: Andrew Perepechko @ 2016-10-07 13:48 UTC (permalink / raw)
To: linux-fsdevel; +Cc: andrew.perepechko, alexey.lyashkov
Hello!
Our applications are sometimes getting ENOENT from getcwd() though
the CWD was never really unlinked. Looking into the code of getcwd(),
it appears that the (d_unlinked(pwd.dentry)) check is not properly
protected against a concurrent d_move(), which unhashes and then
rehashes the dentry. I wrote a trivial reproducer for this issue (see below).
The reproducer gets ENOENT when a getcwd() call races with rename().
Is this the expected behaviour? My understanding is that rename() should be
atomic.
Thank you,
Andrew
root@panda:/mnt/sss# cat zzz.c
#include <pthread.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
void *thread_main(void *unused)
{
int rc;
for (;;) {
rc = rename("/tmp/t-a", "/tmp/t-b");
assert(rc == 0);
rc = rename("/tmp/t-b", "/tmp/t-a");
assert(rc == 0);
}
return NULL;
}
int main(void)
{
int rc, i;
pthread_t ptt;
rmdir("/tmp/t-a");
rmdir("/tmp/t-b");
rc = mkdir("/tmp/t-a", 0666);
assert(rc == 0);
rc = chdir("/tmp/t-a");
assert(rc == 0);
rc = pthread_create(&ptt, NULL, thread_main, NULL);
assert(rc == 0);
for (i = 0;; i++) {
char buf[100], *b;
b = getcwd(buf, sizeof(buf));
if (b == NULL) {
printf("getcwd failed on iter %d with %d\n", i,
errno);
break;
}
}
return 0;
}
root@panda:/mnt/sss# gcc -pthread zzz.c
root@panda:/mnt/sss# ./a.out
getcwd failed on iter 1225 with 2
root@panda:/mnt/sss# ./a.out
getcwd failed on iter 327 with 2
root@panda:/mnt/sss# ./a.out
getcwd failed on iter 637 with 2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-10-07 13:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-07 13:48 races, getcwd vs rename Andrew Perepechko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).