]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | #include <sys/types.h> | |
5 | #include <asm/types.h> | |
6 | #include <sys/stat.h> | |
7 | #include <sys/ioctl.h> | |
8 | #include <fcntl.h> | |
9 | ||
10 | #include "common/safe_io.h" | |
11 | #include "os/btrfs_ioctl.h" | |
12 | ||
13 | void do_open_wr(const char *fname, int *fd) | |
14 | { | |
15 | *fd = open(fname, O_WRONLY | O_CREAT, 0644); | |
16 | if (*fd < 0) { | |
17 | perror("open"); | |
18 | exit(1); | |
19 | } | |
20 | } | |
21 | ||
22 | void do_open_rd(const char *fname, int *fd) | |
23 | { | |
24 | *fd = open(fname, O_RDONLY); | |
25 | if (*fd < 0) { | |
26 | perror("open"); | |
27 | exit(1); | |
28 | } | |
29 | } | |
30 | ||
31 | void do_lseek(int fd, int ofs) | |
32 | { | |
33 | int rc = lseek(fd, ofs, SEEK_SET); | |
34 | if (rc < 0) { | |
35 | perror("lseek"); | |
36 | exit(1); | |
37 | } | |
38 | } | |
39 | ||
40 | void do_write(int fd, int len) | |
41 | { | |
42 | char *buf = malloc(len); | |
43 | int rc; | |
44 | if (!buf) { | |
45 | printf("not enough memory\n"); | |
46 | exit(1); | |
47 | } | |
48 | ||
49 | memset(buf, 0, len); | |
50 | rc = safe_write(fd, buf, len); | |
51 | if (rc) { | |
52 | fprintf(stderr, "safe_write failed with error %d (%s)\n", | |
53 | rc, strerror(rc)); | |
54 | exit(1); | |
55 | } | |
56 | ||
57 | if (rc != len) { | |
58 | printf("invalid number of bytes written\n"); | |
59 | exit(1); | |
60 | } | |
61 | ||
62 | free(buf); | |
63 | } | |
64 | ||
65 | void do_link(const char *old, const char *new) | |
66 | { | |
67 | int rc = link(old, new); | |
68 | if (rc < 0) { | |
69 | perror("link"); | |
70 | exit(1); | |
71 | } | |
72 | } | |
73 | ||
74 | void do_clone_range(int from, int to, int off, int len) | |
75 | { | |
76 | struct btrfs_ioctl_clone_range_args a; | |
77 | int r; | |
78 | ||
79 | a.src_fd = from; | |
80 | a.src_offset = off; | |
81 | a.src_length = len; | |
82 | a.dest_offset = off; | |
83 | r = ioctl(to, BTRFS_IOC_CLONE_RANGE, &a); | |
84 | if (r < 0) { | |
85 | perror("ioctl"); | |
86 | exit(1); | |
87 | } | |
88 | } | |
89 | ||
90 | void do_snap_async(int fd, const char *name, unsigned long long *transid) | |
91 | { | |
92 | struct btrfs_ioctl_async_vol_args async_args; | |
93 | struct btrfs_ioctl_vol_args volargs; | |
94 | int r; | |
95 | ||
96 | strcpy(volargs.name, name); | |
97 | volargs.fd = fd; | |
98 | ||
99 | async_args.args = &volargs; | |
100 | async_args.transid = transid; | |
101 | ||
102 | r = ioctl(fd, BTRFS_IOC_SNAP_CREATE_ASYNC, &async_args); | |
103 | ||
104 | if (r < 0) { | |
105 | perror("ioctl"); | |
106 | exit(1); | |
107 | } | |
108 | } | |
109 | ||
110 | void do_snap_destroy(int fd, const char *name) | |
111 | { | |
112 | struct btrfs_ioctl_vol_args volargs; | |
113 | int r; | |
114 | ||
115 | strcpy(volargs.name, name); | |
116 | volargs.fd = 0; | |
117 | ||
118 | r = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &volargs); | |
119 | ||
120 | if (r < 0) { | |
121 | perror("snap_destroy: ioctl"); | |
122 | exit(1); | |
123 | } | |
124 | } | |
125 | ||
126 | void do_snap_wait(int fd, unsigned long long transid) | |
127 | { | |
128 | int r = ioctl(fd, BTRFS_IOC_WAIT_SYNC, &transid); | |
129 | if (r < 0) { | |
130 | perror("do_snap_wait: ioctl"); | |
131 | exit(1); | |
132 | } | |
133 | } | |
134 | ||
135 | void usage_exit(char *arg) | |
136 | { | |
137 | printf("usage: %s <btrfs_base> <snap_name>\n", arg); | |
138 | exit(1); | |
139 | } | |
140 | ||
141 | #define TEMP_FILENAME "temp" | |
142 | #define DEST_FILENAME "dest" | |
143 | #define SRC_FILENAME "src" | |
144 | ||
145 | int main(int argc, char *argv[]) | |
146 | { | |
147 | const char *base_dir; | |
148 | const char *snap_name; | |
149 | ||
150 | int fd; | |
151 | int i; | |
152 | unsigned long long transid; | |
153 | ||
154 | if (argc < 3) | |
155 | usage_exit(argv[0]); | |
156 | ||
157 | base_dir = argv[1]; | |
158 | snap_name = argv[2]; | |
159 | ||
160 | for (i=0; i<10; i++) { | |
161 | printf("%d\n", i); | |
162 | do_open_rd(base_dir, &fd); | |
163 | do_snap_async(fd, snap_name, &transid); | |
164 | sleep(2); | |
165 | //do_snap_wait(fd, transid); | |
166 | do_snap_destroy(fd, snap_name); | |
167 | close(fd); | |
168 | } | |
169 | ||
170 | return 0; | |
171 | } |