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.

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

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?

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