mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
Make zfs_replay.c work on FreeBSD
FreeBSD's vfs currently doesn't permit file systems to do their own locking. To avoid having to have duplicate zfs functions with and without locking add locking here. With luck these changes can be removed in the future. Reviewed-by: Sean Eric Fagan <sef@ixsystems.com> Reviewed-by: Jorgen Lundman <lundman@lundman.net> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Matt Macy <mmacy@FreeBSD.org> Closes #9715
This commit is contained in:
parent
9bb0d89c5c
commit
13a9a6f5e8
@ -43,6 +43,8 @@ extern int zfs_close(struct inode *ip, int flag, cred_t *cr);
|
||||
extern int zfs_holey(struct inode *ip, int cmd, loff_t *off);
|
||||
extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
|
||||
extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
|
||||
extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
|
||||
loff_t pos, size_t *resid);
|
||||
extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr);
|
||||
extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp,
|
||||
int flags, cred_t *cr, int *direntflags, pathname_t *realpnp);
|
||||
|
@ -973,6 +973,42 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the bytes to a file.
|
||||
*
|
||||
* IN: zp - znode of file to be written to
|
||||
* data - bytes to write
|
||||
* len - number of bytes to write
|
||||
* pos - offset to start writing at
|
||||
*
|
||||
* OUT: resid - remaining bytes to write
|
||||
*
|
||||
* RETURN: 0 if success
|
||||
* positive error code if failure
|
||||
*
|
||||
* Timestamps:
|
||||
* zp - ctime|mtime updated if byte count > 0
|
||||
*/
|
||||
int
|
||||
zfs_write_simple(znode_t *zp, const void *data, size_t len,
|
||||
loff_t pos, size_t *resid)
|
||||
{
|
||||
ssize_t written;
|
||||
int error = 0;
|
||||
|
||||
written = zpl_write_common(ZTOI(zp), data, len, &pos,
|
||||
UIO_SYSSPACE, 0, kcred);
|
||||
if (written < 0) {
|
||||
error = -written;
|
||||
} else if (resid == NULL) {
|
||||
if (written < len)
|
||||
error = SET_ERROR(EIO); /* short write */
|
||||
} else {
|
||||
*resid = len - written;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop a reference on the passed inode asynchronously. This ensures
|
||||
* that the caller will never drop the last reference on an inode in
|
||||
|
@ -320,6 +320,12 @@ zfs_znode_hold_exit(zfsvfs_t *zfsvfs, znode_hold_t *zh)
|
||||
kmem_cache_free(znode_hold_cache, zh);
|
||||
}
|
||||
|
||||
dev_t
|
||||
zfs_cmpldev(uint64_t dev)
|
||||
{
|
||||
return (dev);
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp,
|
||||
dmu_buf_t *db, dmu_object_type_t obj_type, sa_handle_t *sa_hdl)
|
||||
|
@ -63,7 +63,7 @@ zfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode,
|
||||
vap->va_mode = mode;
|
||||
vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid;
|
||||
vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid;
|
||||
vap->va_rdev = rdev;
|
||||
vap->va_rdev = zfs_cmpldev(rdev);
|
||||
vap->va_nodeid = nodeid;
|
||||
}
|
||||
|
||||
@ -493,6 +493,9 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
|
||||
lr->lr_uid, lr->lr_gid);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
vn_lock(ZTOV(dzp), LK_EXCLUSIVE | LK_RETRY);
|
||||
#endif
|
||||
switch (txtype) {
|
||||
case TX_CREATE_ATTR:
|
||||
lrattr = (lr_attr_t *)(caddr_t)(lr + 1);
|
||||
@ -543,6 +546,9 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
|
||||
error = SET_ERROR(ENOTSUP);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
VOP_UNLOCK(ZTOV(dzp), 0);
|
||||
#endif
|
||||
out:
|
||||
if (error == 0 && zp != NULL)
|
||||
zrele(zp);
|
||||
@ -574,6 +580,9 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
|
||||
if (lr->lr_common.lrc_txtype & TX_CI)
|
||||
vflg |= FIGNORECASE;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
vn_lock(ZTOV(dzp), LK_EXCLUSIVE | LK_RETRY);
|
||||
#endif
|
||||
switch ((int)lr->lr_common.lrc_txtype) {
|
||||
case TX_REMOVE:
|
||||
error = zfs_remove(dzp, name, kcred, vflg);
|
||||
@ -585,6 +594,9 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
|
||||
error = SET_ERROR(ENOTSUP);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
VOP_UNLOCK(ZTOV(dzp), 0);
|
||||
#endif
|
||||
zrele(dzp);
|
||||
|
||||
return (error);
|
||||
@ -614,8 +626,15 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
|
||||
if (lr->lr_common.lrc_txtype & TX_CI)
|
||||
vflg |= FIGNORECASE;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
vn_lock(ZTOV(dzp), LK_EXCLUSIVE | LK_RETRY);
|
||||
vn_lock(ZTOV(zp), LK_EXCLUSIVE | LK_RETRY);
|
||||
#endif
|
||||
error = zfs_link(dzp, zp, name, kcred, vflg);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
VOP_UNLOCK(ZTOV(zp), 0);
|
||||
VOP_UNLOCK(ZTOV(dzp), 0);
|
||||
#endif
|
||||
zrele(zp);
|
||||
zrele(dzp);
|
||||
|
||||
@ -662,7 +681,7 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||
lr_write_t *lr = arg2;
|
||||
char *data = (char *)(lr + 1); /* data follows lr_write_t */
|
||||
znode_t *zp;
|
||||
int error, written;
|
||||
int error;
|
||||
uint64_t eod, offset, length;
|
||||
|
||||
if (byteswap)
|
||||
@ -706,14 +725,7 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||
if (zp->z_size < eod)
|
||||
zfsvfs->z_replay_eof = eod;
|
||||
}
|
||||
|
||||
written = zpl_write_common(ZTOI(zp), data, length, &offset,
|
||||
UIO_SYSSPACE, 0, kcred);
|
||||
if (written < 0)
|
||||
error = -written;
|
||||
else if (written < length)
|
||||
error = SET_ERROR(EIO); /* short write */
|
||||
|
||||
error = zfs_write_simple(zp, data, length, offset, NULL);
|
||||
zrele(zp);
|
||||
zfsvfs->z_replay_eof = 0; /* safety */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user