diff options
Diffstat (limited to 'test/release_unlink_race.c')
-rw-r--r-- | test/release_unlink_race.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/test/release_unlink_race.c b/test/release_unlink_race.c new file mode 100644 index 0000000..2edb200 --- /dev/null +++ b/test/release_unlink_race.c @@ -0,0 +1,111 @@ +/* + This program can be distributed under the terms of the GNU GPLv2. + See the file COPYING. +*/ + +#define FUSE_USE_VERSION 31 + +#define _GNU_SOURCE + +#include <fuse.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +static void *xmp_init(struct fuse_conn_info *conn, + struct fuse_config *cfg) +{ + (void) conn; + + cfg->use_ino = 1; + cfg->nullpath_ok = 1; + cfg->entry_timeout = 0; + cfg->attr_timeout = 0; + cfg->negative_timeout = 0; + + return NULL; +} + +static int xmp_getattr(const char *path, struct stat *stbuf, + struct fuse_file_info *fi) +{ + int res; + + (void) path; + + if(fi) + res = fstat(fi->fh, stbuf); + else + res = lstat(path, stbuf); + if (res == -1) + return -errno; + + return 0; +} + +static int xmp_unlink(const char *path) +{ + int res; + + res = unlink(path); + if (res == -1) + return -errno; + + return 0; +} + +static int xmp_rename(const char *from, const char *to, unsigned int flags) +{ + int res; + + if (flags) + return -EINVAL; + + if(!getenv("RELEASEUNLINKRACE_DELAY_DISABLE")) usleep(100000); + + res = rename(from, to); + if (res == -1) + return -errno; + + return 0; +} + +static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi) +{ + int fd; + + fd = open(path, fi->flags, mode); + if (fd == -1) + return -errno; + + fi->fh = fd; + return 0; +} + +static int xmp_release(const char *path, struct fuse_file_info *fi) +{ + (void) path; + + if(!getenv("RELEASEUNLINKRACE_DELAY_DISABLE")) usleep(100000); + + close(fi->fh); + + return 0; +} + +static const struct fuse_operations xmp_oper = { + .init = xmp_init, + .getattr = xmp_getattr, + .unlink = xmp_unlink, + .rename = xmp_rename, + .create = xmp_create, + .release = xmp_release, +}; + +int main(int argc, char *argv[]) +{ + umask(0); + return fuse_main(argc, argv, &xmp_oper, NULL); +} |