At first go, you need a bit more #ifdef WAPBL in there.. the idea being we want to be able to build kernels selectively with and without WAPBL compiled in at all.... and initially we may not (by default) put it in GENERIC.
I'll mail you a diff shortly. On Wed, Nov 25, 2015 at 10:55 AM, Bob Beck <b...@openbsd.org> wrote: > 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; >>