diff options
author | jhb <jhb@FreeBSD.org> | 2009-02-06 20:09:14 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-02-06 20:09:14 +0000 |
commit | d33df07e4e0ecbe8d46a2bdcace8f213a1955177 (patch) | |
tree | 0e316cb7bdbefe9347e2fbe31dd8f6d3c388bf0f /sys | |
parent | f856c6d618010b9224df31d6521124b672608255 (diff) | |
download | FreeBSD-src-d33df07e4e0ecbe8d46a2bdcace8f213a1955177.zip FreeBSD-src-d33df07e4e0ecbe8d46a2bdcace8f213a1955177.tar.gz |
Add support for fifos to UDF:
- Add a separate set of vnode operations that inherits from the fifo ops
and use it for fifo nodes.
- Add a VOP_SETATTR() method that allows setting the size (by silently
ignoring the requests) of fifos. This is to allow O_TRUNC opens of
fifo devices (e.g. I/O redirection in shells using ">").
- Add a VOP_PRINT() handler while I'm here.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/udf/udf.h | 2 | ||||
-rw-r--r-- | sys/fs/udf/udf_vfsops.c | 1 | ||||
-rw-r--r-- | sys/fs/udf/udf_vnops.c | 61 |
3 files changed, 64 insertions, 0 deletions
diff --git a/sys/fs/udf/udf.h b/sys/fs/udf/udf.h index 05eb2e4..fe16bf5 100644 --- a/sys/fs/udf/udf.h +++ b/sys/fs/udf/udf.h @@ -137,3 +137,5 @@ int udf_vget(struct mount *, ino_t, int, struct vnode **); extern uma_zone_t udf_zone_trans; extern uma_zone_t udf_zone_node; extern uma_zone_t udf_zone_ds; + +extern struct vop_vector udf_fifoops; diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index 5120187..faab9df 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -680,6 +680,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) break; case 9: vp->v_type = VFIFO; + vp->v_op = &udf_fifoops; break; case 10: vp->v_type = VSOCK; diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c index b62e9ef..4b03b9d 100644 --- a/sys/fs/udf/udf_vnops.c +++ b/sys/fs/udf/udf_vnops.c @@ -48,6 +48,7 @@ #include <vm/uma.h> +#include <fs/fifofs/fifo.h> #include <fs/udf/ecma167-udf.h> #include <fs/udf/osta.h> #include <fs/udf/udf.h> @@ -60,9 +61,11 @@ static vop_getattr_t udf_getattr; static vop_open_t udf_open; static vop_ioctl_t udf_ioctl; static vop_pathconf_t udf_pathconf; +static vop_print_t udf_print; static vop_read_t udf_read; static vop_readdir_t udf_readdir; static vop_readlink_t udf_readlink; +static vop_setattr_t udf_setattr; static vop_strategy_t udf_strategy; static vop_bmap_t udf_bmap; static vop_cachedlookup_t udf_lookup; @@ -84,14 +87,26 @@ static struct vop_vector udf_vnodeops = { .vop_lookup = vfs_cache_lookup, .vop_open = udf_open, .vop_pathconf = udf_pathconf, + .vop_print = udf_print, .vop_read = udf_read, .vop_readdir = udf_readdir, .vop_readlink = udf_readlink, .vop_reclaim = udf_reclaim, + .vop_setattr = udf_setattr, .vop_strategy = udf_strategy, .vop_vptofh = udf_vptofh, }; +struct vop_vector udf_fifoops = { + .vop_default = &fifo_specops, + .vop_access = udf_access, + .vop_getattr = udf_getattr, + .vop_print = udf_print, + .vop_reclaim = udf_reclaim, + .vop_setattr = udf_setattr, + .vop_vptofh = udf_vptofh, +}; + MALLOC_DEFINE(M_UDFFID, "udf_fid", "UDF FileId structure"); MALLOC_DEFINE(M_UDFDS, "udf_ds", "UDF Dirstream structure"); @@ -318,6 +333,38 @@ udf_getattr(struct vop_getattr_args *a) return (0); } +static int +udf_setattr(struct vop_setattr_args *a) +{ + struct vnode *vp; + struct vattr *vap; + + vp = a->a_vp; + vap = a->a_vap; + if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL || + vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || + vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) + return (EROFS); + if (vap->va_size != (u_quad_t)VNOVAL) { + switch (vp->v_type) { + case VDIR: + return (EISDIR); + case VLNK: + case VREG: + return (EROFS); + case VCHR: + case VBLK: + case VSOCK: + case VFIFO: + case VNON: + case VBAD: + case VMARKER: + return (0); + } + } + return (0); +} + /* * File specific ioctls. */ @@ -354,6 +401,20 @@ udf_pathconf(struct vop_pathconf_args *a) } } +static int +udf_print(struct vop_print_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct udf_node *node = VTON(vp); + + printf(" ino %lu, on dev %s", (u_long)node->hash_id, + devtoname(node->udfmp->im_dev)); + if (vp->v_type == VFIFO) + fifo_printinfo(vp); + printf("\n"); + return (0); +} + #define lblkno(udfmp, loc) ((loc) >> (udfmp)->bshift) #define blkoff(udfmp, loc) ((loc) & (udfmp)->bmask) #define lblktosize(imp, blk) ((blk) << (udfmp)->bshift) |