Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270002
b: refs/heads/master
c: d56fa8a
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Oct 21, 2011
1 parent e6b557d commit b635d17
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 79 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 534029e2fd06ac9a5a1b33b2735e3ac3242adb29
refs/heads/master: d56fa8a1c17b68274349fc852f634af99c0c4671
149 changes: 71 additions & 78 deletions trunk/fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ struct metapath {
__u16 mp_list[GFS2_MAX_META_HEIGHT];
};

typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh,
struct buffer_head *bh, __be64 *top,
__be64 *bottom, unsigned int height,
void *data);

struct strip_mine {
int sm_first;
unsigned int sm_height;
Expand Down Expand Up @@ -667,76 +662,6 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
return ret;
}

/**
* recursive_scan - recursively scan through the end of a file
* @ip: the inode
* @dibh: the dinode buffer
* @mp: the path through the metadata to the point to start
* @height: the height the recursion is at
* @block: the indirect block to look at
* @first: 1 if this is the first block
* @bc: the call to make for each piece of metadata
* @data: data opaque to this function to pass to @bc
*
* When this is first called @height and @block should be zero and
* @first should be 1.
*
* Returns: errno
*/

static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
struct metapath *mp, unsigned int height,
u64 block, int first, block_call_t bc,
void *data)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *bh = NULL;
__be64 *top, *bottom;
u64 bn;
int error;
int mh_size = sizeof(struct gfs2_meta_header);

if (!height) {
error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
return error;
dibh = bh;

top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0];
bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs;
} else {
error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh);
if (error)
return error;

top = (__be64 *)(bh->b_data + mh_size) +
(first ? mp->mp_list[height] : 0);

bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs;
}

error = bc(ip, dibh, bh, top, bottom, height, data);
if (error)
goto out;

if (height < ip->i_height - 1)
for (; top < bottom; top++, first = 0) {
if (!*top)
continue;

bn = be64_to_cpu(*top);

error = recursive_scan(ip, dibh, mp, height + 1, bn,
first, bc, data);
if (error)
break;
}

out:
brelse(bh);
return error;
}

/**
* do_strip - Look for a layer a particular layer of the file and strip it off
* @ip: the inode
Expand All @@ -752,9 +677,8 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,

static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
struct buffer_head *bh, __be64 *top, __be64 *bottom,
unsigned int height, void *data)
unsigned int height, struct strip_mine *sm)
{
struct strip_mine *sm = data;
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrp_list rlist;
u64 bn, bstart;
Expand Down Expand Up @@ -885,6 +809,75 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
return error;
}

/**
* recursive_scan - recursively scan through the end of a file
* @ip: the inode
* @dibh: the dinode buffer
* @mp: the path through the metadata to the point to start
* @height: the height the recursion is at
* @block: the indirect block to look at
* @first: 1 if this is the first block
* @sm: data opaque to this function to pass to @bc
*
* When this is first called @height and @block should be zero and
* @first should be 1.
*
* Returns: errno
*/

static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
struct metapath *mp, unsigned int height,
u64 block, int first, struct strip_mine *sm)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *bh = NULL;
__be64 *top, *bottom;
u64 bn;
int error;
int mh_size = sizeof(struct gfs2_meta_header);

if (!height) {
error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
return error;
dibh = bh;

top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0];
bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs;
} else {
error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh);
if (error)
return error;

top = (__be64 *)(bh->b_data + mh_size) +
(first ? mp->mp_list[height] : 0);

bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs;
}

error = do_strip(ip, dibh, bh, top, bottom, height, sm);
if (error)
goto out;

if (height < ip->i_height - 1)
for (; top < bottom; top++, first = 0) {
if (!*top)
continue;

bn = be64_to_cpu(*top);

error = recursive_scan(ip, dibh, mp, height + 1, bn,
first, sm);
if (error)
break;
}

out:
brelse(bh);
return error;
}


/**
* gfs2_block_truncate_page - Deal with zeroing out data for truncate
*
Expand Down Expand Up @@ -1024,7 +1017,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
sm.sm_first = !!size;
sm.sm_height = height;

error = recursive_scan(ip, NULL, &mp, 0, 0, 1, do_strip, &sm);
error = recursive_scan(ip, NULL, &mp, 0, 0, 1, &sm);
if (error)
break;
}
Expand Down

0 comments on commit b635d17

Please sign in to comment.