]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/boot/zfs/zfs.c
MFC r241292: zfs loader: treat plain pool name as a name of its root
[FreeBSD/stable/9.git] / sys / boot / zfs / zfs.c
1 /*-
2  * Copyright (c) 2007 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $FreeBSD$
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 /*
33  *      Stand-alone file reading package.
34  */
35
36 #include <sys/param.h>
37 #include <sys/disklabel.h>
38 #include <sys/time.h>
39 #include <sys/queue.h>
40 #include <stddef.h>
41 #include <stdarg.h>
42 #include <string.h>
43 #include <stand.h>
44 #include <bootstrap.h>
45
46 #include "libzfs.h"
47
48 #include "zfsimpl.c"
49
50 static int      zfs_open(const char *path, struct open_file *f);
51 static int      zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
52 static int      zfs_close(struct open_file *f);
53 static int      zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
54 static off_t    zfs_seek(struct open_file *f, off_t offset, int where);
55 static int      zfs_stat(struct open_file *f, struct stat *sb);
56 static int      zfs_readdir(struct open_file *f, struct dirent *d);
57
58 struct devsw zfs_dev;
59
60 struct fs_ops zfs_fsops = {
61         "zfs",
62         zfs_open,
63         zfs_close,
64         zfs_read,
65         zfs_write,
66         zfs_seek,
67         zfs_stat,
68         zfs_readdir
69 };
70
71 /*
72  * In-core open file.
73  */
74 struct file {
75         off_t           f_seekp;        /* seek pointer */
76         dnode_phys_t    f_dnode;
77         uint64_t        f_zap_type;     /* zap type for readdir */
78         uint64_t        f_num_leafs;    /* number of fzap leaf blocks */
79         zap_leaf_phys_t *f_zap_leaf;    /* zap leaf buffer */
80 };
81
82 /*
83  * Open a file.
84  */
85 static int
86 zfs_open(const char *upath, struct open_file *f)
87 {
88         struct zfsmount *mount = (struct zfsmount *)f->f_devdata;
89         struct file *fp;
90         int rc;
91
92         if (f->f_dev != &zfs_dev)
93                 return (EINVAL);
94
95         /* allocate file system specific data structure */
96         fp = malloc(sizeof(struct file));
97         bzero(fp, sizeof(struct file));
98         f->f_fsdata = (void *)fp;
99
100         rc = zfs_lookup(mount, upath, &fp->f_dnode);
101         fp->f_seekp = 0;
102         if (rc) {
103                 f->f_fsdata = NULL;
104                 free(fp);
105         }
106         return (rc);
107 }
108
109 static int
110 zfs_close(struct open_file *f)
111 {
112         struct file *fp = (struct file *)f->f_fsdata;
113
114         dnode_cache_obj = 0;
115         f->f_fsdata = (void *)0;
116         if (fp == (struct file *)0)
117                 return (0);
118
119         free(fp);
120         return (0);
121 }
122
123 /*
124  * Copy a portion of a file into kernel memory.
125  * Cross block boundaries when necessary.
126  */
127 static int
128 zfs_read(struct open_file *f, void *start, size_t size, size_t *resid   /* out */)
129 {
130         const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
131         struct file *fp = (struct file *)f->f_fsdata;
132         struct stat sb;
133         size_t n;
134         int rc;
135
136         rc = zfs_stat(f, &sb);
137         if (rc)
138                 return (rc);
139         n = size;
140         if (fp->f_seekp + n > sb.st_size)
141                 n = sb.st_size - fp->f_seekp;
142         
143         rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n);
144         if (rc)
145                 return (rc);
146
147         if (0) {
148             int i;
149             for (i = 0; i < n; i++)
150                 putchar(((char*) start)[i]);
151         }
152         fp->f_seekp += n;
153         if (resid)
154                 *resid = size - n;
155
156         return (0);
157 }
158
159 /*
160  * Don't be silly - the bootstrap has no business writing anything.
161  */
162 static int
163 zfs_write(struct open_file *f, void *start, size_t size, size_t *resid  /* out */)
164 {
165
166         return (EROFS);
167 }
168
169 static off_t
170 zfs_seek(struct open_file *f, off_t offset, int where)
171 {
172         struct file *fp = (struct file *)f->f_fsdata;
173
174         switch (where) {
175         case SEEK_SET:
176                 fp->f_seekp = offset;
177                 break;
178         case SEEK_CUR:
179                 fp->f_seekp += offset;
180                 break;
181         case SEEK_END:
182             {
183                 struct stat sb;
184                 int error;
185
186                 error = zfs_stat(f, &sb);
187                 if (error != 0) {
188                         errno = error;
189                         return (-1);
190                 }
191                 fp->f_seekp = sb.st_size - offset;
192                 break;
193             }
194         default:
195                 errno = EINVAL;
196                 return (-1);
197         }
198         return (fp->f_seekp);
199 }
200
201 static int
202 zfs_stat(struct open_file *f, struct stat *sb)
203 {
204         const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
205         struct file *fp = (struct file *)f->f_fsdata;
206
207         return (zfs_dnode_stat(spa, &fp->f_dnode, sb));
208 }
209
210 static int
211 zfs_readdir(struct open_file *f, struct dirent *d)
212 {
213         const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
214         struct file *fp = (struct file *)f->f_fsdata;
215         mzap_ent_phys_t mze;
216         struct stat sb;
217         size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT;
218         int rc;
219
220         rc = zfs_stat(f, &sb);
221         if (rc)
222                 return (rc);
223         if (!S_ISDIR(sb.st_mode))
224                 return (ENOTDIR);
225
226         /*
227          * If this is the first read, get the zap type.
228          */
229         if (fp->f_seekp == 0) {
230                 rc = dnode_read(spa, &fp->f_dnode,
231                                 0, &fp->f_zap_type, sizeof(fp->f_zap_type));
232                 if (rc)
233                         return (rc);
234
235                 if (fp->f_zap_type == ZBT_MICRO) {
236                         fp->f_seekp = offsetof(mzap_phys_t, mz_chunk);
237                 } else {
238                         rc = dnode_read(spa, &fp->f_dnode,
239                                         offsetof(zap_phys_t, zap_num_leafs),
240                                         &fp->f_num_leafs,
241                                         sizeof(fp->f_num_leafs));
242                         if (rc)
243                                 return (rc);
244
245                         fp->f_seekp = bsize;
246                         fp->f_zap_leaf = (zap_leaf_phys_t *)malloc(bsize);
247                         rc = dnode_read(spa, &fp->f_dnode,
248                                         fp->f_seekp,
249                                         fp->f_zap_leaf,
250                                         bsize);
251                         if (rc)
252                                 return (rc);
253                 }
254         }
255
256         if (fp->f_zap_type == ZBT_MICRO) {
257         mzap_next:
258                 if (fp->f_seekp >= bsize)
259                         return (ENOENT);
260
261                 rc = dnode_read(spa, &fp->f_dnode,
262                                 fp->f_seekp, &mze, sizeof(mze));
263                 if (rc)
264                         return (rc);
265                 fp->f_seekp += sizeof(mze);
266
267                 if (!mze.mze_name[0])
268                         goto mzap_next;
269
270                 d->d_fileno = ZFS_DIRENT_OBJ(mze.mze_value);
271                 d->d_type = ZFS_DIRENT_TYPE(mze.mze_value);
272                 strcpy(d->d_name, mze.mze_name);
273                 d->d_namlen = strlen(d->d_name);
274                 return (0);
275         } else {
276                 zap_leaf_t zl;
277                 zap_leaf_chunk_t *zc, *nc;
278                 int chunk;
279                 size_t namelen;
280                 char *p;
281                 uint64_t value;
282
283                 /*
284                  * Initialise this so we can use the ZAP size
285                  * calculating macros.
286                  */
287                 zl.l_bs = ilog2(bsize);
288                 zl.l_phys = fp->f_zap_leaf;
289
290                 /*
291                  * Figure out which chunk we are currently looking at
292                  * and consider seeking to the next leaf. We use the
293                  * low bits of f_seekp as a simple chunk index.
294                  */
295         fzap_next:
296                 chunk = fp->f_seekp & (bsize - 1);
297                 if (chunk == ZAP_LEAF_NUMCHUNKS(&zl)) {
298                         fp->f_seekp = (fp->f_seekp & ~(bsize - 1)) + bsize;
299                         chunk = 0;
300
301                         /*
302                          * Check for EOF and read the new leaf.
303                          */
304                         if (fp->f_seekp >= bsize * fp->f_num_leafs)
305                                 return (ENOENT);
306
307                         rc = dnode_read(spa, &fp->f_dnode,
308                                         fp->f_seekp,
309                                         fp->f_zap_leaf,
310                                         bsize);
311                         if (rc)
312                                 return (rc);
313                 }
314
315                 zc = &ZAP_LEAF_CHUNK(&zl, chunk);
316                 fp->f_seekp++;
317                 if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
318                         goto fzap_next;
319
320                 namelen = zc->l_entry.le_name_numints;
321                 if (namelen > sizeof(d->d_name))
322                         namelen = sizeof(d->d_name);
323
324                 /*
325                  * Paste the name back together.
326                  */
327                 nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk);
328                 p = d->d_name;
329                 while (namelen > 0) {
330                         int len;
331                         len = namelen;
332                         if (len > ZAP_LEAF_ARRAY_BYTES)
333                                 len = ZAP_LEAF_ARRAY_BYTES;
334                         memcpy(p, nc->l_array.la_array, len);
335                         p += len;
336                         namelen -= len;
337                         nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next);
338                 }
339                 d->d_name[sizeof(d->d_name) - 1] = 0;
340
341                 /*
342                  * Assume the first eight bytes of the value are
343                  * a uint64_t.
344                  */
345                 value = fzap_leaf_value(&zl, zc);
346
347                 d->d_fileno = ZFS_DIRENT_OBJ(value);
348                 d->d_type = ZFS_DIRENT_TYPE(value);
349                 d->d_namlen = strlen(d->d_name);
350
351                 return (0);
352         }
353 }
354
355 static int
356 vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size)
357 {
358         int fd;
359
360         fd = (uintptr_t) priv;
361         lseek(fd, offset, SEEK_SET);
362         if (read(fd, buf, size) == size) {
363                 return 0;
364         } else {
365                 return (EIO);
366         }
367 }
368
369 static int
370 zfs_dev_init(void)
371 {
372         spa_t *spa;
373         spa_t *next;
374         spa_t *prev;
375
376         zfs_init();
377         if (archsw.arch_zfs_probe == NULL)
378                 return (ENXIO);
379         archsw.arch_zfs_probe();
380
381         prev = NULL;
382         spa = STAILQ_FIRST(&zfs_pools);
383         while (spa != NULL) {
384                 next = STAILQ_NEXT(spa, spa_link);
385                 if (zfs_spa_init(spa)) {
386                         if (prev == NULL)
387                                 STAILQ_REMOVE_HEAD(&zfs_pools, spa_link);
388                         else
389                                 STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link);
390                 } else
391                         prev = spa;
392                 spa = next;
393         }
394         return (0);
395 }
396
397 int
398 zfs_probe_dev(const char *devname, uint64_t *pool_guid)
399 {
400         spa_t *spa;
401         int fd;
402         int ret;
403
404         fd = open(devname, O_RDONLY);
405         if (fd == -1)
406                 return (ENXIO);
407         ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa);
408         if (ret != 0)
409                 close(fd);
410         else if (pool_guid != NULL)
411                 *pool_guid = spa->spa_guid;
412         return (0);
413 }
414
415 /*
416  * Print information about ZFS pools
417  */
418 static void
419 zfs_dev_print(int verbose)
420 {
421         spa_t *spa;
422         char line[80];
423
424         if (verbose) {
425                 spa_all_status();
426                 return;
427         }
428         STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
429                 sprintf(line, "    zfs:%s\n", spa->spa_name);
430                 pager_output(line);
431         }
432 }
433
434 /*
435  * Attempt to open the pool described by (dev) for use by (f).
436  */
437 static int
438 zfs_dev_open(struct open_file *f, ...)
439 {
440         va_list         args;
441         struct zfs_devdesc      *dev;
442         struct zfsmount *mount;
443         spa_t           *spa;
444         int             rv;
445
446         va_start(args, f);
447         dev = va_arg(args, struct zfs_devdesc *);
448         va_end(args);
449
450         if (dev->pool_guid == 0)
451                 spa = STAILQ_FIRST(&zfs_pools);
452         else
453                 spa = spa_find_by_guid(dev->pool_guid);
454         if (!spa)
455                 return (ENXIO);
456         mount = malloc(sizeof(*mount));
457         rv = zfs_mount(spa, dev->root_guid, mount);
458         if (rv != 0) {
459                 free(mount);
460                 return (rv);
461         }
462         if (mount->objset.os_type != DMU_OST_ZFS) {
463                 printf("Unexpected object set type %ju\n",
464                     (uintmax_t)mount->objset.os_type);
465                 free(mount);
466                 return (EIO);
467         }
468         f->f_devdata = mount;
469         free(dev);
470         return (0);
471 }
472
473 static int
474 zfs_dev_close(struct open_file *f)
475 {
476
477         free(f->f_devdata);
478         f->f_devdata = NULL;
479         return (0);
480 }
481
482 static int
483 zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
484 {
485
486         return (ENOSYS);
487 }
488
489 struct devsw zfs_dev = {
490         .dv_name = "zfs",
491         .dv_type = DEVT_ZFS,
492         .dv_init = zfs_dev_init,
493         .dv_strategy = zfs_dev_strategy,
494         .dv_open = zfs_dev_open,
495         .dv_close = zfs_dev_close,
496         .dv_ioctl = noioctl,
497         .dv_print = zfs_dev_print,
498         .dv_cleanup = NULL
499 };
500
501 int
502 zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
503 {
504         static char     rootname[ZFS_MAXNAMELEN];
505         static char     poolname[ZFS_MAXNAMELEN];
506         spa_t           *spa;
507         const char      *end;
508         const char      *np;
509         const char      *sep;
510         int             rv;
511
512         np = devspec;
513         if (*np != ':')
514                 return (EINVAL);
515         np++;
516         end = strchr(np, ':');
517         if (end == NULL)
518                 return (EINVAL);
519         sep = strchr(np, '/');
520         if (sep == NULL || sep >= end)
521                 sep = end;
522         memcpy(poolname, np, sep - np);
523         poolname[sep - np] = '\0';
524         if (sep < end) {
525                 sep++;
526                 memcpy(rootname, sep, end - sep);
527                 rootname[end - sep] = '\0';
528         }
529         else
530                 rootname[0] = '\0';
531
532         spa = spa_find_by_name(poolname);
533         if (!spa)
534                 return (ENXIO);
535         dev->pool_guid = spa->spa_guid;
536         rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
537         if (rv != 0)
538                 return (rv);
539         if (path != NULL)
540                 *path = (*end == '\0') ? end : end + 1;
541         dev->d_dev = &zfs_dev;
542         dev->d_type = zfs_dev.dv_type;
543         return (0);
544 }
545
546 char *
547 zfs_fmtdev(void *vdev)
548 {
549         static char             rootname[ZFS_MAXNAMELEN];
550         static char             buf[2 * ZFS_MAXNAMELEN + 8];
551         struct zfs_devdesc      *dev = (struct zfs_devdesc *)vdev;
552         spa_t                   *spa;
553
554         buf[0] = '\0';
555         if (dev->d_type != DEVT_ZFS)
556                 return (buf);
557
558         if (dev->pool_guid == 0) {
559                 spa = STAILQ_FIRST(&zfs_pools);
560                 dev->pool_guid = spa->spa_guid;
561         } else
562                 spa = spa_find_by_guid(dev->pool_guid);
563         if (spa == NULL) {
564                 printf("ZFS: can't find pool by guid\n");
565                 return (buf);
566         }
567         if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
568                 printf("ZFS: can't find root filesystem\n");
569                 return (buf);
570         }
571         if (zfs_rlookup(spa, dev->root_guid, rootname)) {
572                 printf("ZFS: can't find filesystem by guid\n");
573                 return (buf);
574         }
575
576         if (rootname[0] == '\0')
577                 sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name);
578         else
579                 sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name,
580                     rootname);
581         return (buf);
582 }
583
584 int
585 zfs_list(const char *name)
586 {
587         static char     poolname[ZFS_MAXNAMELEN];
588         uint64_t        objid;
589         spa_t           *spa;
590         const char      *dsname;
591         int             len;
592         int             rv;
593
594         len = strlen(name);
595         dsname = strchr(name, '/');
596         if (dsname != NULL) {
597                 len = dsname - name;
598                 dsname++;
599         } else
600                 dsname = "";
601         memcpy(poolname, name, len);
602         poolname[len] = '\0';
603
604         spa = spa_find_by_name(poolname);
605         if (!spa)
606                 return (ENXIO);
607         rv = zfs_lookup_dataset(spa, dsname, &objid);
608         if (rv != 0)
609                 return (rv);
610         rv = zfs_list_dataset(spa, objid);
611         return (rv);
612 }