]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libhandle/handle.c
Update copyright dates
[thirdparty/xfsprogs-dev.git] / libhandle / handle.c
1 /*
2 * Copyright (c) 1995, 2001-2002 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.1 of the GNU Lesser General Public License
6 * as 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 Lesser General Public
20 * License along with this program; if not, write the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
22 * USA.
23 *
24 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
25 * Mountain View, CA 94043, or:
26 *
27 * http://www.sgi.com
28 *
29 * For further information regarding this notice, see:
30 *
31 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
32 */
33
34 #include <libxfs.h>
35 #include <sys/stat.h>
36 #include <sys/ioctl.h>
37
38 /* attributes.h (purposefully) unavailable to xfsprogs, make do */
39 struct attrlist_cursor { __u32 opaque[4]; };
40
41 #include <handle.h>
42
43 /* just pick a value we know is more than big enough */
44 #define MAXHANSIZ 64
45
46 /*
47 * The actual content of a handle is supposed to be opaque here.
48 * But, to do handle_to_fshandle, we need to know what it is. Sigh.
49 * However we can get by with knowing only that the first 8 bytes of
50 * a file handle are the file system ID, and that a file system handle
51 * consists of only those 8 bytes.
52 */
53
54 #define FSIDSIZE 8
55
56 typedef union {
57 int fd;
58 char *path;
59 } comarg_t;
60
61 int
62 obj_to_handle (
63 int fsfd,
64 unsigned int opcode,
65 comarg_t obj,
66 void **hanp,
67 size_t *hlen);
68
69
70 /*
71 * Filesystem Handle -> Open File Descriptor Cache
72 *
73 * Maps filesystem handles to a corresponding open file descriptor for that
74 * filesystem. We need this because we're doing handle operations via ioctl
75 * and we need to remember the open file descriptor for each filesystem.
76 */
77
78 struct fdhash {
79 int fsfd;
80 char fsh[FSIDSIZE];
81 struct fdhash *fnxt;
82 };
83
84 struct fdhash *fdhash_head = NULL;
85
86 int
87 path_to_fshandle (
88 char *path, /* input, path to convert */
89 void **hanp, /* output, pointer to data */
90 size_t *hlen) /* output, size of returned data */
91 {
92 int result;
93 int fd;
94 comarg_t obj;
95 struct fdhash *fdhp;
96
97 fd = open(path, O_RDONLY);
98
99 if (fd < 0) {
100 perror(path);
101 exit(1);
102 }
103
104 obj.path = path;
105
106 result = obj_to_handle (fd, XFS_IOC_PATH_TO_FSHANDLE,
107 obj, hanp, hlen);
108
109 if (result >= 0) {
110 fdhp = malloc(sizeof(struct fdhash));
111
112 if (fdhp == NULL) {
113 errno = ENOMEM;
114 return -1;
115 }
116
117 fdhp->fsfd = fd;
118 fdhp->fnxt = NULL;
119
120 memcpy(fdhp->fsh, *hanp, FSIDSIZE);
121
122 if (fdhash_head)
123 fdhash_head->fnxt = fdhp;
124 else
125 fdhash_head = fdhp;
126 }
127
128 return result;
129 }
130
131
132 int
133 path_to_handle (
134 char *path, /* input, path to convert */
135 void **hanp, /* output, pointer to data */
136 size_t *hlen) /* output, size of returned data */
137 {
138 int fd;
139 int result;
140 comarg_t obj;
141
142 fd = open(path, O_RDONLY);
143
144 if (fd < 0) {
145 perror(path);
146 exit(1);
147 }
148
149 obj.path = path;
150
151 result = obj_to_handle (fd, XFS_IOC_PATH_TO_HANDLE, obj, hanp, hlen);
152
153 close(fd);
154
155 return result;
156 }
157
158
159 int
160 fd_to_handle (
161 int fd, /* input, file descriptor */
162 void **hanp, /* output, pointer to data */
163 size_t *hlen) /* output, size of returned data */
164 {
165 comarg_t obj;
166
167 obj.fd = fd;
168
169 return obj_to_handle (fd, XFS_IOC_FD_TO_HANDLE, obj, hanp, hlen);
170 }
171
172
173 int
174 handle_to_fshandle (
175 void *hanp,
176 size_t hlen,
177 void **fshanp,
178 size_t *fshlen)
179 {
180 if (hlen < FSIDSIZE)
181 return EINVAL;
182
183 *fshanp = malloc (FSIDSIZE);
184
185 if (*fshanp == NULL)
186 return ENOMEM;
187
188 *fshlen = FSIDSIZE;
189
190 memcpy(*fshanp, hanp, FSIDSIZE);
191
192 return 0;
193 }
194
195
196 int
197 handle_to_fsfd(void *hanp)
198 {
199 struct fdhash *fdhp;
200
201 for (fdhp = fdhash_head; fdhp != NULL; fdhp = fdhp->fnxt) {
202 if (memcmp(fdhp->fsh, hanp, FSIDSIZE) == 0)
203 return fdhp->fsfd;
204 }
205 return -1;
206 }
207
208
209 int
210 obj_to_handle (
211 int fsfd,
212 unsigned int opcode,
213 comarg_t obj,
214 void **hanp,
215 size_t *hlen)
216 {
217 char hbuf [MAXHANSIZ];
218 int ret;
219 xfs_fsop_handlereq_t hreq;
220
221 if (opcode == XFS_IOC_FD_TO_HANDLE) {
222 hreq.fd = obj.fd;
223 hreq.path = NULL;
224 } else {
225 hreq.fd = 0;
226 hreq.path = obj.path;
227 }
228
229 hreq.oflags = O_LARGEFILE;
230 hreq.ihandle = NULL;
231 hreq.ihandlen = 0;
232 hreq.ohandle = hbuf;
233 hreq.ohandlen = (__u32 *)hlen;
234
235 ret = (int) ioctl(fsfd, opcode, &hreq);
236
237 if (ret)
238 return ret;
239
240 *hanp = malloc(*hlen);
241
242 if (*hanp == NULL) {
243 errno = ENOMEM;
244 return -1;
245 }
246
247 memcpy(*hanp, hbuf, (int) *hlen);
248
249 return 0;
250 }
251
252
253
254 int
255 open_by_handle (
256 void *hanp,
257 size_t hlen,
258 int rw)
259 {
260 int fd;
261 int result;
262 xfs_fsop_handlereq_t hreq;
263
264 if ((fd = handle_to_fsfd(hanp)) < 0) {
265 errno = EBADF;
266 return -1;
267 }
268
269 hreq.fd = 0;
270 hreq.path = NULL;
271 hreq.oflags = rw | O_LARGEFILE;
272 hreq.ihandle = hanp;
273 hreq.ihandlen = hlen;
274 hreq.ohandle = NULL;
275 hreq.ohandlen = NULL;
276
277 result = ioctl(fd, XFS_IOC_OPEN_BY_HANDLE, &hreq);
278
279 return result;
280 }
281
282 int
283 readlink_by_handle (
284 void *hanp,
285 size_t hlen,
286 void *buf,
287 size_t bufsiz)
288 {
289 int fd;
290 xfs_fsop_handlereq_t hreq;
291
292
293 if ((fd = handle_to_fsfd(hanp)) < 0) {
294 errno = EBADF;
295 return -1;
296 }
297
298 hreq.fd = 0;
299 hreq.path = NULL;
300 hreq.oflags = O_LARGEFILE;
301 hreq.ihandle = hanp;
302 hreq.ihandlen = hlen;
303 hreq.ohandle = buf;
304 hreq.ohandlen = (__u32 *)&bufsiz;
305
306 return (int) ioctl(fd, XFS_IOC_READLINK_BY_HANDLE, &hreq);
307 }
308
309 int
310 attr_multi_by_handle(
311 void *hanp,
312 size_t hlen,
313 void *buf,
314 int rtrvcnt,
315 int flags)
316 {
317 int fd;
318 xfs_fsop_attrmulti_handlereq_t amhreq;
319
320 if ((fd = handle_to_fsfd(hanp)) < 0) {
321 errno = EBADF;
322 return -1;
323 }
324
325 amhreq.hreq.fd = 0;
326 amhreq.hreq.path = NULL;
327 amhreq.hreq.oflags = O_LARGEFILE;
328 amhreq.hreq.ihandle = hanp;
329 amhreq.hreq.ihandlen = hlen;
330 amhreq.hreq.ohandle = NULL;
331 amhreq.hreq.ohandlen = NULL;
332
333 amhreq.opcount = rtrvcnt;
334 amhreq.ops = buf;
335
336 return (int) ioctl(fd, XFS_IOC_ATTRMULTI_BY_HANDLE, &amhreq);
337 }
338
339 int
340 attr_list_by_handle(
341 void *hanp,
342 size_t hlen,
343 void *buf,
344 size_t bufsize,
345 int flags,
346 struct attrlist_cursor *cursor)
347 {
348 int fd;
349 xfs_fsop_attrlist_handlereq_t alhreq;
350
351 if ((fd = handle_to_fsfd(hanp)) < 0) {
352 errno = EBADF;
353 return -1;
354 }
355
356 alhreq.hreq.fd = 0;
357 alhreq.hreq.path = NULL;
358 alhreq.hreq.oflags = O_LARGEFILE;
359 alhreq.hreq.ihandle = hanp;
360 alhreq.hreq.ihandlen = hlen;
361 alhreq.hreq.ohandle = NULL;
362 alhreq.hreq.ohandlen = NULL;
363
364 memcpy(&alhreq.pos, cursor, sizeof(alhreq.pos));
365 alhreq.flags = flags;
366 alhreq.buflen = bufsize;
367 alhreq.buffer = buf;
368
369 return (int) ioctl(fd, XFS_IOC_ATTRLIST_BY_HANDLE, &alhreq);
370 }
371
372 int
373 fssetdm_by_handle (
374 void *hanp,
375 size_t hlen,
376 struct fsdmidata *fsdmidata)
377 {
378 int fd;
379 xfs_fsop_setdm_handlereq_t dmhreq;
380
381
382 if ((fd = handle_to_fsfd(hanp)) < 0) {
383 errno = EBADF;
384 return -1;
385 }
386
387 dmhreq.hreq.fd = 0;
388 dmhreq.hreq.path = NULL;
389 dmhreq.hreq.oflags = O_LARGEFILE;
390 dmhreq.hreq.ihandle = hanp;
391 dmhreq.hreq.ihandlen = hlen;
392 dmhreq.hreq.ohandle = NULL;
393 dmhreq.hreq.ohandlen = NULL;
394
395 dmhreq.data = fsdmidata;
396
397 return (int) ioctl(fd, XFS_IOC_FSSETDM_BY_HANDLE, &dmhreq);
398 }
399
400 /*ARGSUSED*/
401 void
402 free_handle (
403 void *hanp,
404 size_t hlen)
405 {
406 free (hanp);
407 }