lkml.org 
[lkml]   [2008]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 27/48] [GFS2] Add a function to interate over an extent
    Date
    From: Steven Whitehouse <swhiteho@redhat.com>

    This adds a function (currently the only use is during mapping
    of already allocated blocks, but watch this space) which iterates
    over a number of pointers in a block and returns the extent length.

    If the initial pointer is 0 (i.e. unallocated) it will return the
    number of unallocated blocks in the extent. If the initial pointer
    is allocated, then it returns the number of contiguously allocated
    blocks in the extent.

    Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

    diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
    index 7f72564..6780aa5 100644
    --- a/fs/gfs2/bmap.c
    +++ b/fs/gfs2/bmap.c
    @@ -422,6 +422,42 @@ static void release_metapath(struct metapath *mp)
    brelse(mp->mp_bh[i]);
    }

    +/**
    + * gfs2_extent_length - Returns length of an extent of blocks
    + * @start: Start of the buffer
    + * @len: Length of the buffer in bytes
    + * @ptr: Current position in the buffer
    + * @limit: Max extent length to return (0 = unlimited)
    + * @eob: Set to 1 if we hit "end of block"
    + *
    + * If the first block is zero (unallocated) it will return the number of
    + * unallocated blocks in the extent, otherwise it will return the number
    + * of contiguous blocks in the extent.
    + *
    + * Returns: The length of the extent (minimum of one block)
    + */
    +
    +static inline unsigned int gfs2_extent_length(void *start, unsigned int len, __be64 *ptr, unsigned limit, int *eob)
    +{
    + const __be64 *end = (start + len);
    + const __be64 *first = ptr;
    + u64 d = be64_to_cpu(*ptr);
    +
    + *eob = 0;
    + do {
    + ptr++;
    + if (ptr >= end)
    + break;
    + if (limit && --limit == 0)
    + break;
    + if (d)
    + d++;
    + } while(be64_to_cpu(*ptr) == d);
    + if (ptr >= end)
    + *eob = 1;
    + return (ptr - first);
    +}
    +
    static inline void bmap_lock(struct inode *inode, int create)
    {
    struct gfs2_inode *ip = GFS2_I(inode);
    @@ -499,26 +535,26 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
    goto out_fail;
    boundary = error;

    + if (new) {
    + map_bh(bh_map, inode->i_sb, dblock);
    + if (boundary)
    + set_buffer_boundary(bh_map);
    + gfs2_trans_add_bh(ip->i_gl, mp.mp_bh[0], 1);
    + gfs2_dinode_out(ip, mp.mp_bh[0]->b_data);
    + set_buffer_new(bh_map);
    + goto out_ok;
    + }
    +
    if (dblock) {
    + unsigned int len;
    + struct buffer_head *bh = mp.mp_bh[ip->i_height - 1];
    + __be64 *ptr = metapointer(&boundary, ip->i_height - 1, &mp);
    map_bh(bh_map, inode->i_sb, dblock);
    + len = gfs2_extent_length(bh->b_data, bh->b_size, ptr, maxlen,
    + &boundary);
    + bh_map->b_size = (len << inode->i_blkbits);
    if (boundary)
    set_buffer_boundary(bh_map);
    - if (new) {
    - gfs2_trans_add_bh(ip->i_gl, mp.mp_bh[0], 1);
    - gfs2_dinode_out(ip, mp.mp_bh[0]->b_data);
    - set_buffer_new(bh_map);
    - goto out_ok;
    - }
    - while(--maxlen && !buffer_boundary(bh_map)) {
    - u64 eblock;
    - mp.mp_list[ip->i_height - 1]++;
    - boundary = lookup_block(ip, ip->i_height - 1, &mp, 0, &new, &eblock);
    - if (eblock != ++dblock)
    - break;
    - bh_map->b_size += (1 << inode->i_blkbits);
    - if (boundary)
    - set_buffer_boundary(bh_map);
    - }
    }
    out_ok:
    error = 0;
    --
    1.5.1.2


    \
     
     \ /
      Last update: 2008-04-17 11:49    [W:0.023 / U:64.204 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site