diff options
author | pjd <pjd@FreeBSD.org> | 2008-11-17 20:49:29 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2008-11-17 20:49:29 +0000 |
commit | bbe899b96e388a8b82439f81ed3707e0d9c6070d (patch) | |
tree | 81b89fa4ac6467771d5aa291a97f4665981a6108 /sys/cddl/compat/opensolaris/kern/opensolaris_zone.c | |
parent | d2f579595c362ce27b4d87e2c40e1c4e09b929e3 (diff) | |
download | FreeBSD-src-bbe899b96e388a8b82439f81ed3707e0d9c6070d.zip FreeBSD-src-bbe899b96e388a8b82439f81ed3707e0d9c6070d.tar.gz |
Update ZFS from version 6 to 13 and bring some FreeBSD-specific changes.
This bring huge amount of changes, I'll enumerate only user-visible changes:
- Delegated Administration
Allows regular users to perform ZFS operations, like file system
creation, snapshot creation, etc.
- L2ARC
Level 2 cache for ZFS - allows to use additional disks for cache.
Huge performance improvements mostly for random read of mostly
static content.
- slog
Allow to use additional disks for ZFS Intent Log to speed up
operations like fsync(2).
- vfs.zfs.super_owner
Allows regular users to perform privileged operations on files stored
on ZFS file systems owned by him. Very careful with this one.
- chflags(2)
Not all the flags are supported. This still needs work.
- ZFSBoot
Support to boot off of ZFS pool. Not finished, AFAIK.
Submitted by: dfr
- Snapshot properties
- New failure modes
Before if write requested failed, system paniced. Now one
can select from one of three failure modes:
- panic - panic on write error
- wait - wait for disk to reappear
- continue - serve read requests if possible, block write requests
- Refquota, refreservation properties
Just quota and reservation properties, but don't count space consumed
by children file systems, clones and snapshots.
- Sparse volumes
ZVOLs that don't reserve space in the pool.
- External attributes
Compatible with extattr(2).
- NFSv4-ACLs
Not sure about the status, might not be complete yet.
Submitted by: trasz
- Creation-time properties
- Regression tests for zpool(8) command.
Obtained from: OpenSolaris
Diffstat (limited to 'sys/cddl/compat/opensolaris/kern/opensolaris_zone.c')
-rw-r--r-- | sys/cddl/compat/opensolaris/kern/opensolaris_zone.c | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_zone.c b/sys/cddl/compat/opensolaris/kern/opensolaris_zone.c index 3059a78..8489052 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_zone.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_zone.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/queue.h> #include <sys/jail.h> +#include <sys/osd.h> #include <sys/priv.h> #include <sys/zone.h> @@ -52,7 +53,7 @@ typedef struct zone_dataset { LIST_HEAD(zone_dataset_head, zone_dataset); -static struct prison_service *zone_prison_service = NULL; +static int zone_slot; int zone_dataset_attach(struct ucred *cred, const char *dataset, int jailid) @@ -60,7 +61,7 @@ zone_dataset_attach(struct ucred *cred, const char *dataset, int jailid) struct zone_dataset_head *head; zone_dataset_t *zd, *zd2; struct prison *pr; - int error; + int dofree, error; if ((error = priv_check_cred(cred, PRIV_ZFS_JAIL, 0)) != 0) return (error); @@ -76,18 +77,33 @@ zone_dataset_attach(struct ucred *cred, const char *dataset, int jailid) return (ENOENT); } - head = prison_service_data_get(zone_prison_service, pr); - LIST_FOREACH(zd2, head, zd_next) { - if (strcmp(dataset, zd2->zd_dataset) == 0) { - free(zd, M_ZONES); - error = EEXIST; - goto failure; + head = osd_jail_get(pr, zone_slot); + if (head != NULL) { + dofree = 0; + LIST_FOREACH(zd2, head, zd_next) { + if (strcmp(dataset, zd2->zd_dataset) == 0) { + free(zd, M_ZONES); + error = EEXIST; + goto end; + } } + } else { + dofree = 1; + prison_hold_locked(pr); + mtx_unlock(&pr->pr_mtx); + head = malloc(sizeof(*head), M_ZONES, M_WAITOK); + LIST_INIT(head); + mtx_lock(&pr->pr_mtx); + error = osd_jail_set(pr, zone_slot, head); + KASSERT(error == 0, ("osd_jail_set() failed (error=%d)", error)); } strcpy(zd->zd_dataset, dataset); LIST_INSERT_HEAD(head, zd, zd_next); -failure: - mtx_unlock(&pr->pr_mtx); +end: + if (dofree) + prison_free_locked(pr); + else + mtx_unlock(&pr->pr_mtx); return (error); } @@ -107,16 +123,25 @@ zone_dataset_detach(struct ucred *cred, const char *dataset, int jailid) sx_sunlock(&allprison_lock); if (pr == NULL) return (ENOENT); - head = prison_service_data_get(zone_prison_service, pr); + head = osd_jail_get(pr, zone_slot); + if (head == NULL) { + error = ENOENT; + goto end; + } LIST_FOREACH(zd, head, zd_next) { - if (strcmp(dataset, zd->zd_dataset) == 0) { - LIST_REMOVE(zd, zd_next); - free(zd, M_ZONES); - goto success; - } + if (strcmp(dataset, zd->zd_dataset) == 0) + break; } - error = ENOENT; -success: + if (zd == NULL) + error = ENOENT; + else { + LIST_REMOVE(zd, zd_next); + free(zd, M_ZONES); + if (LIST_EMPTY(head)) + osd_jail_del(pr, zone_slot); + error = 0; + } +end: mtx_unlock(&pr->pr_mtx); return (error); } @@ -136,14 +161,16 @@ zone_dataset_visible(const char *dataset, int *write) if (dataset[0] == '\0') return (0); - if (INGLOBALZONE(curproc)) { + if (INGLOBALZONE(curthread)) { if (write != NULL) *write = 1; return (1); } pr = curthread->td_ucred->cr_prison; mtx_lock(&pr->pr_mtx); - head = prison_service_data_get(zone_prison_service, pr); + head = osd_jail_get(pr, zone_slot); + if (head == NULL) + goto end; /* * Walk the list once, looking for datasets which match exactly, or @@ -188,49 +215,32 @@ end: return (ret); } -static int -zone_create(struct prison_service *psrv, struct prison *pr) -{ - struct zone_dataset_head *head; - - head = malloc(sizeof(*head), M_ZONES, M_WAITOK); - LIST_INIT(head); - mtx_lock(&pr->pr_mtx); - prison_service_data_set(psrv, pr, head); - mtx_unlock(&pr->pr_mtx); - return (0); -} - -static int -zone_destroy(struct prison_service *psrv, struct prison *pr) +static void +zone_destroy(void *arg) { struct zone_dataset_head *head; zone_dataset_t *zd; - mtx_lock(&pr->pr_mtx); - head = prison_service_data_del(psrv, pr); - mtx_unlock(&pr->pr_mtx); - while ((zd = LIST_FIRST(head)) != NULL) { - LIST_REMOVE(zd, zd_next); - free(zd, M_ZONES); - } - free(head, M_ZONES); - return (0); + head = arg; + while ((zd = LIST_FIRST(head)) != NULL) { + LIST_REMOVE(zd, zd_next); + free(zd, M_ZONES); + } + free(head, M_ZONES); } static void zone_sysinit(void *arg __unused) { - zone_prison_service = prison_service_register("zfs", zone_create, - zone_destroy); + zone_slot = osd_jail_register(zone_destroy); } static void zone_sysuninit(void *arg __unused) { - prison_service_deregister(zone_prison_service); + osd_jail_deregister(zone_slot); } SYSINIT(zone_sysinit, SI_SUB_DRIVERS, SI_ORDER_ANY, zone_sysinit, NULL); |