Skip to content

Commit

Permalink
Merge pull request openzfs#35 from truenas/13-backports
Browse files Browse the repository at this point in the history
Backports for 13.0-BETA1
  • Loading branch information
Ryan Moeller authored Jan 20, 2022
2 parents 903b641 + 589aaa8 commit 979e62a
Show file tree
Hide file tree
Showing 17 changed files with 244 additions and 126 deletions.
1 change: 1 addition & 0 deletions include/sys/vdev_draid.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ extern boolean_t vdev_draid_readable(vdev_t *, uint64_t);
extern boolean_t vdev_draid_missing(vdev_t *, uint64_t, uint64_t, uint64_t);
extern uint64_t vdev_draid_asize_to_psize(vdev_t *, uint64_t);
extern void vdev_draid_map_alloc_empty(zio_t *, struct raidz_row *);
extern int vdev_draid_map_verify_empty(zio_t *, struct raidz_row *);
extern nvlist_t *vdev_draid_read_config_spare(vdev_t *);

/* Functions for dRAID distributed spares. */
Expand Down
2 changes: 2 additions & 0 deletions include/sys/vdev_raidz.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern "C" {
#endif

struct zio;
struct raidz_col;
struct raidz_row;
struct raidz_map;
#if !defined(_KERNEL)
Expand All @@ -49,6 +50,7 @@ void vdev_raidz_generate_parity(struct raidz_map *);
void vdev_raidz_reconstruct(struct raidz_map *, const int *, int);
void vdev_raidz_child_done(zio_t *);
void vdev_raidz_io_done(zio_t *);
void vdev_raidz_checksum_error(zio_t *, struct raidz_col *, abd_t *);

extern const zio_vsd_ops_t vdev_raidz_vsd_ops;

Expand Down
8 changes: 7 additions & 1 deletion lib/libshare/os/freebsd/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,16 +423,22 @@ nfs_commit_shares(void)
struct pidfh *pfh;
pid_t mountdpid;

start:
pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid);
if (pfh != NULL) {
/* Mountd is not running. */
/* mountd(8) is not running. */
pidfile_remove(pfh);
return (SA_OK);
}
if (errno != EEXIST) {
/* Cannot open pidfile for some reason. */
return (SA_SYSTEM_ERR);
}
if (mountdpid == -1) {
/* mountd(8) exists, but didn't write the PID yet */
usleep(500);
goto start;
}
/* We have mountd(8) PID in mountdpid variable. */
kill(mountdpid, SIGHUP);
return (SA_OK);
Expand Down
2 changes: 1 addition & 1 deletion lib/libspl/include/sys/feature_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define ____cacheline_aligned
#define __NORETURN __attribute__((__noreturn__))

#if !defined(fallthrough)
#if !defined(fallthrough) && !defined(_LIBCPP_VERSION)
#if defined(HAVE_IMPLICIT_FALLTHROUGH)
#define fallthrough __attribute__((__fallthrough__))
#else
Expand Down
25 changes: 16 additions & 9 deletions lib/libspl/os/freebsd/mnttab.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,28 @@ optadd(char *mntopts, size_t size, const char *opt)
strlcat(mntopts, opt, size);
}

static __thread char gfstypename[MFSNAMELEN];
static __thread char gmntfromname[MNAMELEN];
static __thread char gmntonname[MNAMELEN];
static __thread char gmntopts[MNTMAXSTR];

void
statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
{
static char mntopts[MNTMAXSTR];
long flags;

mntopts[0] = '\0';
strlcpy(gfstypename, sfs->f_fstypename, sizeof (gfstypename));
mp->mnt_fstype = gfstypename;

strlcpy(gmntfromname, sfs->f_mntfromname, sizeof (gmntfromname));
mp->mnt_special = gmntfromname;

strlcpy(gmntonname, sfs->f_mntonname, sizeof (gmntonname));
mp->mnt_mountp = gmntonname;

flags = sfs->f_flags;
#define OPTADD(opt) optadd(mntopts, sizeof (mntopts), (opt))
gmntopts[0] = '\0';
#define OPTADD(opt) optadd(gmntopts, sizeof (gmntopts), (opt))
if (flags & MNT_RDONLY)
OPTADD(MNTOPT_RO);
else
Expand All @@ -121,10 +133,7 @@ statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
else
OPTADD(MNTOPT_EXEC);
#undef OPTADD
mp->mnt_special = strdup(sfs->f_mntfromname);
mp->mnt_mountp = strdup(sfs->f_mntonname);
mp->mnt_fstype = strdup(sfs->f_fstypename);
mp->mnt_mntopts = strdup(mntopts);
mp->mnt_mntopts = gmntopts;
}

static struct statfs *gsfs = NULL;
Expand Down Expand Up @@ -166,7 +175,6 @@ statfs_init(void)
int
getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
{
// struct statfs *sfs;
int i, error;

error = statfs_init();
Expand Down Expand Up @@ -195,7 +203,6 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
int
getmntent(FILE *fp, struct mnttab *mp)
{
// struct statfs *sfs;
int error, nfs;

nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
Expand Down
2 changes: 1 addition & 1 deletion lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2563,7 +2563,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
"progress thread exited nonzero")));
}

if (flags->props || flags->holds || flags->backup) {
if (err == 0 && (flags->props || flags->holds || flags->backup)) {
/* Write the final end record. */
err = send_conclusion_record(fd, NULL);
if (err != 0)
Expand Down
2 changes: 1 addition & 1 deletion lib/libzfs/os/linux/libzfs_mount_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags)

if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
char badopt[MNT_LINE_MAX] = {0};
unsigned long mntflags = flags, zfsflags;
unsigned long mntflags = flags, zfsflags = 0;
char myopts[MNT_LINE_MAX] = {0};

if (zfs_parse_mount_options(opts, &mntflags,
Expand Down
1 change: 1 addition & 0 deletions module/os/freebsd/zfs/vdev_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ vdev_file_io_strategy(void *arg)
err = zfs_file_pwrite(vf->vf_file, buf, size, off, &resid);
abd_return_buf(zio->io_abd, buf, size);
}
zio->io_error = err;
if (resid != 0 && zio->io_error == 0)
zio->io_error = ENOSPC;

Expand Down
8 changes: 7 additions & 1 deletion module/os/freebsd/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,7 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
vnode_t *dvp;
uint64_t object = 0;
uint64_t fid_gen = 0;
uint64_t setgen = 0;
uint64_t gen_mask;
uint64_t zp_gen;
int i, err;
Expand All @@ -1838,7 +1839,6 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
if (zfsvfs->z_parent == zfsvfs && fidp->fid_len == LONG_FID_LEN) {
zfid_long_t *zlfid = (zfid_long_t *)fidp;
uint64_t objsetid = 0;
uint64_t setgen = 0;

for (i = 0; i < sizeof (zlfid->zf_setid); i++)
objsetid |= ((uint64_t)zlfid->zf_setid[i]) << (8 * i);
Expand Down Expand Up @@ -1867,6 +1867,12 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp)
return (SET_ERROR(EINVAL));
}

if (fidp->fid_len == LONG_FID_LEN && (fid_gen > 1 || setgen != 0)) {
dprintf("snapdir fid: fid_gen (%llu) and setgen (%llu)\n",
(u_longlong_t)fid_gen, (u_longlong_t)setgen);
return (SET_ERROR(EINVAL));
}

/*
* A zero fid_gen means we are in .zfs or the .zfs/snapshot
* directory tree. If the object == zfsvfs->z_shares_dir, then
Expand Down
14 changes: 10 additions & 4 deletions module/os/freebsd/zfs/zfs_vnops_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ VFS_SMR_DECLARE;
#define VNCHECKREF(vp)
#endif

#if __FreeBSD_version >= 1400045
typedef uint64_t cookie_t;
#else
typedef ulong_t cookie_t;
#endif

/*
* Programming rules.
*
Expand Down Expand Up @@ -1679,7 +1685,7 @@ zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd, cred_t *cr, int flags)
/* ARGSUSED */
static int
zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
int *ncookies, ulong_t **cookies)
int *ncookies, cookie_t **cookies)
{
znode_t *zp = VTOZ(vp);
iovec_t *iovp;
Expand All @@ -1701,7 +1707,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
boolean_t check_sysattrs;
uint8_t type;
int ncooks;
ulong_t *cooks = NULL;
cookie_t *cooks = NULL;
int flags = 0;

ZFS_ENTER(zfsvfs);
Expand Down Expand Up @@ -1778,7 +1784,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
*/
ncooks = zfs_uio_resid(uio) / (sizeof (struct dirent) -
sizeof (((struct dirent *)NULL)->d_name) + 1);
cooks = malloc(ncooks * sizeof (ulong_t), M_TEMP, M_WAITOK);
cooks = malloc(ncooks * sizeof (*cooks), M_TEMP, M_WAITOK);
*cookies = cooks;
*ncookies = ncooks;
}
Expand Down Expand Up @@ -4732,7 +4738,7 @@ struct vop_readdir_args {
struct ucred *a_cred;
int *a_eofflag;
int *a_ncookies;
ulong_t **a_cookies;
cookie_t **a_cookies;
};
#endif

Expand Down
90 changes: 59 additions & 31 deletions module/os/freebsd/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
zvol_state_t *zv;
int err = 0;
boolean_t drop_suspend = B_FALSE;
boolean_t drop_namespace = B_FALSE;

if (!zpool_on_zvol && tsd_get(zfs_geom_probe_vdev_key) != NULL) {
/*
Expand All @@ -226,25 +225,19 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)

retry:
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
/*
* Obtain a copy of private under zvol_state_lock to make sure either
* the result of zvol free code setting private to NULL is observed,
* or the zv is protected from being freed because of the positive
* zv_open_count.
*/
zv = pp->private;
if (zv == NULL) {
rw_exit(&zvol_state_lock);
err = SET_ERROR(ENXIO);
goto out_locked;
}

if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
/*
* We need to guarantee that the namespace lock is held
* to avoid spurious failures in zvol_first_open.
*/
drop_namespace = B_TRUE;
if (!mutex_tryenter(&spa_namespace_lock)) {
rw_exit(&zvol_state_lock);
mutex_enter(&spa_namespace_lock);
goto retry;
}
}
mutex_enter(&zv->zv_state_lock);
if (zv->zv_zso->zso_dying) {
rw_exit(&zvol_state_lock);
Expand Down Expand Up @@ -276,15 +269,36 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
ASSERT(MUTEX_HELD(&zv->zv_state_lock));

if (zv->zv_open_count == 0) {
boolean_t drop_namespace = B_FALSE;

ASSERT(ZVOL_RW_READ_HELD(&zv->zv_suspend_lock));

/*
* Take spa_namespace_lock to prevent lock inversion when
* zvols from one pool are opened as vdevs in another.
*/
if (!mutex_owned(&spa_namespace_lock)) {
if (!mutex_tryenter(&spa_namespace_lock)) {
mutex_exit(&zv->zv_state_lock);
rw_exit(&zv->zv_suspend_lock);
kern_yield(PRI_USER);
goto retry;
} else {
drop_namespace = B_TRUE;
}
}
err = zvol_first_open(zv, !(flag & FWRITE));
if (drop_namespace)
mutex_exit(&spa_namespace_lock);
if (err)
goto out_zv_locked;
pp->mediasize = zv->zv_volsize;
pp->stripeoffset = 0;
pp->stripesize = zv->zv_volblocksize;
}

ASSERT(MUTEX_HELD(&zv->zv_state_lock));

/*
* Check for a bad on-disk format version now since we
* lied about owning the dataset readonly before.
Expand Down Expand Up @@ -317,8 +331,6 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
out_zv_locked:
mutex_exit(&zv->zv_state_lock);
out_locked:
if (drop_namespace)
mutex_exit(&spa_namespace_lock);
if (drop_suspend)
rw_exit(&zv->zv_suspend_lock);
return (err);
Expand Down Expand Up @@ -859,31 +871,28 @@ zvol_cdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
struct zvol_state_dev *zsd;
int err = 0;
boolean_t drop_suspend = B_FALSE;
boolean_t drop_namespace = B_FALSE;

retry:
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
/*
* Obtain a copy of si_drv2 under zvol_state_lock to make sure either
* the result of zvol free code setting si_drv2 to NULL is observed,
* or the zv is protected from being freed because of the positive
* zv_open_count.
*/
zv = dev->si_drv2;
if (zv == NULL) {
rw_exit(&zvol_state_lock);
err = SET_ERROR(ENXIO);
goto out_locked;
}

if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
/*
* We need to guarantee that the namespace lock is held
* to avoid spurious failures in zvol_first_open.
*/
drop_namespace = B_TRUE;
if (!mutex_tryenter(&spa_namespace_lock)) {
rw_exit(&zvol_state_lock);
mutex_enter(&spa_namespace_lock);
goto retry;
}
}
mutex_enter(&zv->zv_state_lock);

if (zv->zv_zso->zso_dying) {
rw_exit(&zvol_state_lock);
err = SET_ERROR(ENXIO);
goto out_zv_locked;
}
ASSERT3S(zv->zv_volmode, ==, ZFS_VOLMODE_DEV);

/*
Expand All @@ -909,12 +918,33 @@ zvol_cdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
ASSERT(MUTEX_HELD(&zv->zv_state_lock));

if (zv->zv_open_count == 0) {
boolean_t drop_namespace = B_FALSE;

ASSERT(ZVOL_RW_READ_HELD(&zv->zv_suspend_lock));

/*
* Take spa_namespace_lock to prevent lock inversion when
* zvols from one pool are opened as vdevs in another.
*/
if (!mutex_owned(&spa_namespace_lock)) {
if (!mutex_tryenter(&spa_namespace_lock)) {
rw_exit(&zvol_state_lock);
mutex_enter(&spa_namespace_lock);
kern_yield(PRI_USER);
goto retry;
} else {
drop_namespace = B_TRUE;
}
}
err = zvol_first_open(zv, !(flags & FWRITE));
if (drop_namespace)
mutex_exit(&spa_namespace_lock);
if (err)
goto out_zv_locked;
}

ASSERT(MUTEX_HELD(&zv->zv_state_lock));

if ((flags & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
err = SET_ERROR(EROFS);
goto out_opened;
Expand Down Expand Up @@ -949,8 +979,6 @@ zvol_cdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
out_zv_locked:
mutex_exit(&zv->zv_state_lock);
out_locked:
if (drop_namespace)
mutex_exit(&spa_namespace_lock);
if (drop_suspend)
rw_exit(&zv->zv_suspend_lock);
return (err);
Expand Down
Loading

0 comments on commit 979e62a

Please sign in to comment.