Skip to content

Commit

Permalink
Factor out non-portable vnode_t usage
Browse files Browse the repository at this point in the history
On FreeBSD file offset state is maintained in struct file. A given
vnode can be referenced from many different struct file *. As a
consequence, FreeBSD's SPL doesn't support vn_rdwr with the FAPPEND
flag.

This change replaces the non-portable vnode_t with the portable
file_t in the common code.

Signed-off-by: Matt Macy <mmacy@FreeBSD.org>
  • Loading branch information
mattmacy committed Nov 12, 2019
1 parent 035ebb3 commit 72f3f9c
Show file tree
Hide file tree
Showing 23 changed files with 642 additions and 433 deletions.
1 change: 0 additions & 1 deletion include/os/linux/spl/sys/Makefile.am
Expand Up @@ -19,7 +19,6 @@ KERNEL_H = \
$(top_srcdir)/include/os/linux/spl/sys/isa_defs.h \
$(top_srcdir)/include/os/linux/spl/sys/kmem_cache.h \
$(top_srcdir)/include/os/linux/spl/sys/kmem.h \
$(top_srcdir)/include/os/linux/spl/sys/kobj.h \
$(top_srcdir)/include/os/linux/spl/sys/kstat.h \
$(top_srcdir)/include/os/linux/spl/sys/list.h \
$(top_srcdir)/include/os/linux/spl/sys/mod_os.h \
Expand Down
2 changes: 2 additions & 0 deletions include/os/linux/spl/sys/kmem_cache.h
Expand Up @@ -231,6 +231,8 @@ extern uint64_t spl_kmem_cache_entry_size(kmem_cache_t *cache);
spl_kmem_cache_reap_now(skc, skc->skc_reap)
#define kmem_reap() spl_kmem_reap()

extern spl_kmem_cache_t *vn_file_cache;

/*
* The following functions are only available for internal use.
*/
Expand Down
42 changes: 0 additions & 42 deletions include/os/linux/spl/sys/kobj.h

This file was deleted.

7 changes: 1 addition & 6 deletions include/os/linux/spl/sys/vnode.h
Expand Up @@ -165,13 +165,8 @@ extern vnode_t *vn_alloc(int flag);
void vn_free(vnode_t *vp);
extern vtype_t vn_mode_to_vtype(mode_t);
extern mode_t vn_vtype_to_mode(vtype_t);
extern int vn_open(const char *path, uio_seg_t seg, int flags, int mode,
vnode_t **vpp, int x1, void *x2);
extern int vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
vnode_t **vpp, int x1, void *x2, vnode_t *vp, int fd);
extern int vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len,
offset_t off, uio_seg_t seg, int x1, rlim64_t x2,
void *x3, ssize_t *residp);
extern int vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4);
extern int vn_seek(vnode_t *vp, offset_t o, offset_t *op, void *ct);

Expand All @@ -182,6 +177,7 @@ extern int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
extern file_t *vn_getf(int fd);
extern void vn_releasef(int fd);
extern void vn_areleasef(int fd, uf_info_t *fip);
extern void vn_file_add(file_t *fp);

int spl_vn_init(void);
void spl_vn_fini(void);
Expand All @@ -198,5 +194,4 @@ void spl_vn_fini(void);
#define areleasef vn_areleasef

extern vnode_t *rootdir;

#endif /* SPL_VNODE_H */
1 change: 1 addition & 0 deletions include/sys/Makefile.am
Expand Up @@ -104,6 +104,7 @@ COMMON_H = \
$(top_srcdir)/include/sys/zfs_context.h \
$(top_srcdir)/include/sys/zfs_debug.h \
$(top_srcdir)/include/sys/zfs_delay.h \
$(top_srcdir)/include/sys/zfs_file.h \
$(top_srcdir)/include/sys/zfs_fuid.h \
$(top_srcdir)/include/sys/zfs_project.h \
$(top_srcdir)/include/sys/zfs_ratelimit.h \
Expand Down
2 changes: 1 addition & 1 deletion include/sys/dmu.h
Expand Up @@ -1071,7 +1071,7 @@ void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
dmu_traverse_cb_t cb, void *arg);

int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
struct vnode *vp, offset_t *offp);
file_t *fp, offset_t *offp);

/* CRC64 table */
#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
Expand Down
5 changes: 3 additions & 2 deletions include/sys/dmu_recv.h
Expand Up @@ -62,7 +62,7 @@ typedef struct dmu_recv_cookie {
nvlist_t *drc_begin_nvl;

objset_t *drc_os;
vnode_t *drc_vp; /* The vnode to read the stream from */
file_t *drc_fp; /* The file to read the stream from */
uint64_t drc_voff; /* The current offset in the stream */
uint64_t drc_bytes_read;
/*
Expand All @@ -82,10 +82,11 @@ typedef struct dmu_recv_cookie {
int dmu_recv_begin(char *tofs, char *tosnap, dmu_replay_record_t *drr_begin,
boolean_t force, boolean_t resumable, nvlist_t *localprops,
nvlist_t *hidden_args, char *origin, dmu_recv_cookie_t *drc,
vnode_t *vp, offset_t *voffp);
file_t *fp, offset_t *voffp);
int dmu_recv_stream(dmu_recv_cookie_t *drc, int cleanup_fd,
uint64_t *action_handlep, offset_t *voffp);
int dmu_recv_end(dmu_recv_cookie_t *drc, void *owner);
boolean_t dmu_objset_is_receiving(objset_t *os);


#endif /* _DMU_RECV_H */
16 changes: 6 additions & 10 deletions include/sys/zfs_context.h
Expand Up @@ -42,7 +42,6 @@
#include <sys/vmem.h>
#include <sys/taskq.h>
#include <sys/param.h>
#include <sys/kobj.h>
#include <sys/disp.h>
#include <sys/debug.h>
#include <sys/random.h>
Expand Down Expand Up @@ -524,6 +523,12 @@ typedef struct vnode {
int v_dump_fd;
} vnode_t;

typedef struct file {
int f_fd;
loff_t f_pos;
loff_t f_offset;
} file_t;

extern char *vn_dumpdir;
#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */

Expand Down Expand Up @@ -613,12 +618,8 @@ extern int fop_getattr(vnode_t *vp, vattr_t *vap);

#define VN_RELE(vp) vn_close(vp)

extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3);
extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3, vnode_t *vp, int fd);
extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
extern void vn_close(vnode_t *vp);

#define vn_remove(path, x1, x2) remove(path)
Expand Down Expand Up @@ -759,11 +760,6 @@ typedef struct ace_object {
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08

extern struct _buf *kobj_open_file(char *name);
extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
unsigned off);
extern void kobj_close_file(struct _buf *file);
extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
cred_t *cr);
Expand Down
33 changes: 33 additions & 0 deletions include/sys/zfs_file.h
@@ -0,0 +1,33 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

#ifndef _SYS_ZFS_FILE_H
#define _SYS_ZFS_FILE_H

int zfs_file_write(file_t *, const void *, size_t, loff_t *, ssize_t *);
int zfs_file_read(file_t *, void *, size_t, loff_t *, ssize_t *);
int zfs_file_seek(file_t *, loff_t *, int);
int zfs_file_open(const char *path, int flags, int mode, file_t **fp);
void zfs_file_close(file_t *fp);
int zfs_file_getattr(file_t *fp, vattr_t *vap);
int zfs_file_fsync(file_t *fp, int flags);

#endif /* _SYS_ZFS_FILE_H */
1 change: 1 addition & 0 deletions lib/libzpool/Makefile.am
Expand Up @@ -144,6 +144,7 @@ KERNEL_C = \
zfeature.c \
zfs_byteswap.c \
zfs_debug.c \
zfs_file_os.c \
zfs_fm.c \
zfs_fuid.c \
zfs_sa.c \
Expand Down
108 changes: 1 addition & 107 deletions lib/libzpool/kernel.c
Expand Up @@ -496,7 +496,7 @@ procfs_list_add(procfs_list_t *procfs_list, void *p)
*/

/*ARGSUSED*/
int
static int
vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
{
int fd = -1;
Expand Down Expand Up @@ -584,58 +584,6 @@ vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
return (ret);
}

/*ARGSUSED*/
int
vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
{
ssize_t rc, done = 0, split;

if (uio == UIO_READ) {
rc = pread64(vp->v_fd, addr, len, offset);
if (vp->v_dump_fd != -1 && rc != -1) {
int status;
status = pwrite64(vp->v_dump_fd, addr, rc, offset);
ASSERT(status != -1);
}
} else {
/*
* To simulate partial disk writes, we split writes into two
* system calls so that the process can be killed in between.
*/
int sectors = len >> SPA_MINBLOCKSHIFT;
split = (sectors > 0 ? rand() % sectors : 0) <<
SPA_MINBLOCKSHIFT;
rc = pwrite64(vp->v_fd, addr, split, offset);
if (rc != -1) {
done = rc;
rc = pwrite64(vp->v_fd, (char *)addr + split,
len - split, offset + split);
}
}

#ifdef __linux__
if (rc == -1 && errno == EINVAL) {
/*
* Under Linux, this most likely means an alignment issue
* (memory or disk) due to O_DIRECT, so we abort() in order to
* catch the offender.
*/
abort();
}
#endif
if (rc == -1)
return (errno);

done += rc;

if (residp)
*residp = len - done;
else if (done != len)
return (EIO);
return (0);
}

void
vn_close(vnode_t *vp)
{
Expand Down Expand Up @@ -858,60 +806,6 @@ cmn_err(int ce, const char *fmt, ...)
va_end(adx);
}

/*
* =========================================================================
* kobj interfaces
* =========================================================================
*/
struct _buf *
kobj_open_file(char *name)
{
struct _buf *file;
vnode_t *vp;

/* set vp as the _fd field of the file */
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
-1) != 0)
return ((void *)-1UL);

file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
file->_fd = (intptr_t)vp;
return (file);
}

int
kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
{
ssize_t resid = 0;

if (vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
UIO_SYSSPACE, 0, 0, 0, &resid) != 0)
return (-1);

return (size - resid);
}

void
kobj_close_file(struct _buf *file)
{
vn_close((vnode_t *)file->_fd);
umem_free(file, sizeof (struct _buf));
}

int
kobj_get_filesize(struct _buf *file, uint64_t *size)
{
struct stat64 st;
vnode_t *vp = (vnode_t *)file->_fd;

if (fstat64(vp->v_fd, &st) == -1) {
vn_close(vp);
return (errno);
}
*size = st.st_size;
return (0);
}

/*
* =========================================================================
* misc routines
Expand Down
1 change: 0 additions & 1 deletion module/os/linux/spl/Makefile.in
Expand Up @@ -5,7 +5,6 @@ $(MODULE)-objs += ../os/linux/spl/spl-err.o
$(MODULE)-objs += ../os/linux/spl/spl-generic.o
$(MODULE)-objs += ../os/linux/spl/spl-kmem.o
$(MODULE)-objs += ../os/linux/spl/spl-kmem-cache.o
$(MODULE)-objs += ../os/linux/spl/spl-kobj.o
$(MODULE)-objs += ../os/linux/spl/spl-kstat.o
$(MODULE)-objs += ../os/linux/spl/spl-proc.o
$(MODULE)-objs += ../os/linux/spl/spl-procfs-list.o
Expand Down

0 comments on commit 72f3f9c

Please sign in to comment.