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

Reply via email to