4105aeef664b8e2c4de3bc3f79bbff6664325d32
[xfstests-dev.git] / src / godown.c
1 /*
2  * Copyright (c) 2004 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 "global.h"
20
21 /* These should be in libxfs.h */
22 #ifndef XFS_IOC_GOINGDOWN
23 #define XFS_IOC_GOINGDOWN           _IOR ('X', 125, __uint32_t)
24 #endif
25 #ifndef XFS_FSOP_GOING_FLAGS_DEFAULT
26 #define XFS_FSOP_GOING_FLAGS_DEFAULT    0x0     /* going down */
27 #endif
28 #ifndef XFS_FSOP_GOING_FLAGS_LOGFLUSH
29 #define XFS_FSOP_GOING_FLAGS_LOGFLUSH    0x1     /* flush log */
30 #endif
31 #ifndef XFS_FSOP_GOING_FLAGS_NOLOGFLUSH
32 #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH  0x2     /* don't flush log */
33 #endif
34
35 static char *xprogname;
36
37
38 static void
39 usage(void)
40 {
41         fprintf(stderr, "usage: %s [-f] [-v] mnt-dir\n", xprogname);
42 }
43
44 int
45 main(int argc, char *argv[])
46 {
47         int c;
48         int flag;
49         int flushlog_opt = 0;
50         int verbose_opt = 0;
51         struct stat st;
52         char *mnt_dir;
53         int fd;
54
55         xprogname = argv[0];
56
57         while ((c = getopt(argc, argv, "fv")) != -1) {
58                 switch (c) {
59                 case 'f':
60                         flushlog_opt = 1;
61                         break;
62                 case 'v':
63                         verbose_opt = 1;
64                         break;
65                 case '?':
66                         usage();
67                         return 1;
68                 }
69         }
70
71         /* process required cmd argument */
72         if (optind == argc-1) {
73                 mnt_dir = argv[optind];
74         }
75         else {
76                 usage();
77                 return 1;
78         }
79
80         if ((stat(mnt_dir, &st)) == -1) {
81                 fprintf(stderr, "%s: error on stat \"%s\": %s\n",
82                         xprogname, mnt_dir, strerror(errno));
83                 return 1;
84         }
85
86         if (!S_ISDIR(st.st_mode)) {
87                 fprintf(stderr, "%s: argument \"%s\" is not a directory\n",
88                         xprogname, mnt_dir);
89                 return 1;
90         }
91
92         
93 #if 0
94         {
95                 struct statvfs stvfs;
96                 if ((statvfs(mnt_dir, &stvfs)) == -1) {
97                         fprintf(stderr, "%s: error on statfs \"%s\": %s\n",
98                                 xprogname, mnt_dir, strerror(errno));
99                         return 1;
100                 }
101
102                 if (strcmp(stvfs.f_basetype, "xfs") != 0) {
103                         fprintf(stderr, "%s: filesys for \"%s\" is not XFS:\"%s\"\n",
104                                 xprogname, mnt_dir, stvfs.f_basetype);
105                         return 1;
106                 }
107         }
108 #endif
109
110
111         flag = (flushlog_opt ? XFS_FSOP_GOING_FLAGS_LOGFLUSH 
112                             : XFS_FSOP_GOING_FLAGS_NOLOGFLUSH);
113
114         if (verbose_opt) {
115                 printf("Opening \"%s\"\n", mnt_dir);
116         }
117         if ((fd = open(mnt_dir, O_RDONLY)) == -1) {
118                 fprintf(stderr, "%s: error on open of \"%s\": %s\n",
119                         xprogname, mnt_dir, strerror(errno));
120                 return 1;
121         }
122
123         if (verbose_opt) {
124                 printf("Calling XFS_IOC_GOINGDOWN\n");
125         }
126         if ((xfsctl(mnt_dir, fd, XFS_IOC_GOINGDOWN, &flag)) == -1) {
127                 fprintf(stderr, "%s: error on xfsctl(GOINGDOWN) of \"%s\": %s\n",
128                         xprogname, mnt_dir, strerror(errno));
129                 return 1;
130         }
131
132         close(fd);
133
134         return 0;
135 }