Changeset View
Changeset View
Standalone View
Standalone View
stand/libsa/zfs/zfs.c
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
#define ZFS_BE_LAST 8 | #define ZFS_BE_LAST 8 | ||||
static int zfs_open(const char *path, struct open_file *f); | static int zfs_open(const char *path, struct open_file *f); | ||||
static int zfs_close(struct open_file *f); | static int zfs_close(struct open_file *f); | ||||
static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); | static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); | ||||
static off_t zfs_seek(struct open_file *f, off_t offset, int where); | static off_t zfs_seek(struct open_file *f, off_t offset, int where); | ||||
static int zfs_stat(struct open_file *f, struct stat *sb); | static int zfs_stat(struct open_file *f, struct stat *sb); | ||||
static int zfs_readdir(struct open_file *f, struct dirent *d); | static int zfs_readdir(struct open_file *f, struct dirent *d); | ||||
static int zfs_mount(const char *dev, const char *path, void **data); | |||||
static int zfs_unmount(const char *dev, void *data); | |||||
static void zfs_bootenv_initial(const char *envname, spa_t *spa, | static void zfs_bootenv_initial(const char *envname, spa_t *spa, | ||||
const char *name, const char *dsname, int checkpoint); | const char *name, const char *dsname, int checkpoint); | ||||
static void zfs_checkpoints_initial(spa_t *spa, const char *name, | static void zfs_checkpoints_initial(spa_t *spa, const char *name, | ||||
const char *dsname); | const char *dsname); | ||||
struct devsw zfs_dev; | struct devsw zfs_dev; | ||||
struct fs_ops zfs_fsops = { | struct fs_ops zfs_fsops = { | ||||
"zfs", | .fs_name = "zfs", | ||||
zfs_open, | .fo_open = zfs_open, | ||||
zfs_close, | .fo_close = zfs_close, | ||||
zfs_read, | .fo_read = zfs_read, | ||||
null_write, | .fo_write = null_write, | ||||
zfs_seek, | .fo_seek = zfs_seek, | ||||
zfs_stat, | .fo_stat = zfs_stat, | ||||
zfs_readdir | .fo_readdir = zfs_readdir, | ||||
.fo_mount = zfs_mount, | |||||
.fo_unmount = zfs_unmount | |||||
}; | }; | ||||
/* | /* | ||||
* In-core open file. | * In-core open file. | ||||
*/ | */ | ||||
struct file { | struct file { | ||||
off_t f_seekp; /* seek pointer */ | off_t f_seekp; /* seek pointer */ | ||||
dnode_phys_t f_dnode; | dnode_phys_t f_dnode; | ||||
▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | fzap_next: | ||||
d->d_fileno = ZFS_DIRENT_OBJ(value); | d->d_fileno = ZFS_DIRENT_OBJ(value); | ||||
d->d_type = ZFS_DIRENT_TYPE(value); | d->d_type = ZFS_DIRENT_TYPE(value); | ||||
d->d_namlen = strlen(d->d_name); | d->d_namlen = strlen(d->d_name); | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
/* | |||||
* if path is NULL, create mount structure, but do not add it to list. | |||||
*/ | |||||
static int | static int | ||||
zfs_mount(const char *dev, const char *path, void **data) | |||||
{ | |||||
struct zfs_devdesc *zfsdev; | |||||
spa_t *spa; | |||||
struct zfsmount *mnt; | |||||
int rv; | |||||
errno = 0; | |||||
zfsdev = malloc(sizeof(*zfsdev)); | |||||
if (zfsdev == NULL) | |||||
return (errno); | |||||
rv = zfs_parsedev(zfsdev, dev + 3, NULL); | |||||
if (rv != 0) { | |||||
free(zfsdev); | |||||
return (rv); | |||||
} | |||||
spa = spa_find_by_dev(zfsdev); | |||||
if (spa == NULL) | |||||
return (ENXIO); | |||||
mnt = calloc(1, sizeof(*mnt)); | |||||
if (mnt != NULL && path != NULL) | |||||
mnt->path = strdup(path); | |||||
rv = errno; | |||||
if (rv == 0) | |||||
rv = zfs_mount_impl(spa, zfsdev->root_guid, mnt); | |||||
free(zfsdev); | |||||
if (rv == 0 && mnt->objset.os_type != DMU_OST_ZFS) { | |||||
printf("Unexpected object set type %ju\n", | |||||
(uintmax_t)mnt->objset.os_type); | |||||
rv = EIO; | |||||
} | |||||
if (rv != 0) { | |||||
free(mnt->path); | |||||
free(mnt); | |||||
return (rv); | |||||
} | |||||
*data = mnt; | |||||
if (path != NULL) | |||||
STAILQ_INSERT_TAIL(&zfsmount, mnt, next); | |||||
return (rv); | |||||
} | |||||
static int | |||||
zfs_unmount(const char *dev, void *data) | |||||
{ | |||||
struct zfsmount *mnt = data; | |||||
STAILQ_REMOVE(&zfsmount, mnt, zfsmount, next); | |||||
free(mnt->path); | |||||
free(mnt); | |||||
return (0); | |||||
} | |||||
static int | |||||
vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes) | vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes) | ||||
{ | { | ||||
int fd, ret; | int fd, ret; | ||||
size_t res, head, tail, total_size, full_sec_size; | size_t res, head, tail, total_size, full_sec_size; | ||||
unsigned secsz, do_tail_read; | unsigned secsz, do_tail_read; | ||||
off_t start_sec; | off_t start_sec; | ||||
char *outbuf, *bouncebuf; | char *outbuf, *bouncebuf; | ||||
▲ Show 20 Lines • Show All 1,124 Lines • ▼ Show 20 Lines | zfs_dev_open(struct open_file *f, ...) | ||||
va_start(args, f); | va_start(args, f); | ||||
dev = va_arg(args, struct zfs_devdesc *); | dev = va_arg(args, struct zfs_devdesc *); | ||||
va_end(args); | va_end(args); | ||||
if ((spa = spa_find_by_dev(dev)) == NULL) | if ((spa = spa_find_by_dev(dev)) == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
mount = malloc(sizeof(*mount)); | STAILQ_FOREACH(mount, &zfsmount, next) { | ||||
if (mount == NULL) | if (spa->spa_guid == mount->spa->spa_guid) | ||||
rv = ENOMEM; | break; | ||||
else | |||||
rv = zfs_mount(spa, dev->root_guid, mount); | |||||
if (rv != 0) { | |||||
free(mount); | |||||
return (rv); | |||||
} | } | ||||
if (mount->objset.os_type != DMU_OST_ZFS) { | |||||
printf("Unexpected object set type %ju\n", | rv = 0; | ||||
(uintmax_t)mount->objset.os_type); | /* This device is not set as currdev, mount us private copy. */ | ||||
free(mount); | if (mount == NULL) | ||||
return (EIO); | rv = zfs_mount(zfs_fmtdev(dev), NULL, (void **)&mount); | ||||
} | |||||
if (rv == 0) { | |||||
f->f_devdata = mount; | f->f_devdata = mount; | ||||
free(dev); | free(dev); | ||||
return (0); | |||||
} | } | ||||
return (rv); | |||||
} | |||||
static int | static int | ||||
zfs_dev_close(struct open_file *f) | zfs_dev_close(struct open_file *f) | ||||
{ | { | ||||
struct zfsmount *mnt, *mount; | |||||
mnt = f->f_devdata; | |||||
STAILQ_FOREACH(mount, &zfsmount, next) { | |||||
if (mnt->spa->spa_guid == mount->spa->spa_guid) | |||||
break; | |||||
} | |||||
/* if f has private f_devdata, free it */ | |||||
if (mount == NULL) | |||||
free(f->f_devdata); | free(f->f_devdata); | ||||
f->f_devdata = NULL; | f->f_devdata = NULL; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) | zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 419 Lines • Show Last 20 Lines |