Nice walter.. I was just going to start separating this out myself and theo distracted me :)
I'll take a look at this right away. On Wed, Nov 25, 2015 at 8:27 AM, Walter Neto <wsouz...@gmail.com> wrote: > Changes needed in buffercache(9) for WAPBL > > - All changes needed in vfs_bio.c > - Adding WAPBL headers > - Introducing buf_adjcnt to inform wapbl when a buffer has changed its size > (get > it from Bitrig) > > Hi guys, with this diff I'm trying to introduce WAPBL to OpenBSD a > little more splitted than before. > > If someone want to see all the implementation, you can get it on > https://github.com/radixo/openbsd-src/tree/wapbl > > I hope to get the feature as soon as possible in OpenBSD. > Thanks in advance guys. :) > > Index: sys/kern/vfs_bio.c > =================================================================== > RCS file: /Volumes/CSP/cvs/src/sys/kern/vfs_bio.c,v > retrieving revision 1.170 > diff -u -r1.170 vfs_bio.c > --- sys/kern/vfs_bio.c 19 Jul 2015 16:21:11 -0000 1.170 > +++ sys/kern/vfs_bio.c 25 Nov 2015 14:37:01 -0000 > @@ -56,7 +56,7 @@ > #include <sys/resourcevar.h> > #include <sys/conf.h> > #include <sys/kernel.h> > -#include <sys/specdev.h> > +#include <sys/wapbl.h> > #include <uvm/uvm_extern.h> > > int nobuffers; > @@ -556,6 +556,16 @@ > mp = NULL; > > /* > + * If using WAPBL, convert it to a delayed write > + */ > + if (mp && mp->mnt_wapbl) { > + if (bp->b_iodone != mp->mnt_wapbl_op->wo_wapbl_biodone) { > + bdwrite(bp); > + return 0; > + } > + } > + > + /* > * Remember buffer type, to switch on it later. If the write was > * synchronous, but the file system was mounted with MNT_ASYNC, > * convert it to a delayed write. > @@ -628,7 +638,6 @@ > return (rv); > } > > - > /* > * Delayed write. > * > @@ -647,6 +656,20 @@ > { > int s; > > + /* If this is a tape block, write the block now. */ > + if (major(bp->b_dev) < nblkdev && > + bdevsw[major(bp->b_dev)].d_type == D_TAPE) { > + bawrite(bp); > + return; > + } > + > + if (wapbl_vphaswapbl(bp->b_vp)) { > + struct mount *mp = wapbl_vptomp(bp->b_vp); > + > + if (bp->b_iodone != mp->mnt_wapbl_op->wo_wapbl_biodone) > + WAPBL_ADD_BUF(mp, bp); > + } > + > /* > * If the block hasn't been seen before: > * (1) Mark it as having been seen, > @@ -663,13 +686,6 @@ > curproc->p_ru.ru_oublock++; /* XXX */ > } > > - /* If this is a tape block, write the block now. */ > - if (major(bp->b_dev) < nblkdev && > - bdevsw[major(bp->b_dev)].d_type == D_TAPE) { > - bawrite(bp); > - return; > - } > - > /* Otherwise, the "write" is done, so mark and release the buffer. */ > CLR(bp->b_flags, B_NEEDCOMMIT); > SET(bp->b_flags, B_DONE); > @@ -743,12 +759,28 @@ > * Determine which queue the buffer should be on, then put it there. > */ > > + /* If it's locked, don't report an error; try again later */ > + if (ISSET(bp->b_flags, (B_LOCKED|B_ERROR)) == (B_LOCKED|B_ERROR)) > + CLR(bp->b_flags, B_ERROR); > + > /* If it's not cacheable, or an error, mark it invalid. */ > if (ISSET(bp->b_flags, (B_NOCACHE|B_ERROR))) > SET(bp->b_flags, B_INVAL); > > if (ISSET(bp->b_flags, B_INVAL)) { > /* > + * If using WAPBL > + */ > + if (ISSET(bp->b_flags, B_LOCKED)) { > + if (wapbl_vphaswapbl(bp->b_vp)) { > + struct mount *mp = wapbl_vptomp(bp->b_vp); > + KASSERT(bp->b_iodone > + != mp->mnt_wapbl_op->wo_wapbl_biodone); > + WAPBL_REMOVE_BUF(mp, bp); > + } > + } > + > + /* > * If the buffer is invalid, free it now rather than leaving > * it in a queue and wasting memory. > */ > @@ -1079,6 +1111,19 @@ > if (!ISSET(bp->b_flags, B_DELWRI)) > panic("Clean buffer on dirty queue"); > #endif > + > + > +#ifdef WAPBL > + if (ISSET(bp->b_flags, B_LOCKED) && > + wapbl_vphaswapbl(bp->b_vp)) { > + brelse(bp); > + struct mount *mp = wapbl_vptomp(bp->b_vp); > + wapbl_flush(mp->mnt_wapbl, 1); > + s = splbio(); > + continue; > + } > +#endif /* WAPBL */ > + > if (LIST_FIRST(&bp->b_dep) != NULL && > !ISSET(bp->b_flags, B_DEFERRED) && > buf_countdeps(bp, 0, 0)) { > @@ -1206,6 +1251,17 @@ > } > #endif > > +void > +buf_adjcnt(struct buf *bp, long ncount) > +{ > + KASSERT(ncount <= bp->b_bufsize); > + long ocount = bp->b_bcount; > + bp->b_bcount = ncount; > + if (wapbl_vphaswapbl(bp->b_vp)) > + WAPBL_RESIZE_BUF(wapbl_vptomp(bp->b_vp), bp, bp->b_bufsize, > + ocount); > +} > + > /* bufcache freelist code below */ > /* > * Copyright (c) 2014 Ted Unangst <t...@openbsd.org> > Index: sys/sys/buf.h > =================================================================== > RCS file: /Volumes/CSP/cvs/src/sys/sys/buf.h,v > retrieving revision 1.99 > diff -u -r1.99 buf.h > --- sys/sys/buf.h 19 Jul 2015 16:21:11 -0000 1.99 > +++ sys/sys/buf.h 25 Nov 2015 14:51:02 -0000 > @@ -221,12 +221,14 @@ > #define B_COLD 0x01000000 /* buffer is on the cold > queue */ > #define B_BC 0x02000000 /* buffer is managed by the > cache */ > #define B_DMA 0x04000000 /* buffer is DMA reachable */ > +#define B_LOCKED 0x08000000 /* Locked in core (not > reusable). */ > > #define B_BITS "\20\001AGE\002NEEDCOMMIT\003ASYNC\004BAD\005BUSY" \ > "\006CACHE\007CALL\010DELWRI\011DONE\012EINTR\013ERROR" \ > "\014INVAL\015NOCACHE\016PHYS\017RAW\020READ" \ > "\021WANTED\022WRITEINPROG\023XXX(FORMAT)\024DEFERRED" \ > - "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA" > + "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA" \ > + "\034LOCKED" > > /* > * This structure describes a clustered I/O. It is stored in the b_saveaddr > @@ -292,6 +294,7 @@ > void bufinit(void); > void buf_dirty(struct buf *); > void buf_undirty(struct buf *); > +void buf_adjcnt(struct buf *, long); > int bwrite(struct buf *); > struct buf *getblk(struct vnode *, daddr_t, int, int, int); > struct buf *geteblk(int); > Index: sys/sys/mount.h > =================================================================== > RCS file: /Volumes/CSP/cvs/src/sys/sys/mount.h,v > retrieving revision 1.121 > diff -u -r1.121 mount.h > --- sys/sys/mount.h 8 Sep 2014 01:47:06 -0000 1.121 > +++ sys/sys/mount.h 25 Nov 2015 14:46:45 -0000 > @@ -358,6 +358,11 @@ > int mnt_maxsymlinklen; /* max size of short symlink > */ > struct statfs mnt_stat; /* cache of filesystem stats > */ > void *mnt_data; /* private data */ > + struct wapbl_ops > + *mnt_wapbl_op; /* logging ops */ > + struct wapbl *mnt_wapbl; /* log info */ > + struct wapbl_replay > + *mnt_wapbl_replay; /* replay support XXX: what? > */ > }; > > /* > @@ -501,6 +506,51 @@ > extern int bufbackoff(struct uvm_constraint_range*, long); > > /* > + * This operations vector is so wapbl can be wrapped into a filesystem lkm. > + * XXX Eventually, we want to move this functionality > + * down into the filesystems themselves so that this isn't needed. > + */ > +struct wapbl_ops { > + void (*wo_wapbl_discard)(struct wapbl *); > + int (*wo_wapbl_replay_isopen)(struct wapbl_replay *); > + int (*wo_wapbl_replay_can_read)(struct wapbl_replay *, daddr_t, long); > + int (*wo_wapbl_replay_read)(struct wapbl_replay *, void *, daddr_t, > + long); > + void (*wo_wapbl_add_buf)(struct wapbl *, struct buf *); > + void (*wo_wapbl_remove_buf)(struct wapbl *, struct buf *); > + void (*wo_wapbl_resize_buf)(struct wapbl *, struct buf *, long, long); > + int (*wo_wapbl_begin)(struct wapbl *, const char *, int); > + void (*wo_wapbl_end)(struct wapbl *); > + void (*wo_wapbl_junlock_assert)(struct wapbl *); > + void (*wo_wapbl_biodone)(struct buf *); > +}; > +#define WAPBL_DISCARD(MP) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_discard)((MP)->mnt_wapbl) > +#define WAPBL_REPLAY_ISOPEN(MP) > \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_replay_isopen)((MP)->mnt_wapbl_replay) > +#define WAPBL_REPLAY_CAN_READ(MP, BLK, LEN) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_replay_can_read)((MP)->mnt_wapbl_replay, \ > + (BLK), (LEN)) > +#define WAPBL_REPLAY_READ(MP, DATA, BLK, LEN) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_replay_read)((MP)->mnt_wapbl_replay, > \ > + (DATA), (BLK), (LEN)) > +#define WAPBL_ADD_BUF(MP, BP) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_add_buf)((MP)->mnt_wapbl, (BP)) > +#define WAPBL_REMOVE_BUF(MP, BP) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_remove_buf)((MP)->mnt_wapbl, (BP)) > +#define WAPBL_RESIZE_BUF(MP, BP, OLDSZ, OLDCNT) > \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_resize_buf)((MP)->mnt_wapbl, (BP), \ > + (OLDSZ), (OLDCNT)) > +#define WAPBL_BEGIN(MP) > \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_begin)((MP)->mnt_wapbl, \ > + __FILE__, __LINE__) > +#define WAPBL_END(MP) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_end)((MP)->mnt_wapbl) > +#define WAPBL_JUNLOCK_ASSERT(MP) \ > + (*(MP)->mnt_wapbl_op->wo_wapbl_junlock_assert)((MP)->mnt_wapbl) > + > + > +/* > * Operations supported on mounted file system. > */ > struct nameidata; >