6b4d0b6cb5efa1b66025205474221206b7824195
[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         Progname = strrchr(argv[0], '/');
112         if (Progname) {
113                 Progname++;
114         } else {
115                 Progname = argv[0];
116         }
117
118         /* Crack and validate the command line options. */
119
120         while ((opt = getopt(argc, argv, "o:l:s:xp")) != EOF) {
121                 switch (opt) {
122                 case 'o':
123                         offset = strtoll(optarg, &p, 10);
124                         if (p && (*p == 'k' || *p == 'K'))
125                                 offset *= 1024;
126                         break;
127                 case 'l':
128                         length = strtoll(optarg, &p, 10);
129                         if (p && (*p == 'k' || *p == 'K'))
130                                 length *= 1024;
131                         break;
132                 case 's':
133                         sid = atol(optarg);
134                         break;
135                 case 'x':
136                         method = METHOD_XFSCTL;
137                         break;
138                 case 'p':
139                         method = METHOD_DMAPI_PUNCH;
140                         break;
141                 case '?':
142                         usage();
143                 }
144         }
145         if (optind + 1 != argc)
146                 usage();
147         pathname = argv[optind];
148
149         if (!pathname)
150                 usage();
151
152         printf("Running %s on %s with settings:\n", methodmap[method], pathname);
153         printf("  offset = '%lld', length = '%lld', sid = '%lld'\n",
154                 (long long) offset, (unsigned long long) length, (long long) sid);
155         
156         if (method ==  METHOD_XFSCTL) 
157                 return xfsctl_punch_hole(pathname, offset, length);
158         
159         if (dm_init_service(&name) == -1)  {
160                 fprintf(stderr, "Can't initialize the DMAPI\n");
161                 exit(1);
162         }
163         if (sid == DM_NO_SESSION)
164                 find_test_session(&sid);
165         
166         /* Get the file's handle. */
167         
168         if (dm_path_to_handle(pathname, &hanp, &hlen)) {
169                 fprintf(stderr, "can't get handle for file %s\n", pathname);
170                 exit(1);
171         }
172         
173         switch(method) {
174         case METHOD_DMAPI_PROBE:
175                 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
176                                   &roffp, &rlenp)) {
177                         fprintf(stderr, "dm_probe_hole failed, %s\n",
178                                 strerror(errno));
179                         exit(1);
180                 }
181                 fprintf(stdout, "roffp is %lld, rlenp is %llu\n",
182                         (long long) roffp, (unsigned long long) rlenp);
183                 break;
184         case METHOD_DMAPI_PUNCH:
185                 if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length)) {
186                         fprintf(stderr, "dm_punch_hole failed, %s\n",
187                                 strerror(errno));
188                         exit(1);
189                 }
190                 break;                  
191         }
192         dm_handle_free(hanp, hlen);
193         
194         return 0;
195 }