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