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