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 <[email protected]>
  • Loading branch information
mattmacy committed Nov 13, 2019
1 parent 870fc32 commit 470f2a6
Show file tree
Hide file tree
Showing 28 changed files with 702 additions and 1,207 deletions.
4 changes: 2 additions & 2 deletions cmd/ztest/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -5826,8 +5826,8 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
(long long)vd0->vdev_id, (int)maxfaults);

if (vf != NULL && ztest_random(3) == 0) {
(void) close(vf->vf_vnode->v_fd);
vf->vf_vnode->v_fd = -1;
(void) close(vf->vf_file->f_fd);
vf->vf_file->f_fd = -1;
} else if (ztest_random(2) == 0) {
vd0->vdev_cant_read = B_TRUE;
} else {
Expand Down
1 change: 0 additions & 1 deletion include/os/linux/spl/sys/Makefile.am
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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.

55 changes: 2 additions & 53 deletions include/os/linux/spl/sys/vnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,66 +137,15 @@ typedef struct vattr {
struct dentry *va_dentry; /* dentry to wire */
} vattr_t;

typedef struct vnode {
struct file *v_file;
kmutex_t v_lock; /* protects vnode fields */
uint_t v_flag; /* vnode flags (see below) */
uint_t v_count; /* reference count */
void *v_data; /* private data for fs */
struct vfs *v_vfsp; /* ptr to containing VFS */
struct stdata *v_stream; /* associated stream */
enum vtype v_type; /* vnode type */
dev_t v_rdev; /* device (VCHR, VBLK) */
gfp_t v_gfp_mask; /* original mapping gfp mask */
} vnode_t;

typedef struct vn_file {
int f_fd; /* linux fd for lookup */
struct task_struct *f_task; /* linux task this fd belongs to */
struct file *f_file; /* linux file struct */
atomic_t f_ref; /* ref count */
kmutex_t f_lock; /* struct lock */
loff_t f_offset; /* offset */
vnode_t *f_vnode; /* vnode */
struct list_head f_list; /* list referenced file_t's */
} file_t;

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);

extern int vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4);
extern int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4);
extern int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
offset_t offset, void *x6, void *x7);
extern file_t *vn_getf(int fd);

extern struct file *vn_getf(int fd);
extern void vn_releasef(int fd);
extern void vn_areleasef(int fd, uf_info_t *fip);

int spl_vn_init(void);
void spl_vn_fini(void);

#define VOP_CLOSE vn_close
#define VOP_SEEK vn_seek
#define VOP_GETATTR vn_getattr
#define VOP_FSYNC vn_fsync
#define VOP_SPACE vn_space
#define VOP_PUTPAGE(vp, o, s, f, x1, x2) ((void)0)
#define vn_is_readonly(vp) 0
#define getf vn_getf
#define releasef vn_releasef
#define areleasef vn_areleasef

extern vnode_t *rootdir;

#endif /* SPL_VNODE_H */
1 change: 1 addition & 0 deletions include/sys/Makefile.am
Original file line number Diff line number Diff line change
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
3 changes: 2 additions & 1 deletion include/sys/dmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <sys/zio_compress.h>
#include <sys/zio_priority.h>
#include <sys/uio.h>
#include <sys/zfs_file.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -1071,7 +1072,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);
zfs_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
Original file line number Diff line number Diff line change
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 */
zfs_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);
zfs_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 */
2 changes: 1 addition & 1 deletion include/sys/vdev_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extern "C" {
#endif

typedef struct vdev_file {
vnode_t *vf_vnode;
zfs_file_t *vf_file;
} vdev_file_t;

extern void vdev_file_init(void);
Expand Down
2 changes: 0 additions & 2 deletions include/sys/vdev_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,6 @@ struct vdev {
vdev_ops_t *vdev_ops; /* vdev operations */
spa_t *vdev_spa; /* spa for this vdev */
void *vdev_tsd; /* type-specific data */
vnode_t *vdev_name_vp; /* vnode for pathname */
vnode_t *vdev_devid_vp; /* vnode for devid */
vdev_t *vdev_top; /* top-level vdev */
vdev_t *vdev_parent; /* parent vdev */
vdev_t **vdev_child; /* array of children */
Expand Down
45 changes: 0 additions & 45 deletions include/sys/zfs_context.h
Original file line number Diff line number Diff line change
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 @@ -514,16 +513,6 @@ extern void system_taskq_fini(void);
#define XVA_MAPSIZE 3
#define XVA_MAGIC 0x78766174

/*
* vnodes
*/
typedef struct vnode {
uint64_t v_size;
int v_fd;
char *v_path;
int v_dump_fd;
} vnode_t;

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

Expand Down Expand Up @@ -593,38 +582,9 @@ typedef struct vsecattr {

#define F_FREESP 11

extern int fop_getattr(vnode_t *vp, vattr_t *vap);

#define VOP_CLOSE(vp, f, c, o, cr, ct) vn_close(vp)
#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0
#define VOP_GETATTR(vp, vap, fl, cr, ct) fop_getattr((vp), (vap));

#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd)

#if defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE)
#define VOP_SPACE(vp, cmd, flck, fl, off, cr, ct) \
fallocate((vp)->v_fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, \
(flck)->l_start, (flck)->l_len)
#else
#define VOP_SPACE(vp, cmd, flck, fl, off, cr, ct) (0)
#endif

#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)
#define vn_rename(from, to, seg) rename((from), (to))
#define vn_is_readonly(vp) B_FALSE

extern vnode_t *rootdir;

#include <sys/file.h> /* for FREAD, FWRITE, etc */

/*
Expand Down Expand Up @@ -757,11 +717,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
46 changes: 46 additions & 0 deletions include/sys/zfs_file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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

#ifndef _KERNEL
typedef struct zfs_file {
int f_fd;
} zfs_file_t;
#elif defined(__linux__) || defined(__FreeBSD__)
typedef struct file zfs_file_t;
#else
#error "unknown OS"
#endif



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

#endif /* _SYS_ZFS_FILE_H */
Loading

0 comments on commit 470f2a6

Please sign in to comment.