]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libhandle/handle.c
Checked standards compliance - update standards version to 3.5.5.
[thirdparty/xfsprogs-dev.git] / libhandle / handle.c
CommitLineData
e9688c1d
NS
1/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
f91dde66 33#include <libxfs.h>
e9688c1d 34#include <sys/stat.h>
e9688c1d 35#include <sys/ioctl.h>
e9688c1d 36#include "handle.h"
e9688c1d 37
e9688c1d
NS
38/* just pick a value we know is more than big enough */
39#define MAXHANSIZ 64
40
41/*
42 * The actual content of a handle is supposed to be opaque here.
43 * But, to do handle_to_fshandle, we need to know what it is. Sigh.
44 * However we can get by with knowing only that the first 8 bytes of
45 * a file handle are the file system ID, and that a file system handle
46 * consists of only those 8 bytes.
47 */
48
49#define FSIDSIZE 8
50
51typedef union {
52 int fd;
53 char *path;
54} comarg_t;
55
89184fbc
AG
56
57int
58obj_to_handle (
59 int fsfd,
5b64e00a 60 unsigned int opcode,
89184fbc
AG
61 comarg_t obj,
62 void **hanp,
63 size_t *hlen);
64
65
66/*
67 * Filesystem Handle -> Open File Descriptor Cache
68 *
69 * Maps filesystem handles to a corresponding open file descriptor for that
70 * filesystem. We need this because we're doing handle operations via ioctl
71 * and we need to remember the open file descriptor for each filesystem.
72 */
e9688c1d
NS
73
74struct fdhash {
75 int fsfd;
76 char fsh[FSIDSIZE];
77 struct fdhash *fnxt;
78};
79
80struct fdhash *fdhash_head = NULL;
81
82int
83path_to_fshandle (
84 char *path, /* input, path to convert */
85 void **hanp, /* output, pointer to data */
86 size_t *hlen) /* output, size of returned data */
87{
88 int result;
89 int fd;
90 comarg_t obj;
91 struct fdhash *fdhp;
92
93 fd = open(path, O_RDONLY);
94
95 if (fd < 0) {
96 perror(path);
97 exit(1);
98 }
99
100 obj.path = path;
101
102 result = obj_to_handle (fd, XFS_IOC_PATH_TO_FSHANDLE,
89184fbc 103 obj, hanp, hlen);
e9688c1d
NS
104
105 if (result >= 0) {
106 fdhp = malloc(sizeof(struct fdhash));
107
108 if (fdhp == NULL) {
109 errno = ENOMEM;
110 return -1;
111 }
112
113 fdhp->fsfd = fd;
114 fdhp->fnxt = NULL;
115
116 memcpy(fdhp->fsh, *hanp, FSIDSIZE);
117
118 if (fdhash_head)
119 fdhash_head->fnxt = fdhp;
120 else
121 fdhash_head = fdhp;
122 }
123
124 return result;
125}
126
127
128int
129path_to_handle (
130 char *path, /* input, path to convert */
131 void **hanp, /* output, pointer to data */
132 size_t *hlen) /* output, size of returned data */
133{
134 int fd;
135 int result;
136 comarg_t obj;
137
138 fd = open(path, O_RDONLY);
139
140 if (fd < 0) {
141 perror(path);
142 exit(1);
143 }
144
145 obj.path = path;
146
147 result = obj_to_handle (fd, XFS_IOC_PATH_TO_HANDLE, obj, hanp, hlen);
148
149 close(fd);
150
151 return result;
152}
153
154
155int
156fd_to_handle (
157 int fd, /* input, file descriptor */
158 void **hanp, /* output, pointer to data */
159 size_t *hlen) /* output, size of returned data */
160{
161 comarg_t obj;
162
163 obj.fd = fd;
164
165 return obj_to_handle (fd, XFS_IOC_FD_TO_HANDLE, obj, hanp, hlen);
166}
167
168
169int
170handle_to_fshandle (
171 void *hanp,
172 size_t hlen,
173 void **fshanp,
174 size_t *fshlen)
175{
176 if (hlen < FSIDSIZE)
177 return EINVAL;
178
179 *fshanp = malloc (FSIDSIZE);
180
181 if (*fshanp == NULL)
182 return ENOMEM;
183
184 *fshlen = FSIDSIZE;
185
186 memcpy(*fshanp, hanp, FSIDSIZE);
187
188 return 0;
189}
190
191
89184fbc
AG
192int
193handle_to_fsfd(void *hanp)
194{
195 struct fdhash *fdhp;
196
197 for (fdhp = fdhash_head; fdhp != NULL; fdhp = fdhp->fnxt) {
198 if (memcmp(fdhp->fsh, hanp, FSIDSIZE) == 0)
199 return fdhp->fsfd;
200 }
201 return -1;
202}
203
204
e9688c1d
NS
205int
206obj_to_handle (
207 int fsfd,
5b64e00a 208 unsigned int opcode,
e9688c1d
NS
209 comarg_t obj,
210 void **hanp,
211 size_t *hlen)
212{
213 char hbuf [MAXHANSIZ];
214 int ret;
215 xfs_fsop_handlereq_t hreq;
216
217 if (opcode == XFS_IOC_FD_TO_HANDLE) {
218 hreq.fd = obj.fd;
219 hreq.path = NULL;
220 } else {
221 hreq.fd = 0;
222 hreq.path = obj.path;
223 }
224
225 hreq.oflags = 0;
226 hreq.ihandle = NULL;
227 hreq.ihandlen = 0;
228 hreq.ohandle = hbuf;
5b64e00a 229 hreq.ohandlen = (__u32 *)hlen;
e9688c1d
NS
230
231 ret = (int) ioctl(fsfd, opcode, &hreq);
232
233 if (ret)
234 return ret;
235
236 *hanp = malloc(*hlen);
237
238 if (*hanp == NULL) {
239 errno = ENOMEM;
240 return -1;
241 }
242
243 memcpy(*hanp, hbuf, (int) *hlen);
244
245 return 0;
246}
247
248
89184fbc 249
e9688c1d
NS
250int
251open_by_handle (
252 void *hanp,
253 size_t hlen,
254 int rw)
255{
256 int fd;
257 int result;
e9688c1d
NS
258 xfs_fsop_handlereq_t hreq;
259
89184fbc 260 if ((fd = handle_to_fsfd(hanp)) < 0) {
e9688c1d
NS
261 errno = EBADF;
262 return -1;
263 }
264
265 hreq.fd = 0;
266 hreq.path = NULL;
267 hreq.oflags = rw;
268 hreq.ihandle = hanp;
269 hreq.ihandlen = hlen;
270 hreq.ohandle = NULL;
271 hreq.ohandlen = NULL;
272
273 result = ioctl(fd, XFS_IOC_OPEN_BY_HANDLE, &hreq);
274
275 return result;
276}
277
278int
279readlink_by_handle (
280 void *hanp,
281 size_t hlen,
282 void *buf,
283 size_t bufsiz)
284{
285 int fd;
e9688c1d
NS
286 xfs_fsop_handlereq_t hreq;
287
288
89184fbc 289 if ((fd = handle_to_fsfd(hanp)) < 0) {
e9688c1d
NS
290 errno = EBADF;
291 return -1;
292 }
293
294 hreq.fd = 0;
295 hreq.path = NULL;
296 hreq.oflags = 0;
297 hreq.ihandle = hanp;
298 hreq.ihandlen = hlen;
299 hreq.ohandle = buf;
5b64e00a 300 hreq.ohandlen = (__u32 *)&bufsiz;
e9688c1d
NS
301
302 return (int) ioctl(fd, XFS_IOC_READLINK_BY_HANDLE, &hreq);
303}
304
305/*ARGSUSED*/
306void
307free_handle (
308 void *hanp,
309 size_t hlen)
310{
311 free (hanp);
312}