summaryrefslogtreecommitdiff
path: root/src/trunc.c
blob: 5f940b66a9636fcf47a4af186a7f8ed6d98408fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
 * All Rights Reserved.
 */

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef O_DIRECT
#define O_DIRECT	040000
#endif

#define WAITTIME	60
#define BUFSIZE		4096
#define ALIGNMENT	16384
#define TRUNCSIZE	1000

/* write data to disk - buffered/sync or direct
 * write different buffered data to disk
 * truncate
 * direct read back, see if server puts stale data down
 */

int
main(argc, argv)
int	argc;
char	**argv;
{
	int fd, err, elapsed;
	char *buf = NULL, *goodbuf = NULL;
	time_t starttime;
        char *filename="testfile";
	int c;

	if (argc != 3) {
		printf("Usage: trunc -f testfilename\n");
		exit(1);
        }

	while((c=getopt(argc,argv,"f:"))!=EOF) {
		switch (c) {
		case 'f':
			filename = optarg;
			break;
		default:
			fprintf(stderr,"Usage: trunc -f filename\n");
			exit(1);
		}
	}

	err = posix_memalign((void **)&buf, ALIGNMENT, BUFSIZE);
	if (err)
		fprintf(stderr, "posix_memalign failed: %s\n", strerror(err));

	err = posix_memalign((void **)&goodbuf, ALIGNMENT, BUFSIZE);
	if (err)
		fprintf(stderr, "posix_memalign failed: %s\n", strerror(err));

	err = unlink(filename);
/*	if (err < 0) perror("unlink failed");*/
        
	fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
	if (fd < 0) perror("direct open failed");

	memset(buf, 1, BUFSIZE);

	printf("direct write of 1's into file\n");	
	err = write(fd, buf, BUFSIZE);
	if (err < 0) perror("direct write failed");

	close(fd);
	
	fd = open(filename, O_CREAT|O_RDWR, 0666);
	if (fd < 0) perror("buffered open failed");

	/* 1 now on disk */

	memset(buf, 2, BUFSIZE);
	memset(goodbuf, 2, BUFSIZE);

	printf("buffered write of 2's into file\n");	
	err = write(fd, buf, BUFSIZE);
	if (err < 0) perror("buffered write failed");

	/* 1 now on disk, but 2 data is buffered */

	printf("truncate file\n");
	err = ftruncate(fd, TRUNCSIZE);
	if (err < 0) perror("ftruncate failed");
	starttime = time(NULL);

	printf("sync buffered data (2's)\n");
	err = fdatasync(fd);
	if (err < 0) perror("fdatasync failed");

	/* during truncate server may have read/modified/written last block */

	close(fd);

	fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0666);
	if (fd < 0) perror("direct open failed");

	/* read what's really on disk now */

	printf("iterate direct reads for %ds or until failure...\n", WAITTIME);

	while ((elapsed = (time(NULL) - starttime)) <= WAITTIME) {

		/* printf(".");
		fflush(stdout);*/

		err = lseek(fd, 0, SEEK_SET);
		if (err < 0) perror("lseek failed");

		err = read(fd, buf, BUFSIZE);
		if (err < 0) perror("read failed");

		err = memcmp(buf, goodbuf, 100);
		if (err) {
			printf("\nFailed after %d secs: read %d's\n", elapsed, buf[0]); 
			return 1;
		}

		sleep(1);
	}
	
	free(buf);
	free(goodbuf);

	printf("Passed\n");
	return 0;
}