fsstress: translate flags in fiemap_f
[xfstests-dev.git] / src / open_unlink.c
1 /*
2  * Copyright (c) 2005 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 #include <stdlib.h>
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <sys/attributes.h>
27 #include <sys/fs/xfs_itable.h>
28
29 #ifndef ATTR_PARENT
30 #define ATTR_PARENT 0x0040
31 #endif
32
33 #define EA_LISTBUF_SZ 16384
34
35 int
36 main(int argc, char *argv[])
37 {
38         char *path;
39         int fd;
40         char *prog = argv[0];
41         void *handle;
42         size_t hlen;
43         attrlist_cursor_t cursor;
44         attrlist_t *ea_listbuf = (attrlist_t *)malloc(EA_LISTBUF_SZ);
45         uint64_t parent_ino;
46         uint64_t link_cnt;
47         int sts;
48         int nameix;
49         attrlist_ent_t *entp;
50
51         if (argc < 2) {
52                 fprintf(stderr, "%s: missing pathname argument\n", prog);
53                 return 1;
54         }
55         path = argv[1];
56
57         if (argc > 2) {
58                 fprintf(stderr, "%s: too many arguments\n", prog);
59                 return 1;
60         }
61
62         /* if file already exists then error out */
63         if (access(path, F_OK) == 0) {
64                 fprintf(stderr, "%s: file \"%s\" already exists\n", prog, path);
65                 return 1;
66         }
67
68         fd = open(path, O_RDWR|O_CREAT|O_EXCL);
69         if (fd == -1) {
70                 fprintf(stderr, "%s: failed to create \"%s\": %s\n", prog, path, strerror(errno));
71                 return 1;
72         }
73
74
75         /* for linux libhandle version - to set libhandle fsfd cache */
76         {
77                 void *fshandle;
78                 size_t fshlen;
79
80                 if (path_to_fshandle(path, &fshandle, &fshlen) != 0) {
81                         fprintf(stderr, "%s: failed path_to_fshandle \"%s\": %s\n",
82                                 prog, path, strerror(errno));
83                         return 1;
84                 }
85         }
86
87
88         /* 
89          * look at parentptr EAs and see if the path exists now that
90          * it has been unlinked.
91          */ 
92         if (fd_to_handle(fd, &handle, &hlen) != 0) {
93                 fprintf(stderr, "%s: failed to fd_to_handle \"%s\": %s\n",
94                         prog, path, strerror(errno));
95                 return 1;
96         }
97
98         if (unlink(path) == -1) {
99                 fprintf(stderr, "%s: failed to unlink \"%s\": %s\n", prog, path, strerror(errno));
100                 return 1;
101         }
102
103         memset(&cursor, 0, sizeof(cursor));
104
105         /* just do one call - don't bother with continue logic */
106         sts = attr_list_by_handle(handle,
107                         hlen,
108                         (char*)ea_listbuf,
109                         EA_LISTBUF_SZ,
110                         ATTR_PARENT,
111                         &cursor);
112         if (sts != 0) {
113                 fprintf(stderr, "%s: failed to list attr for \"%s\": %s\n", prog, path, strerror(errno));
114                 return 1;
115         }
116
117         printf("ea count = %d\n", ea_listbuf->al_count);
118
119         /*
120          * process EA list
121          */
122         for (nameix = 0; nameix < ea_listbuf->al_count; nameix++) {
123                 entp = ATTR_ENTRY(ea_listbuf, nameix);
124
125                 sts = sscanf(entp->a_name, "%llx %llx", &parent_ino, &link_cnt);
126                 if (sts != 2) {
127                         fprintf(stderr,
128                                 "inode-path for \"%s\" is corrupted\n",
129                                 path);
130
131                         /* go onto next EA name */
132                         continue;
133                 }
134                 /* just print the info out */
135                 printf("[%d] parent_ino = %llu, link_cnt = %llu\n", nameix, parent_ino, link_cnt);
136         }
137
138
139         free_handle(handle, hlen);
140
141         if (close(fd) == -1) {
142                 fprintf(stderr, "%s: failed to close \"%s\": %s\n", prog, path, strerror(errno));
143                 return 1;
144         }
145
146         return 0;
147 }