Changeset View
Changeset View
Standalone View
Standalone View
stand/libsa/zfs/zfs.c
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
} *zfs_be, *zfs_be_tmp; | } *zfs_be, *zfs_be_tmp; | ||||
/* | /* | ||||
* Open a file. | * Open a file. | ||||
*/ | */ | ||||
static int | static int | ||||
zfs_open(const char *upath, struct open_file *f) | zfs_open(const char *upath, struct open_file *f) | ||||
{ | { | ||||
struct zfsmount *mount = (struct zfsmount *)f->f_devdata; | struct devdesc *dev = f->f_devdata; | ||||
struct zfsmount *mount = dev->d_opendata; | |||||
struct file *fp; | struct file *fp; | ||||
int rc; | int rc; | ||||
if (f->f_dev != &zfs_dev) | if (f->f_dev != &zfs_dev) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* allocate file system specific data structure */ | /* allocate file system specific data structure */ | ||||
fp = calloc(1, sizeof(struct file)); | fp = calloc(1, sizeof(struct file)); | ||||
Show All 24 Lines | |||||
/* | /* | ||||
* Copy a portion of a file into kernel memory. | * Copy a portion of a file into kernel memory. | ||||
* Cross block boundaries when necessary. | * Cross block boundaries when necessary. | ||||
*/ | */ | ||||
static int | static int | ||||
zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */) | zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */) | ||||
{ | { | ||||
const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; | struct devdesc *dev = f->f_devdata; | ||||
const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; | |||||
struct file *fp = (struct file *)f->f_fsdata; | struct file *fp = (struct file *)f->f_fsdata; | ||||
struct stat sb; | struct stat sb; | ||||
size_t n; | size_t n; | ||||
int rc; | int rc; | ||||
rc = zfs_stat(f, &sb); | rc = zfs_stat(f, &sb); | ||||
if (rc) | if (rc) | ||||
return (rc); | return (rc); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | default: | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (fp->f_seekp); | return (fp->f_seekp); | ||||
} | } | ||||
static int | static int | ||||
zfs_stat(struct open_file *f, struct stat *sb) | zfs_stat(struct open_file *f, struct stat *sb) | ||||
{ | { | ||||
const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; | struct devdesc *dev = f->f_devdata; | ||||
const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; | |||||
struct file *fp = (struct file *)f->f_fsdata; | struct file *fp = (struct file *)f->f_fsdata; | ||||
return (zfs_dnode_stat(spa, &fp->f_dnode, sb)); | return (zfs_dnode_stat(spa, &fp->f_dnode, sb)); | ||||
} | } | ||||
static int | static int | ||||
zfs_readdir(struct open_file *f, struct dirent *d) | zfs_readdir(struct open_file *f, struct dirent *d) | ||||
{ | { | ||||
const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; | struct devdesc *dev = f->f_devdata; | ||||
const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa; | |||||
struct file *fp = (struct file *)f->f_fsdata; | struct file *fp = (struct file *)f->f_fsdata; | ||||
mzap_ent_phys_t mze; | mzap_ent_phys_t mze; | ||||
struct stat sb; | struct stat sb; | ||||
size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT; | size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT; | ||||
int rc; | int rc; | ||||
rc = zfs_stat(f, &sb); | rc = zfs_stat(f, &sb); | ||||
if (rc) | if (rc) | ||||
▲ Show 20 Lines • Show All 1,347 Lines • ▼ Show 20 Lines | zfs_dev_open(struct open_file *f, ...) | ||||
} | } | ||||
rv = 0; | rv = 0; | ||||
/* This device is not set as currdev, mount us private copy. */ | /* This device is not set as currdev, mount us private copy. */ | ||||
if (mount == NULL) | if (mount == NULL) | ||||
rv = zfs_mount(devformat(&dev->dd), NULL, (void **)&mount); | rv = zfs_mount(devformat(&dev->dd), NULL, (void **)&mount); | ||||
if (rv == 0) { | if (rv == 0) { | ||||
f->f_devdata = mount; | dev->dd.d_opendata = mount; | ||||
free(dev); | |||||
} | } | ||||
return (rv); | return (rv); | ||||
} | } | ||||
static int | static int | ||||
zfs_dev_close(struct open_file *f) | zfs_dev_close(struct open_file *f) | ||||
{ | { | ||||
struct devdesc *dev; | |||||
struct zfsmount *mnt, *mount; | struct zfsmount *mnt, *mount; | ||||
mnt = f->f_devdata; | dev = f->f_devdata; | ||||
mnt = dev->d_opendata; | |||||
STAILQ_FOREACH(mount, &zfsmount, next) { | STAILQ_FOREACH(mount, &zfsmount, next) { | ||||
if (mnt->spa->spa_guid == mount->spa->spa_guid) | if (mnt->spa->spa_guid == mount->spa->spa_guid) | ||||
break; | break; | ||||
} | } | ||||
/* | /* XXX */ | ||||
imp: ????
| |||||
* devclose() will free f->f_devdata, but since we do have | |||||
* pointer to zfsmount structure in f->f_devdata, and | |||||
* zfs_unmount() will also free the zfsmount structure, | |||||
* we will get double free. To prevent double free, | |||||
* we must set f_devdata to NULL there. | |||||
*/ | |||||
if (mount != 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) | ||||
{ | { | ||||
return (ENOSYS); | return (ENOSYS); | ||||
▲ Show 20 Lines • Show All 419 Lines • Show Last 20 Lines |
????