Home | History | Annotate | Download | only in fallocate
      1 /*
      2  * Copyright (c) 2017 Cyril Hrubis <chrubis (at) suse.cz>
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 2 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
     16  */
     17 
     18 /*
     19  * Tests that writing to fallocated file works when filesystem is full.
     20  */
     21 
     22 #define _GNU_SOURCE
     23 
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <errno.h>
     27 #include <fcntl.h>
     28 #include "tst_test.h"
     29 #include "lapi/fallocate.h"
     30 
     31 #define MNTPOINT "mntpoint"
     32 #define FALLOCATE_SIZE 8192
     33 
     34 static int fd;
     35 
     36 static void run(void)
     37 {
     38 	char buf[FALLOCATE_SIZE];
     39 	ssize_t ret;
     40 
     41 	fd = SAFE_OPEN(MNTPOINT "/test_file", O_WRONLY | O_CREAT);
     42 
     43 	if (fallocate(fd, 0, 0, FALLOCATE_SIZE)) {
     44 		if (errno == EOPNOTSUPP) {
     45 			tst_res(TCONF | TERRNO, "fallocate() not supported");
     46 			SAFE_CLOSE(fd);
     47 			return;
     48 		}
     49 
     50 		tst_brk(TBROK | TERRNO,
     51 			"fallocate(fd, 0, 0, %i)", FALLOCATE_SIZE);
     52 	}
     53 
     54 	tst_fill_fs(MNTPOINT, 1);
     55 
     56 	ret = write(fd, buf, sizeof(buf));
     57 
     58 	if (ret < 0)
     59 		tst_res(TFAIL | TERRNO, "write() failed unexpectedly");
     60 	else
     61 		tst_res(TPASS, "write() wrote %zu bytes", ret);
     62 
     63 	ret = fallocate(fd, 0, FALLOCATE_SIZE, FALLOCATE_SIZE);
     64 	if (ret != -1)
     65 		tst_brk(TFAIL, "fallocate() succeeded unexpectedly");
     66 
     67 	if (errno != ENOSPC)
     68 		tst_brk(TFAIL | TERRNO, "fallocate() should fail with ENOSPC");
     69 
     70 	tst_res(TPASS | TERRNO, "fallocate() on full FS");
     71 
     72 	ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE, 0, FALLOCATE_SIZE);
     73 	if (ret == -1) {
     74 		if (errno == EOPNOTSUPP)
     75 			tst_brk(TCONF, "fallocate(FALLOC_FL_PUNCH_HOLE)");
     76 
     77 		tst_brk(TBROK | TERRNO, "fallocate(FALLOC_FL_PUNCH_HOLE)");
     78 	}
     79 	tst_res(TPASS, "fallocate(FALLOC_FL_PUNCH_HOLE)");
     80 
     81 	ret = write(fd, buf, 10);
     82 	if (ret == -1)
     83 		tst_res(TFAIL | TERRNO, "write()");
     84 	else
     85 		tst_res(TPASS, "write()");
     86 
     87 	SAFE_CLOSE(fd);
     88 }
     89 
     90 static void cleanup(void)
     91 {
     92 	if (fd > 0)
     93 		SAFE_CLOSE(fd);
     94 }
     95 
     96 static struct tst_test test = {
     97 	.needs_root = 1,
     98 	.needs_tmpdir = 1,
     99 	.mount_device = 1,
    100 	.mntpoint = MNTPOINT,
    101 	.all_filesystems = 1,
    102 	.cleanup = cleanup,
    103 	.test_all = run,
    104 };
    105