[PATCH 08/35] fs-tests: integck: handle errors in file_delete

Artem Bityutskiy dedekind1 at gmail.com
Wed Apr 20 06:18:41 EDT 2011


From: Artem Bityutskiy <Artem.Bityutskiy at nokia.com>

Teach 'file_delete()' and several other functions it calls
(like 'file_unlink()) to handle write errors and propagate the
up to the caller.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy at nokia.com>
---
 tests/fs-tests/integrity/integck.c |   77 +++++++++++++++++++++++++-----------
 1 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/tests/fs-tests/integrity/integck.c b/tests/fs-tests/integrity/integck.c
index 06e33b5..7ccbcb1 100644
--- a/tests/fs-tests/integrity/integck.c
+++ b/tests/fs-tests/integrity/integck.c
@@ -476,8 +476,8 @@ static struct dir_info *dir_new(struct dir_info *parent, const char *name)
 	return dir;
 }
 
-static void file_delete(struct file_info *file);
-static void file_unlink(struct dir_entry_info *entry);
+static int file_delete(struct file_info *file);
+static int file_unlink(struct dir_entry_info *entry);
 static void symlink_remove(struct symlink_info *symlink);
 
 static void dir_remove(struct dir_info *dir)
@@ -576,20 +576,28 @@ static void file_close_all(struct file_info *file)
 	}
 }
 
-static void file_unlink(struct dir_entry_info *entry)
+/*
+ * Unlink a directory entry for a file.
+ */
+static int file_unlink(struct dir_entry_info *entry)
 {
 	struct file_info *file = entry->file;
 	char *path;
+	int ret;
 
 	path = dir_path(entry->parent, entry->name);
+	/* Unlink the file */
+	ret = unlink(path);
+	if (ret) {
+		pcv("cannot unlink file %s", path);
+		free(path);
+		return -1;
+	}
+	free(path);
 
 	/* Remove file entry from parent directory */
 	remove_dir_entry(entry);
 
-	/* Unlink the file */
-	CHECK(unlink(path) == 0);
-	free(path);
-
 	/* Free struct file_info if file is not open and not linked */
 	if (!file->fds && !file->links) {
 		struct write_info *w, *next;
@@ -604,6 +612,8 @@ static void file_unlink(struct dir_entry_info *entry)
 		free(file);
 	} else if (!file->links)
 		file->deleted = 1;
+
+	return 0;
 }
 
 static struct dir_entry_info *pick_entry(struct file_info *file)
@@ -630,7 +640,11 @@ static void file_unlink_file(struct file_info *file)
 	file_unlink(entry);
 }
 
-static void file_delete(struct file_info *file)
+/*
+ * Close all open descriptors for a file described by 'file' and delete it by
+ * unlinking all its hardlinks.
+ */
+static int file_delete(struct file_info *file)
 {
 	struct dir_entry_info *entry = file->links;
 
@@ -638,9 +652,12 @@ static void file_delete(struct file_info *file)
 	while (entry) {
 		struct dir_entry_info *next = entry->next_link;
 
-		file_unlink(entry);
+		if (file_unlink(entry))
+			return -1;
 		entry = next;
 	}
+
+	return 0;
 }
 
 static void file_info_display(struct file_info *file)
@@ -892,7 +909,8 @@ static int file_ftruncate(struct file_info *file, int fd, off_t new_length)
 			file->no_space_error = 1;
 			/* Delete errored files */
 			if (!fsinfo.nospc_size_ok)
-				file_delete(file);
+				if (file_delete(file))
+					return -1;
 			return 1;
 		} else
 			pcv("cannot truncate file %s to %llu",
@@ -970,17 +988,21 @@ static void file_mmap_write(struct file_info *file)
 	file_write_info(file, offset, size, seed);
 }
 
-static void file_write(struct file_info *file, int fd)
+/*
+ * Write random amount of data to a random offset in an open file or randomly
+ * choose to truncate it.
+ */
+static int file_write(struct file_info *file, int fd)
 {
 	off_t offset;
 	size_t size, actual;
 	unsigned seed;
-	int truncate = 0;
+	int ret, truncate = 0;
 
 	if (fsinfo.can_mmap && !full && !file->deleted &&
 	    random_no(100) == 1) {
 		file_mmap_write(file);
-		return;
+		return 0;
 	}
 
 	get_offset_and_size(file, &offset, &size);
@@ -997,30 +1019,38 @@ static void file_write(struct file_info *file, int fd)
 		file_write_info(file, offset, actual, seed);
 
 	/* Delete errored files */
-	if (!fsinfo.nospc_size_ok && file->no_space_error) {
-		file_delete(file);
-		return;
-	}
+	if (!fsinfo.nospc_size_ok && file->no_space_error)
+		return file_delete(file);
 
 	if (truncate) {
 		size_t new_length = offset + actual;
 
-		if (!file_ftruncate(file, fd, new_length))
+		ret = file_ftruncate(file, fd, new_length);
+		if (ret == -1)
+			return -1;
+		if (!ret)
 			file_truncate_info(file, new_length);
 	}
+
+	return 0;
 }
 
-static void file_write_file(struct file_info *file)
+/*
+ * Write random amount of data to a random offset in a file or randomly
+ * choose to truncate it.
+ */
+static int file_write_file(struct file_info *file)
 {
-	int fd;
+	int fd, ret;
 	char *path;
 
 	path = dir_path(file->links->parent, file->links->name);
 	fd = open(path, O_WRONLY);
 	CHECK(fd != -1);
-	file_write(file, fd);
+	ret = file_write(file, fd);
 	CHECK(close(fd) == 0);
 	free(path);
+	return ret;
 }
 
 static void file_truncate_info(struct file_info *file, size_t new_length)
@@ -1924,9 +1954,10 @@ static int operate_on_open_file(struct fd_info *fdi)
 	else if (r < 21)
 		file_close(fdi);
 	else if (shrink && r < 121 && !fdi->file->deleted)
-		file_delete(fdi->file);
+		return file_delete(fdi->file);
 	else {
-		file_write(fdi->file, fdi->fd);
+		if (file_write(fdi->file, fdi->fd))
+			return -1;
 		if (r >= 999) {
 			if (random_no(100) >= 50)
 				CHECK(fsync(fdi->fd) == 0);
-- 
1.7.2.3




More information about the linux-mtd mailing list