On Sat, Nov 28, 2015 at 03:49:21PM -0700, Bob Beck wrote:
> On Fri, Nov 27, 2015 at 02:50:57PM -0200, Walter Neto wrote:
> 
> You have a number of places here where you introduce a line of 8 spaces
> after your #endif - please clean up the trailing spaces, they shouldn't be 
> there.
> 
Ok, cleaned :)

> You also have uses of B_METAONLY that are not inside a #ifdef WAPBL in 
> ffs_balloc.c
>

Yeah, but I don't know what is the best way to correct it.
Should I use:
#ifdef WAPBL
        foo(..., flags | B_METAONLY, ...);
#else
        foo(..., flags, ...);
#endif

or

        foo(..., flags
#ifdef WAPBL
            | B_METAONLY
#endif
            , ...)

?

(Waiting this answer to send the fixed diff.

> The first one I mostly get - as we are only looking for the first indirect 
> block
> this makes sense.   the second usage I'm not sure is correct... is it?
> 

Yes Bob, It is correct! After many hours reading and re-reading the FFS
code (it is a dragon) I understood it better, and the socond makes sense
too cause it is where other data block is been allocated to store new
indirect data-blocks address, so it is a B_METAONLY data-block.

I don't know if I was clear, any doubts we can discuss.

> I would like some more FFS savvy eyes on this one and not just me. 
> (This is a large hint to some other people)
> 
> -Bob
> 
> 
> > After mpi@ review
> > 
> > --
> > Walter Neto
> > 
> > diff --git a/sys/sys/buf.h b/sys/sys/buf.h
> > index c47f3f9..fd38c28 100644
> > --- a/sys/sys/buf.h
> > +++ b/sys/sys/buf.h
> > @@ -254,6 +254,8 @@ struct cluster_save {
> >  /* Flags to low-level allocation routines. */
> >  #define B_CLRBUF   0x01    /* Request allocated buffer be cleared. */
> >  #define B_SYNC             0x02    /* Do all allocations synchronously. */
> > +#define B_METAONLY 0x04    /* return indirect block buffer */
> > +#define B_CONTIG   0x08    /* allocate file contiguously */
> >  
> >  struct cluster_info {
> >     daddr_t ci_lastr;       /* last read (read-ahead) */
> > diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
> > index 08961b9..807a2d1 100644
> > --- a/sys/ufs/ffs/ffs_alloc.c
> > +++ b/sys/ufs/ffs/ffs_alloc.c
> > @@ -63,16 +63,19 @@
> >         (fs)->fs_fsmnt, (cp));                              \
> >  } while (0)
> >  
> > -daddr_t            ffs_alloccg(struct inode *, int, daddr_t, int);
> > +daddr_t            ffs_alloccg(struct inode *, int, daddr_t, int, int);
> >  struct buf *       ffs_cgread(struct fs *, struct inode *, int);
> > -daddr_t            ffs_alloccgblk(struct inode *, struct buf *, daddr_t);
> > -daddr_t            ffs_clusteralloc(struct inode *, int, daddr_t, int);
> > +daddr_t            ffs_alloccgblk(struct inode *, struct buf *, daddr_t, 
> > int);
> > +daddr_t            ffs_clusteralloc(struct inode *, int, daddr_t, int, 
> > int);
> >  ufsino_t   ffs_dirpref(struct inode *);
> >  daddr_t            ffs_fragextend(struct inode *, int, daddr_t, int, int);
> > -daddr_t            ffs_hashalloc(struct inode *, int, daddr_t, int,
> > -               daddr_t (*)(struct inode *, int, daddr_t, int));
> > -daddr_t            ffs_nodealloccg(struct inode *, int, daddr_t, int);
> > +daddr_t            ffs_hashalloc(struct inode *, int, daddr_t, int, int,
> > +                    daddr_t (*)(struct inode *, int, daddr_t, int, int));
> > +daddr_t            ffs_nodealloccg(struct inode *, int, daddr_t, int, int);
> >  daddr_t            ffs_mapsearch(struct fs *, struct cg *, daddr_t, int);
> > +void               ffs_blkfree_subr(struct fs *, struct vnode *,
> > +               struct inode *, daddr_t bno, long size);
> > +
> >  
> >  int ffs1_reallocblks(void *);
> >  #ifdef FFS2
> > @@ -106,7 +109,7 @@ static const struct timeval     fserr_interval = { 2, 0 
> > };
> >   *      available block is located.
> >   */
> >  int
> > -ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size,
> > +ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size, int 
> > flags,
> >      struct ucred *cred, daddr_t *bnp)
> >  {
> >     static struct timeval fsfull_last;
> > @@ -147,7 +150,7 @@ ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, 
> > int size,
> >             cg = dtog(fs, bpref);
> >  
> >     /* Try allocating a block. */
> > -   bno = ffs_hashalloc(ip, cg, bpref, size, ffs_alloccg);
> > +   bno = ffs_hashalloc(ip, cg, bpref, size, flags, ffs_alloccg);
> >     if (bno > 0) {
> >             /* allocation successful, update inode data */
> >             DIP_ADD(ip, blocks, btodb(size));
> > @@ -159,6 +162,14 @@ ffs_alloc(struct inode *ip, daddr_t lbn, daddr_t 
> > bpref, int size,
> >     /* Restore user's disk quota because allocation failed. */
> >     (void) ufs_quota_free_blocks(ip, btodb(size), cred);
> >  
> > +#ifdef WAPBL
> > +   if (flags & B_CONTIG) {
> > +           /*
> > +            * Fail silently -- it's up to our caller to report errors.
> > +            */
> > +           return (ENOSPC);
> > +   }
> > +#endif /* WAPBL */
> >  nospace:
> >     if (ratecheck(&fsfull_last, &fserr_interval)) {
> >             ffs_fserr(fs, cred->cr_uid, "file system full");
> > @@ -178,7 +189,7 @@ nospace:
> >   */
> >  int
> >  ffs_realloccg(struct inode *ip, daddr_t lbprev, daddr_t bpref, int osize,
> > -    int nsize, struct ucred *cred, struct buf **bpp, daddr_t *blknop)
> > +    int nsize, int flags, struct ucred *cred, struct buf **bpp, daddr_t 
> > *blknop)
> >  {
> >     static struct timeval fsfull_last;
> >     struct fs *fs;
> > @@ -295,7 +306,7 @@ ffs_realloccg(struct inode *ip, daddr_t lbprev, daddr_t 
> > bpref, int osize,
> >             panic("ffs_realloccg: bad optim");
> >             /* NOTREACHED */
> >     }
> > -   bno = ffs_hashalloc(ip, cg, bpref, request, ffs_alloccg);
> > +   bno = ffs_hashalloc(ip, cg, bpref, request, flags, ffs_alloccg);
> >     if (bno <= 0)
> >             goto nospace;
> >  
> > @@ -434,7 +445,7 @@ ffs1_reallocblks(void *v)
> >     /*
> >      * Find the preferred location for the cluster.
> >      */
> > -   pref = ffs1_blkpref(ip, start_lbn, soff, sbap);
> > +   pref = ffs1_blkpref(ip, start_lbn, soff, 0, sbap);
> >     /*
> >      * If the block range spans two block maps, get the second map.
> >      */
> > @@ -454,7 +465,7 @@ ffs1_reallocblks(void *v)
> >     /*
> >      * Search the block map looking for an allocation of the desired size.
> >      */
> > -   if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref, len,
> > +   if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref, len, 0,
> >         ffs_clusteralloc)) == 0)
> >             goto fail;
> >     /*
> > @@ -660,13 +671,13 @@ ffs2_reallocblks(void *v)
> >     /*
> >      * Find the preferred location for the cluster.
> >      */
> > -   pref = ffs2_blkpref(ip, start_lbn, soff, sbap);
> > +   pref = ffs2_blkpref(ip, start_lbn, soff, 0, sbap);
> >  
> >     /*
> >      * Search the block map looking for an allocation of the desired size.
> >      */
> >     if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
> > -       len, ffs_clusteralloc)) == 0)
> > +       len, 0, ffs_clusteralloc)) == 0)
> >             goto fail;
> >  
> >     /*
> > @@ -855,7 +866,7 @@ ffs_inode_alloc(struct inode *pip, mode_t mode, struct 
> > ucred *cred,
> >             if (fs->fs_contigdirs[cg] > 0)
> >                     fs->fs_contigdirs[cg]--;
> >     }
> > -   ino = (ufsino_t)ffs_hashalloc(pip, cg, ipref, mode, ffs_nodealloccg);
> > +   ino = (ufsino_t)ffs_hashalloc(pip, cg, ipref, mode, 0, ffs_nodealloccg);
> >     if (ino == 0)
> >             goto noinodes;
> >     error = VFS_VGET(pvp->v_mount, ino, vpp);
> > @@ -1060,7 +1071,7 @@ end:
> >   * allocated.
> >   */
> >  int32_t
> > -ffs1_blkpref(struct inode *ip, daddr_t lbn, int indx, int32_t *bap)
> > +ffs1_blkpref(struct inode *ip, daddr_t lbn, int indx, int flags, int32_t 
> > *bap)
> >  {
> >     struct fs *fs;
> >     int cg, inocg, avgbfree, startcg;
> > @@ -1068,6 +1079,28 @@ ffs1_blkpref(struct inode *ip, daddr_t lbn, int 
> > indx, int32_t *bap)
> >  
> >     KASSERT(indx <= 0 || bap != NULL);
> >     fs = ip->i_fs;
> > +
> > +#ifdef WAPBL
> > +   /*
> > +    * If allocating a contiguous file with B_CONTIG, use the hints
> > +    * in the inode extentions to return the desired block.
> > +    *
> > +    * For metadata (indirect blocks) return the address of where
> > +    * the first indirect block resides - we'll scan for the next
> > +    * available slot if we need to allocate more than one indirect
> > +    * block.  For data, return the address of the actual block
> > +    * relative to the address of the first data block.
> > +    */
> > +   if (flags & B_CONTIG) {
> > +           KASSERT(ip->i_ffs_first_data_blk != 0);
> > +           KASSERT(ip->i_ffs_first_indir_blk != 0);
> > +           if (flags & B_METAONLY)
> > +                   return ip->i_ffs_first_indir_blk;
> > +           else
> > +                   return ip->i_ffs_first_data_blk + blkstofrags(fs, lbn);
> > +   }
> > +#endif /* WAPBL */
> > +   
> >     /*
> >      * Allocation of indirect blocks is indicated by passing negative
> >      * values in indx: -1 for single indirect, -2 for double indirect,
> > @@ -1160,7 +1193,7 @@ ffs1_blkpref(struct inode *ip, daddr_t lbn, int indx, 
> > int32_t *bap)
> >   */
> >  #ifdef FFS2
> >  int64_t
> > -ffs2_blkpref(struct inode *ip, daddr_t lbn, int indx, int64_t *bap)
> > +ffs2_blkpref(struct inode *ip, daddr_t lbn, int indx, int flags, int64_t 
> > *bap)
> >  {
> >     struct fs *fs;
> >     int cg, inocg, avgbfree, startcg;
> > @@ -1168,6 +1201,28 @@ ffs2_blkpref(struct inode *ip, daddr_t lbn, int 
> > indx, int64_t *bap)
> >  
> >     KASSERT(indx <= 0 || bap != NULL);
> >     fs = ip->i_fs;
> > +
> > +#ifdef WAPBL
> > +   /*
> > +    * If allocating a contiguous file with B_CONTIG, use the hints
> > +    * in the inode extentions to return the desired block.
> > +    *
> > +    * For metadata (indirect blocks) return the address of where
> > +    * the first indirect block resides - we'll scan for the next
> > +    * available slot if we need to allocate more than one indirect
> > +    * block.  For data, return the address of the actual block
> > +    * relative to the address of the first data block.
> > +    */
> > +   if (flags & B_CONTIG) {
> > +           KASSERT(ip->i_ffs_first_data_blk != 0);
> > +           KASSERT(ip->i_ffs_first_indir_blk != 0);
> > +           if (flags & B_METAONLY)
> > +                   return ip->i_ffs_first_indir_blk;
> > +           else
> > +                   return ip->i_ffs_first_data_blk + blkstofrags(fs, lbn);
> > +   }
> > +#endif /* WAPBL */
> > +   
> >     /*
> >      * Allocation of indirect blocks is indicated by passing negative
> >      * values in indx: -1 for single indirect, -2 for double indirect,
> > @@ -1267,8 +1322,8 @@ ffs2_blkpref(struct inode *ip, daddr_t lbn, int indx, 
> > int64_t *bap)
> >   *   3) brute force search for a free block.
> >   */
> >  daddr_t
> > -ffs_hashalloc(struct inode *ip, int cg, daddr_t pref, int size,
> > -    daddr_t (*allocator)(struct inode *, int, daddr_t, int))
> > +ffs_hashalloc(struct inode *ip, int cg, daddr_t pref, int size, int flags,
> > +    daddr_t (*allocator)(struct inode *, int, daddr_t, int, int))
> >  {
> >     struct fs *fs;
> >     daddr_t result;
> > @@ -1278,9 +1333,15 @@ ffs_hashalloc(struct inode *ip, int cg, daddr_t 
> > pref, int size,
> >     /*
> >      * 1: preferred cylinder group
> >      */
> > -   result = (*allocator)(ip, cg, pref, size);
> > +   result = (*allocator)(ip, cg, pref, size, flags);
> >     if (result)
> >             return (result);
> > +
> > +#ifdef WAPBL
> > +   if (flags & B_CONTIG)
> > +           return (result);
> > +#endif /* WAPBL */
> > +   
> >     /*
> >      * 2: quadratic rehash
> >      */
> > @@ -1288,7 +1349,7 @@ ffs_hashalloc(struct inode *ip, int cg, daddr_t pref, 
> > int size,
> >             cg += i;
> >             if (cg >= fs->fs_ncg)
> >                     cg -= fs->fs_ncg;
> > -           result = (*allocator)(ip, cg, 0, size);
> > +           result = (*allocator)(ip, cg, 0, size, flags);
> >             if (result)
> >                     return (result);
> >     }
> > @@ -1299,7 +1360,7 @@ ffs_hashalloc(struct inode *ip, int cg, daddr_t pref, 
> > int size,
> >      */
> >     cg = (icg + 2) % fs->fs_ncg;
> >     for (i = 2; i < fs->fs_ncg; i++) {
> > -           result = (*allocator)(ip, cg, 0, size);
> > +           result = (*allocator)(ip, cg, 0, size, flags);
> >             if (result)
> >                     return (result);
> >             cg++;
> > @@ -1398,7 +1459,7 @@ ffs_fragextend(struct inode *ip, int cg, daddr_t 
> > bprev, int osize, int nsize)
> >   * and if it is, allocate it.
> >   */
> >  daddr_t
> > -ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, int size)
> > +ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, int size, int flags)
> >  {
> >     struct fs *fs;
> >     struct cg *cgp;
> > @@ -1423,7 +1484,7 @@ ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, 
> > int size)
> >  
> >     if (size == fs->fs_bsize) {
> >             /* allocate and return a complete data block */
> > -           bno = ffs_alloccgblk(ip, bp, bpref);
> > +           bno = ffs_alloccgblk(ip, bp, bpref, flags);
> >             bdwrite(bp);
> >             return (bno);
> >     }
> > @@ -1445,7 +1506,7 @@ ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, 
> > int size)
> >                     brelse(bp);
> >                     return (0);
> >             }
> > -           bno = ffs_alloccgblk(ip, bp, bpref);
> > +           bno = ffs_alloccgblk(ip, bp, bpref, flags);
> >             bpref = dtogd(fs, bno);
> >             for (i = frags; i < fs->fs_frag; i++)
> >                     setbit(cg_blksfree(cgp), bpref + i);
> > @@ -1487,7 +1548,7 @@ ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, 
> > int size)
> >   * blocks may be fragmented by the routine that allocates them.
> >   */
> >  daddr_t
> > -ffs_alloccgblk(struct inode *ip, struct buf *bp, daddr_t bpref)
> > +ffs_alloccgblk(struct inode *ip, struct buf *bp, daddr_t bpref, int flags)
> >  {
> >     struct fs *fs;
> >     struct cg *cgp;
> > @@ -1514,6 +1575,15 @@ ffs_alloccgblk(struct inode *ip, struct buf *bp, 
> > daddr_t bpref)
> >     bno = dtogd(fs, blknum(fs, bpref));
> >     if (ffs_isblock(fs, blksfree, fragstoblks(fs, bno)))
> >             goto gotit;
> > +#ifdef WAPBL
> > +   /*
> > +    * if the requested data block isn't available and we are trying to
> > +    * allocate a contiguous file,  return an error.
> > +    */
> > +   if ((flags & (B_CONTIG | B_METAONLY)) == B_CONTIG)
> > +           return (0);
> > +#endif /* WAPBL */
> > +
> >     /*
> >      * Take the next available block in this cylinder group.
> >      */
> > @@ -1556,7 +1626,7 @@ gotit:
> >   * take the first one that we find following bpref.
> >   */
> >  daddr_t
> > -ffs_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len)
> > +ffs_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len, int 
> > flags)
> >  {
> >     struct fs *fs;
> >     struct cg *cgp;
> > @@ -1651,7 +1721,7 @@ ffs_clusteralloc(struct inode *ip, int cg, daddr_t 
> > bpref, int len)
> >  
> >     len = blkstofrags(fs, len);
> >     for (i = 0; i < len; i += fs->fs_frag)
> > -           if (ffs_alloccgblk(ip, bp, bno + i) != bno + i)
> > +           if (ffs_alloccgblk(ip, bp, bno + i, flags) != bno + i)
> >                     panic("ffs_clusteralloc: lost block");
> >     bdwrite(bp);
> >     return (bno);
> > @@ -1663,7 +1733,7 @@ fail:
> >  
> >  /* inode allocation routine */
> >  daddr_t
> > -ffs_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode)
> > +ffs_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode, int 
> > flags)
> >  {
> >     struct fs *fs;
> >     struct cg *cgp;
> > diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
> > index ef9f6d4..34cffa6 100644
> > --- a/sys/ufs/ffs/ffs_balloc.c
> > +++ b/sys/ufs/ffs/ffs_balloc.c
> > @@ -103,8 +103,9 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >             osize = blksize(fs, ip, nb);
> >             if (osize < fs->fs_bsize && osize > 0) {
> >                     error = ffs_realloccg(ip, nb,
> > -                       ffs1_blkpref(ip, nb, (int)nb, &ip->i_ffs1_db[0]),
> > -                       osize, (int)fs->fs_bsize, cred, bpp, &newb);
> > +                       ffs1_blkpref(ip, nb, (int)nb, flags,
> > +                       &ip->i_ffs1_db[0]), osize, (int)fs->fs_bsize,
> > +                       flags, cred, bpp, &newb);
> >                     if (error)
> >                             return (error);
> >                     if (DOINGSOFTDEP(vp))
> > @@ -174,9 +175,9 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >                              * want, grow it.
> >                              */
> >                             error = ffs_realloccg(ip, lbn,
> > -                               ffs1_blkpref(ip, lbn, (int)lbn,
> > +                               ffs1_blkpref(ip, lbn, (int)lbn, flags,
> >                                     &ip->i_ffs1_db[0]),
> > -                               osize, nsize, cred, bpp, &newb);
> > +                               osize, nsize, flags, cred, bpp, &newb);
> >                             if (error)
> >                                     return (error);
> >                             if (DOINGSOFTDEP(vp))
> > @@ -195,8 +196,8 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >                     else
> >                             nsize = fs->fs_bsize;
> >                     error = ffs_alloc(ip, lbn,
> > -                       ffs1_blkpref(ip, lbn, (int)lbn, &ip->i_ffs1_db[0]),
> > -                       nsize, cred, &newb);
> > +                       ffs1_blkpref(ip, lbn, (int)lbn, flags,
> > +                       &ip->i_ffs1_db[0]), nsize, flags, cred, &newb);
> >                     if (error)
> >                             return (error);
> >                     if (bpp != NULL) {
> > @@ -235,9 +236,10 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >     allocib = NULL;
> >     allocblk = allociblk;
> >     if (nb == 0) {
> > -           pref = ffs1_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL);
> > +           pref = ffs1_blkpref(ip, lbn, -indirs[0].in_off - 1,
> > +               flags | B_METAONLY, NULL);
> >             error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
> > -                             cred, &newb);
> > +               flags | B_METAONLY, cred, &newb);
> >             if (error)
> >                     goto fail;
> >             nb = newb;
> > @@ -283,9 +285,10 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >                     continue;
> >             }
> >             if (pref == 0)
> > -                   pref = ffs1_blkpref(ip, lbn, i - num - 1, NULL);
> > -           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
> > -                             &newb);
> > +                   pref = ffs1_blkpref(ip, lbn, i - num - 1,
> > +                       flags | B_METAONLY, NULL);
> > +           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
> > +               flags | B_METAONLY, cred, &newb);
> >             if (error) {
> >                     brelse(bp);
> >                     goto fail;
> > @@ -323,13 +326,22 @@ ffs1_balloc(struct inode *ip, off_t startoffset, int 
> > size, struct ucred *cred,
> >                     bdwrite(bp);
> >             }
> >     }
> > +
> > +#ifdef WAPBL
> > +   if (flags & B_METAONLY) {
> > +           KASSERT(bpp != NULL);
> > +           *bpp = bp;
> > +           return (0);
> > +   }
> > +#endif /* WAPBL */
> > +   
> >     /*
> >      * Get the data block, allocating if necessary.
> >      */
> >     if (nb == 0) {
> > -           pref = ffs1_blkpref(ip, lbn, indirs[i].in_off, &bap[0]);
> > -           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
> > -                             &newb);
> > +           pref = ffs1_blkpref(ip, lbn, indirs[i].in_off, flags, &bap[0]);
> > +           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, flags,
> > +               cred, &newb);
> >             if (error) {
> >                     brelse(bp);
> >                     goto fail;
> > @@ -468,8 +480,8 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >             osize = blksize(fs, ip, nb);
> >             if (osize < fs->fs_bsize && osize > 0) {
> >                     error = ffs_realloccg(ip, nb, ffs2_blkpref(ip,
> > -                       lastlbn, nb, &ip->i_ffs2_db[0]), osize,
> > -                       (int) fs->fs_bsize, cred, bpp, &newb);
> > +                       lastlbn, nb, flags, &ip->i_ffs2_db[0]), osize,
> > +                       (int) fs->fs_bsize, flags, cred, bpp, &newb);
> >                     if (error)
> >                             return (error);
> >  
> > @@ -545,9 +557,9 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >                              * grow it.
> >                              */
> >                             error = ffs_realloccg(ip, lbn,
> > -                               ffs2_blkpref(ip, lbn, (int) lbn,
> > -                               &ip->i_ffs2_db[0]), osize, nsize, cred,
> > -                               bpp, &newb);
> > +                               ffs2_blkpref(ip, lbn, (int) lbn, flags,
> > +                               &ip->i_ffs2_db[0]), osize, nsize, flags,
> > +                               cred, bpp, &newb);
> >                             if (error)
> >                                     return (error);
> >  
> > @@ -567,7 +579,8 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >                             nsize = fs->fs_bsize;
> >  
> >                     error = ffs_alloc(ip, lbn, ffs2_blkpref(ip, lbn,
> > -                       (int) lbn, &ip->i_ffs2_db[0]), nsize, cred, &newb);
> > +                       (int) lbn, flags, &ip->i_ffs2_db[0]), nsize, flags,
> > +                       cred, &newb);
> >                     if (error)
> >                             return (error);
> >  
> > @@ -614,9 +627,10 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >     allocblk = allociblk;
> >  
> >     if (nb == 0) {
> > -           pref = ffs2_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL);
> > -           error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred,
> > -               &newb);
> > +           pref = ffs2_blkpref(ip, lbn, -indirs[0].in_off - 1,
> > +               flags | B_METAONLY, NULL);
> > +           error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize,
> > +               flags | B_METAONLY, cred, &newb);
> >             if (error)
> >                     goto fail;
> >  
> > @@ -670,10 +684,11 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >             }
> >  
> >             if (pref == 0)
> > -                   pref = ffs2_blkpref(ip, lbn, i - num - 1, NULL);
> > +                   pref = ffs2_blkpref(ip, lbn, i - num - 1,
> > +                       flags | B_METAONLY, NULL);
> >  
> > -           error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred,
> > -               &newb);
> > +           error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize,
> > +               flags | B_METAONLY, cred, &newb);
> >             if (error) {
> >                     brelse(bp);
> >                     goto fail;
> > @@ -716,14 +731,23 @@ ffs2_balloc(struct inode *ip, off_t off, int size, 
> > struct ucred *cred,
> >                     bdwrite(bp);
> >     }
> >  
> > +#ifdef WAPBL
> > +   if (flags & B_METAONLY) {
> > +           KASSERT(bpp != NULL);
> > +           *bpp = bp;
> > +           return (0);
> > +   }
> > +#endif /* WAPBL */
> > +   
> >     /*
> >      * Get the data block, allocating if necessary.
> >      */
> >     if (nb == 0) {
> > -           pref = ffs2_blkpref(ip, lbn, indirs[num].in_off, &bap[0]);
> > +           pref = ffs2_blkpref(ip, lbn, indirs[num].in_off, flags,
> > +               &bap[0]);
> >  
> > -           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
> > -               &newb);
> > +           error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, flags,
> > +               cred, &newb);
> >             if (error) {
> >                     brelse(bp);
> >                     goto fail;
> > diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
> > index 3e41bb3..502601b 100644
> > --- a/sys/ufs/ffs/ffs_extern.h
> > +++ b/sys/ufs/ffs/ffs_extern.h
> > @@ -99,19 +99,20 @@ extern struct vops      ffs_specvops;
> >  extern struct vops ffs_fifovops;
> >  
> >  /* ffs_alloc.c */
> > -int ffs_alloc(struct inode *, daddr_t, daddr_t , int, struct ucred *,
> > -              daddr_t *);
> > -int ffs_realloccg(struct inode *, daddr_t, daddr_t, int, int ,
> > -                  struct ucred *, struct buf **, daddr_t *);
> > +int ffs_alloc(struct inode *, daddr_t, daddr_t , int, int, struct ucred *,
> > +       daddr_t *);
> > +int ffs_realloccg(struct inode *, daddr_t, daddr_t, int, int, int,
> > +       struct ucred *, struct buf **, daddr_t *);
> >  int ffs_reallocblks(void *);
> >  int ffs_inode_alloc(struct inode *, mode_t, struct ucred *, struct vnode 
> > **);
> >  int ffs_inode_free(struct inode *, ufsino_t, mode_t);
> >  int ffs_freefile(struct inode *, ufsino_t, mode_t);
> >  
> > -int32_t ffs1_blkpref(struct inode *, daddr_t, int, int32_t *);
> > +int32_t ffs1_blkpref(struct inode *, daddr_t, int, int, int32_t *);
> >  #ifdef FFS2
> > -int64_t ffs2_blkpref(struct inode *, daddr_t, int, int64_t *);
> > +int64_t ffs2_blkpref(struct inode *, daddr_t, int, int, int64_t *);
> >  #endif
> > +int ffs_blkalloc_ump(struct ufsmount *, daddr_t, long);
> >  void ffs_blkfree(struct inode *, daddr_t, long);
> >  void ffs_clusteracct(struct fs *, struct cg *, daddr_t, int);
> >  
> > diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
> > index a253b25..70301e5 100644
> > --- a/sys/ufs/ufs/inode.h
> > +++ b/sys/ufs/ufs/inode.h
> > @@ -48,6 +48,13 @@
> >  /*
> >   * Per-filesystem inode extensions.
> >   */
> > +struct ffs_inode_ext {
> > +   daddr_t *ffs_snapblklist;       /* Collect expunged snapshot blocks. */
> > +   /* follow two fields are used by contiguous allocation code only. */
> > +   daddr_t ffs_first_data_blk;     /* first data block on disk. */
> > +   daddr_t ffs_first_indir_blk;    /* first indirect block on disk. */
> > +};
> > +
> >  struct ext2fs_inode_ext {
> >     u_int32_t       ext2fs_last_lblk;       /* last logical blk allocated */
> >     u_int32_t       ext2fs_last_blk;        /* last blk allocated on disk */
> > @@ -102,10 +109,13 @@ struct inode {
> >      */
> >     union {
> >             /* Other extensions could go here... */
> > +           struct ffs_inode_ext ffs;
> >             struct ext2fs_inode_ext   e2fs;
> >             struct dirhash *dirhash;
> >     } inode_ext;
> >  
> > +#define i_ffs_first_data_blk       inode_ext.ffs.ffs_first_data_blk
> > +#define i_ffs_first_indir_blk      inode_ext.ffs.ffs_first_indir_blk
> >  #define i_e2fs_last_lblk   inode_ext.e2fs.ext2fs_last_lblk
> >  #define i_e2fs_last_blk            inode_ext.e2fs.ext2fs_last_blk
> >  #define i_e2fs_uid         inode_ext.e2fs.ext2fs_effective_uid
> > 

Reply via email to