effa98a45a2fe8a74593c0eba8c31aa8b1af4ee2
[xfstests-dev.git] / dmapi / src / suite1 / cmd / probe_punch_xfsctl_hole.c
1 /*
2  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would 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, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include <lib/hsm.h>
20
21 #include <getopt.h>
22 #include <string.h>
23
24
25 /*---------------------------------------------------------------------------
26
27 Test program used to test the DMAPI function dm_probe_hole().  The
28 command line is:
29
30         probe_hole [-o offset] [-l length] [-s sid] pathname
31
32 where pathname is the name of a file, offset is the offset of the start of
33 the proposed punch, and length is the length of the punch.  sid is the
34 session ID whose events you you are interested in.
35
36 ----------------------------------------------------------------------------*/
37
38 #ifndef linux
39 extern  char    *sys_errlist[];
40 #endif
41 extern  int     optind;
42 extern  char    *optarg;
43
44
45 char    *Progname;
46
47 #define METHOD_DMAPI_PROBE      0
48 #define METHOD_DMAPI_PUNCH      1
49 #define METHOD_XFSCTL           2
50
51 char *methodmap[] = {"DMAPI probe hole",
52                      "DMAPI punch hole",
53                      "Punch hole with xfsctl(XFS_IOC_FREESP64)"};
54
55 static void
56 usage(void)
57 {
58         fprintf(stderr, "usage:\t%s [-x|-p] [-o offset] [-l length] "
59                 "[-s sid] pathname\n", Progname);
60         exit(1);
61 }
62
63 int
64 xfsctl_punch_hole(
65                   char          *path,
66                   dm_off_t      offset,
67                   dm_size_t     length)
68 {
69         xfs_flock64_t   flock;
70         int             fd;
71         
72         if ((fd = open(path, O_RDWR|O_CREAT)) < 0) {
73                 perror(path);
74                 exit(errno);
75         }
76
77         flock.l_whence = 0;
78         flock.l_start = offset;
79         flock.l_len = length; 
80
81         if (xfsctl(path, fd, XFS_IOC_FREESP64, &flock)) {
82                 fprintf(stderr, "can't XFS_IOC_FREESP64 %s: %s\n",
83                         path, strerror(errno));
84                 return errno;
85         }
86         
87         close(fd);
88
89         printf("ok.\n");
90         return 0;
91 }
92
93 int
94 main(
95         int     argc, 
96         char    **argv)
97 {
98         dm_sessid_t     sid = DM_NO_SESSION;
99         char            *pathname = NULL;
100         dm_off_t        offset = 0;
101         dm_size_t       length = 0;
102         dm_off_t        roffp;
103         dm_size_t       rlenp;
104         void            *hanp;
105         size_t          hlen;
106         char            *name;
107         char            *p;
108         int             opt;
109         int             method = METHOD_DMAPI_PROBE;
110
111         if (Progname = strrchr(argv[0], '/')) {
112                 Progname++;
113         } else {
114                 Progname = argv[0];
115         }
116
117         /* Crack and validate the command line options. */
118
119         while ((opt = getopt(argc, argv, "o:l:s:xp")) != EOF) {
120                 switch (opt) {
121                 case 'o':
122                         offset = strtoll(optarg, &p, 10);
123                         if (p && (*p == 'k' || *p == 'K'))
124                                 offset *= 1024;
125                         break;
126                 case 'l':
127                         length = strtoll(optarg, &p, 10);
128                         if (p && (*p == 'k' || *p == 'K'))
129                                 length *= 1024;
130                         break;
131                 case 's':
132                         sid = atol(optarg);
133                         break;
134                 case 'x':
135                         method = METHOD_XFSCTL;
136                         break;
137                 case 'p':
138                         method = METHOD_DMAPI_PUNCH;
139                         break;
140                 case '?':
141                         usage();
142                 }
143         }
144         if (optind + 1 != argc)
145                 usage();
146         pathname = argv[optind];
147
148         if (!pathname)
149                 usage();
150
151         printf("Running %s on %s with settings:\n", methodmap[method], pathname);
152         printf("  offset = '%lld', length = '%lld', sid = '%lld'\n", offset, length, sid);
153         
154         if (method ==  METHOD_XFSCTL) 
155                 return xfsctl_punch_hole(pathname, offset, length);
156         
157         if (dm_init_service(&name) == -1)  {
158                 fprintf(stderr, "Can't initialize the DMAPI\n");
159                 exit(1);
160         }
161         if (sid == DM_NO_SESSION)
162                 find_test_session(&sid);
163         
164         /* Get the file's handle. */
165         
166         if (dm_path_to_handle(pathname, &hanp, &hlen)) {
167                 fprintf(stderr, "can't get handle for file %s\n", pathname);
168                 exit(1);
169         }
170         
171         switch(method) {
172         case METHOD_DMAPI_PROBE:
173                 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
174                                   &roffp, &rlenp)) {
175                         fprintf(stderr, "dm_probe_hole failed, %s\n",
176                                 strerror(errno));
177                         exit(1);
178                 }
179                 fprintf(stdout, "roffp is %lld, rlenp is %lld\n", roffp, rlenp);
180                 break;
181         case METHOD_DMAPI_PUNCH:
182                 if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length)) {
183                         fprintf(stderr, "dm_punch_hole failed, %s\n",
184                                 strerror(errno));
185                         exit(1);
186                 }
187                 break;                  
188         }
189         dm_handle_free(hanp, hlen);
190         
191         return 0;
192 }