aboutsummaryrefslogtreecommitdiff
path: root/testcases/kernel/mem
diff options
context:
space:
mode:
authorCristian Marussi <cristian.marussi@arm.com>2021-04-30 15:35:05 +0100
committerCyril Hrubis <chrubis@suse.cz>2021-05-04 16:32:43 +0200
commit823471134fca2901f15cfd05a1e9094f9136cb1c (patch)
tree50b04654280d34dbd112fdbe915ce63741ee2a36 /testcases/kernel/mem
parent8046928a2b4d74d7c10bab96c9e291f6cb2ba60a (diff)
downloadltp-823471134fca2901f15cfd05a1e9094f9136cb1c.tar.gz
mtest05/mmstress: fix writes operation logic
While generating tmpfiles, the map_and_thread() function does not handle properly incomplete writes that happen to return having written fewer bytes than requested and instead considers such condition an error straight away: this behavior hides real errors on writes and results in far from friendly error reports like these: mmstress 0 TINFO : test1: Test case tests the race condition... map_and_thread(): write(): Success mmstress 1 TFAIL : mmstress.c:625: TEST 1 Failed Fix the logic around such write() to allow for incomplete writes to be properly retried till a real error condition is returned so that a more meaningful report can be generated: mmstress 0 TINFO : test1: Test case tests the race condition... map_and_thread(): write(): No space left on device mmstress 1 TFAIL : mmstress.c:625: TEST 1 Failed While doing that, fix also a couple of minor unrelated issues in the same map_and_thread() function (malloc retval check and redundant close()) Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Diffstat (limited to 'testcases/kernel/mem')
-rw-r--r--testcases/kernel/mem/mtest05/mmstress.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/testcases/kernel/mem/mtest05/mmstress.c b/testcases/kernel/mem/mtest05/mmstress.c
index e5d0ce867..60d49417b 100644
--- a/testcases/kernel/mem/mtest05/mmstress.c
+++ b/testcases/kernel/mem/mtest05/mmstress.c
@@ -289,6 +289,8 @@ int map_and_thread(char *tmpfile,
static pthread_t pthread_ids[NUMTHREAD];
/* contains ids of the threads created */
void * map_addr = NULL; /* address where the file is mapped */
+ ssize_t written = 0;
+ ssize_t bytes;
/* Create a file with permissions 0666, and open it with RDRW perms */
/* if the name is not a NULL */
@@ -299,22 +301,38 @@ int map_and_thread(char *tmpfile,
S_IRWXO | S_IRWXU | S_IRWXG))
== -1) {
perror("map_and_thread(): open()");
- close(fd);
fflush(NULL);
return FAILED;
}
/* Write pagesize * pages_num bytes to the file */
empty_buf = malloc(pagesize * pages_num);
- if (write(fd, empty_buf, pagesize * pages_num) !=
- (pagesize * pages_num)) {
- perror("map_and_thread(): write()");
- free(empty_buf);
- fflush(NULL);
+ if (!empty_buf) {
+ perror("map_and_thread(): malloc()");
remove_files(tmpfile, NULL);
close(fd);
+ fflush(NULL);
return FAILED;
}
+
+ /* Writing fewer bytes than required is not an error so retry if
+ * fewer were written; if that happened due to some permanent
+ * error like ENOSPC the following retry will fail and a proper
+ * errno will be reported.
+ */
+ do {
+ bytes = write(fd, empty_buf + written,
+ pagesize * pages_num - written);
+ if (bytes < 0) {
+ perror("map_and_thread(): write()");
+ free(empty_buf);
+ fflush(NULL);
+ close(fd);
+ remove_files(tmpfile, NULL);
+ return FAILED;
+ }
+ written += bytes;
+ } while (written < pagesize * pages_num);
map_type = (fault_type == COW_FAULT) ? MAP_PRIVATE : MAP_SHARED;
/* Map the file, if the required fault type is COW_FAULT map the file */