When reading or writing the extended attributes of a special device

or fifo in UFS2, the normal ufs_strategy routine needs to be used
rather than the spec_strategy or fifo_strategy routine. Thus the
ffsext_strategy routine is interposed in the ffs_vnops vectors for
special devices and fifo's to pick off this special case. Otherwise
it simply falls through to the usual spec_strategy or fifo_strategy
routine.

Submitted by:	Robert Watson <rwatson@FreeBSD.org>
Sponsored by:	DARPA & NAI Labs.
This commit is contained in:
mckusick 2002-10-14 23:18:09 +00:00
parent 9693ff7295
commit 750c7540cc
2 changed files with 38 additions and 5 deletions

View File

@ -77,12 +77,14 @@
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>
int ffs_fsync(struct vop_fsync_args *);
static int ffs_fsync(struct vop_fsync_args *);
static int ffs_getpages(struct vop_getpages_args *);
static int ffs_read(struct vop_read_args *);
static int ffs_write(struct vop_write_args *);
static int ffs_extread(struct vnode *vp, struct uio *uio, int ioflag);
static int ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred);
static int ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred);
static int ffsext_strategy(struct vop_strategy_args *);
static int ffs_closeextattr(struct vop_closeextattr_args *);
static int ffs_getextattr(struct vop_getextattr_args *);
static int ffs_openextattr(struct vop_openextattr_args *);
@ -111,6 +113,8 @@ vop_t **ffs_specop_p;
static struct vnodeopv_entry_desc ffs_specop_entries[] = {
{ &vop_default_desc, (vop_t *) ufs_vnoperatespec },
{ &vop_fsync_desc, (vop_t *) ffs_fsync },
{ &vop_reallocblks_desc, (vop_t *) ffs_reallocblks },
{ &vop_strategy_desc, (vop_t *) ffsext_strategy },
{ &vop_closeextattr_desc, (vop_t *) ffs_closeextattr },
{ &vop_getextattr_desc, (vop_t *) ffs_getextattr },
{ &vop_openextattr_desc, (vop_t *) ffs_openextattr },
@ -124,6 +128,8 @@ vop_t **ffs_fifoop_p;
static struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
{ &vop_default_desc, (vop_t *) ufs_vnoperatefifo },
{ &vop_fsync_desc, (vop_t *) ffs_fsync },
{ &vop_reallocblks_desc, (vop_t *) ffs_reallocblks },
{ &vop_strategy_desc, (vop_t *) ffsext_strategy },
{ &vop_closeextattr_desc, (vop_t *) ffs_closeextattr },
{ &vop_getextattr_desc, (vop_t *) ffs_getextattr },
{ &vop_openextattr_desc, (vop_t *) ffs_openextattr },
@ -141,7 +147,7 @@ VNODEOP_SET(ffs_fifoop_opv_desc);
* Synch an open file.
*/
/* ARGSUSED */
int
static int
ffs_fsync(ap)
struct vop_fsync_args /* {
struct vnode *a_vp;
@ -1459,6 +1465,35 @@ ffs_close_ea(struct vnode *vp, int commit, struct ucred *cred, struct thread *td
return (error);
}
/*
* Vnode extattr strategy routine for special devices and fifos.
*
* We need to check for a read or write of the external attributes.
* Otherwise we just fall through and do the usual thing.
*/
static int
ffsext_strategy(struct vop_strategy_args *ap)
/*
struct vop_strategy_args {
struct vnodeop_desc *a_desc;
struct vnode *a_vp;
struct buf *a_bp;
};
*/
{
struct vnode *vp;
daddr_t lbn;
vp = ap->a_vp;
lbn = ap->a_bp->b_lblkno;
if (VTOI(vp)->i_fs->fs_magic == FS_UFS2_MAGIC &&
lbn < 0 && lbn >= -NXADDR)
return (ufs_vnoperate((struct vop_generic_args *)ap));
if (vp->v_type == VFIFO)
return (ufs_vnoperatefifo((struct vop_generic_args *)ap));
return (ufs_vnoperatespec((struct vop_generic_args *)ap));
}
/*
* Vnode extattr transaction commit/abort
*/

View File

@ -1938,8 +1938,6 @@ ufs_strategy(ap)
int error;
ip = VTOI(vp);
if (vp->v_type == VBLK || vp->v_type == VCHR)
panic("ufs_strategy: spec");
if (bp->b_blkno == bp->b_lblkno) {
error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, bp, NULL, NULL);
bp->b_blkno = blkno;