]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libhandle/handle.c
Undoes mod: xfs-cmds:slinx:120772a
[thirdparty/xfsprogs-dev.git] / libhandle / handle.c
CommitLineData
e9688c1d 1/*
9911e5dc 2 * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
7c49c48b 3 *
e9688c1d 4 * This program is free software; you can redistribute it and/or modify it
7c49c48b
DR
5 * under the terms of version 2.1 of the GNU Lesser General Public License
6 * as published by the Free Software Foundation.
7 *
e9688c1d
NS
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.
7c49c48b 11 *
e9688c1d
NS
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.
7c49c48b
DR
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 *
e9688c1d
NS
24 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
25 * Mountain View, CA 94043, or:
7c49c48b
DR
26 *
27 * http://www.sgi.com
28 *
29 * For further information regarding this notice, see:
30 *
e9688c1d
NS
31 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
32 */
33
f91dde66 34#include <libxfs.h>
e9688c1d 35#include <sys/stat.h>
e9688c1d 36#include <sys/ioctl.h>
14290264
NS
37
38/* attributes.h (purposefully) unavailable to xfsprogs, make do */
39struct attrlist_cursor { __u32 opaque[4]; };
40
41#include <handle.h>
e9688c1d 42
e9688c1d
NS
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
56typedef union {
57 int fd;
58 char *path;
59} comarg_t;
60
89184fbc
AG
61int
62obj_to_handle (
63 int fsfd,
5b64e00a 64 unsigned int opcode,
89184fbc
AG
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 */
e9688c1d
NS
77
78struct fdhash {
79 int fsfd;
80 char fsh[FSIDSIZE];
81 struct fdhash *fnxt;
82};
83
84struct fdhash *fdhash_head = NULL;
85
86int
87path_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,
89184fbc 107 obj, hanp, hlen);
e9688c1d
NS
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
132int
133path_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
159int
160fd_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
173int
174handle_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
89184fbc
AG
196int
197handle_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
e9688c1d
NS
209int
210obj_to_handle (
211 int fsfd,
5b64e00a 212 unsigned int opcode,
e9688c1d
NS
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
489aaf4d 229 hreq.oflags = O_LARGEFILE;
e9688c1d
NS
230 hreq.ihandle = NULL;
231 hreq.ihandlen = 0;
232 hreq.ohandle = hbuf;
5b64e00a 233 hreq.ohandlen = (__u32 *)hlen;
e9688c1d
NS
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
89184fbc 253
e9688c1d
NS
254int
255open_by_handle (
256 void *hanp,
257 size_t hlen,
258 int rw)
259{
260 int fd;
261 int result;
e9688c1d
NS
262 xfs_fsop_handlereq_t hreq;
263
89184fbc 264 if ((fd = handle_to_fsfd(hanp)) < 0) {
e9688c1d
NS
265 errno = EBADF;
266 return -1;
267 }
268
269 hreq.fd = 0;
270 hreq.path = NULL;
489aaf4d 271 hreq.oflags = rw | O_LARGEFILE;
e9688c1d
NS
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
282int
283readlink_by_handle (
284 void *hanp,
285 size_t hlen,
286 void *buf,
287 size_t bufsiz)
288{
289 int fd;
e9688c1d
NS
290 xfs_fsop_handlereq_t hreq;
291
292
89184fbc 293 if ((fd = handle_to_fsfd(hanp)) < 0) {
e9688c1d
NS
294 errno = EBADF;
295 return -1;
296 }
297
298 hreq.fd = 0;
299 hreq.path = NULL;
489aaf4d 300 hreq.oflags = O_LARGEFILE;
e9688c1d
NS
301 hreq.ihandle = hanp;
302 hreq.ihandlen = hlen;
303 hreq.ohandle = buf;
5b64e00a 304 hreq.ohandlen = (__u32 *)&bufsiz;
e9688c1d
NS
305
306 return (int) ioctl(fd, XFS_IOC_READLINK_BY_HANDLE, &hreq);
307}
308
14290264
NS
309int
310attr_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;
489aaf4d 327 amhreq.hreq.oflags = O_LARGEFILE;
14290264
NS
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
339int
340attr_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;
489aaf4d 358 alhreq.hreq.oflags = O_LARGEFILE;
14290264
NS
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
e1864286
DR
372int
373fssetdm_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;
489aaf4d 389 dmhreq.hreq.oflags = O_LARGEFILE;
e1864286
DR
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
e9688c1d
NS
400/*ARGSUSED*/
401void
402free_handle (
403 void *hanp,
404 size_t hlen)
405{
406 free (hanp);
407}