Przeglądaj źródła

disk: clean temporary files and directories on O_DIRECT open error

Samuel Thibault 7 lat temu
rodzic
commit
4676d335bc
2 zmienionych plików z 27 dodań i 2 usunięć
  1. 25 1
      src/common/utils.c
  2. 2 1
      src/common/utils.h

+ 25 - 1
src/common/utils.c

@@ -207,6 +207,11 @@ char *_starpu_mktemp(const char *directory, int flags, int *fd)
 #elif defined (HAVE_MKOSTEMP)
 	flags &= ~O_RDWR;
 	*fd = mkostemp(baseCpy, flags);
+
+	if (*fd < 0 && (flags & O_DIRECT)) {
+		/* It failed, but perhaps still created the file, clean the mess */
+		unlink(baseCpy);
+	}
 #else
 #  ifdef O_DIRECT
 	STARPU_ASSERT(flags == (O_RDWR | O_BINARY) || flags == (O_RDWR | O_BINARY | O_DIRECT));
@@ -236,6 +241,8 @@ char *_starpu_mktemp(const char *directory, int flags, int *fd)
 		{
 			int err = errno;
 			_STARPU_DISP("Could set O_DIRECT on the temporary file in directory '%s', fcntl failed with error '%s'\n", directory, strerror(errno));
+			close(*fd);
+			unlink(baseCpy);
 			free(baseCpy);
 			errno = err;
 			return NULL;
@@ -253,6 +260,7 @@ char *_starpu_mktemp_many(const char *directory, int depth, int flags, int *fd)
 	char path[len + depth*4 + 1];
 	int i;
 	struct stat sb;
+	char *retpath;
 
 	if (stat(directory, &sb) != 0)
 	{
@@ -294,7 +302,12 @@ char *_starpu_mktemp_many(const char *directory, int depth, int flags, int *fd)
 		_STARPU_DISP("Could not create temporary directory '%s', mkdir failed with error '%s'\n", path, strerror(errno));
 		return NULL;
 	}
-	return _starpu_mktemp(path, flags, fd);
+	retpath = _starpu_mktemp(path, flags, fd);
+	if (!retpath) {
+		/* That failed, drop our directories */
+		_starpu_rmdir_many(path, depth);
+	}
+	return retpath;
 }
 
 void _starpu_rmtemp_many(char *path, int depth)
@@ -308,6 +321,17 @@ void _starpu_rmtemp_many(char *path, int depth)
 	}
 }
 
+void _starpu_rmdir_many(char *path, int depth)
+{
+	int i;
+	for (i = 0; i < depth; i++)
+	{
+		if (rmdir(path) < 0 && errno != ENOTEMPTY && errno != EBUSY)
+			_STARPU_DISP("Could not remove temporary directory '%s', rmdir failed with error '%s'\n", path, strerror(errno));
+		path = dirname(path);
+	}
+}
+
 int _starpu_ftruncate(int fd, size_t length)
 {
 	return ftruncate(fd, length);

+ 2 - 1
src/common/utils.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010, 2012-2016  Université de Bordeaux
+ * Copyright (C) 2010, 2012-2017  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017  CNRS
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -136,6 +136,7 @@ char *_starpu_mktemp(const char *directory, int flags, int *fd);
  * creating a lot of temporary files to be stored in the same place */
 char *_starpu_mktemp_many(const char *directory, int depth, int flags, int *fd);
 void _starpu_rmtemp_many(char *path, int depth);
+void _starpu_rmdir_many(char *path, int depth);
 int _starpu_fftruncate(FILE *file, size_t length);
 int _starpu_ftruncate(int fd, size_t length);
 int _starpu_frdlock(FILE *file);