Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38684
b: refs/heads/master
c: fd88de5
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed May 5, 2006
1 parent d183ef4 commit 266fc5f
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 130 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: 5bb76af1e089ac186c15c6aa792340d22b63d4b4
refs/heads/master: fd88de569b802c4a04aaa6ee74667775f4aed8c6
170 changes: 108 additions & 62 deletions trunk/fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,17 @@ static void find_metapath(struct gfs2_inode *ip, uint64_t block,
* metadata tree.
*/

static inline uint64_t *metapointer(struct buffer_head *bh,
unsigned int height, struct metapath *mp)
static inline u64 *metapointer(struct buffer_head *bh, int *boundary,
unsigned int height, const struct metapath *mp)
{
unsigned int head_size = (height > 0) ?
sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode);

return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height];
u64 *ptr;
*boundary = 0;
ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height];
if (ptr + 1 == (u64*)(bh->b_data + bh->b_size))
*boundary = 1;
return ptr;
}

/**
Expand All @@ -339,24 +343,24 @@ static inline uint64_t *metapointer(struct buffer_head *bh,
*
*/

static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
unsigned int height, struct metapath *mp, int create,
int *new, uint64_t *block)
static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
unsigned int height, struct metapath *mp, int create,
int *new, uint64_t *block)
{
uint64_t *ptr = metapointer(bh, height, mp);
int boundary;
uint64_t *ptr = metapointer(bh, &boundary, height, mp);

if (*ptr) {
*block = be64_to_cpu(*ptr);
return;
return boundary;
}

*block = 0;

if (!create)
return;
return 0;

if (height == ip->i_di.di_height - 1 &&
!gfs2_is_dir(ip))
if (height == ip->i_di.di_height - 1 && !gfs2_is_dir(ip))
*block = gfs2_alloc_data(ip);
else
*block = gfs2_alloc_meta(ip);
Expand All @@ -367,28 +371,31 @@ static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
ip->i_di.di_blocks++;

*new = 1;
return 0;
}

/**
* gfs2_block_map - Map a block from an inode to a disk block
* @ip: The GFS2 inode
* gfs2_block_pointers - Map a block from an inode to a disk block
* @inode: The inode
* @lblock: The logical block number
* @new: Value/Result argument (1 = may create/did create new blocks)
* @dblock: the disk block number of the start of an extent
* @extlen: the size of the extent
* @boundary: gets set if we've hit a block boundary
* @mp: metapath to use
*
* Find the block number on the current device which corresponds to an
* inode's block. If the block had to be created, "new" will be set.
*
* Returns: errno
*/

int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
uint64_t *dblock, uint32_t *extlen)
static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
int *new, u64 *dblock,
int *boundary,
struct metapath *mp)
{
struct gfs2_inode *ip = inode->u.generic_ip;
struct gfs2_sbd *sdp = ip->i_sbd;
struct buffer_head *bh;
struct metapath mp;
int create = *new;
unsigned int bsize;
unsigned int height;
Expand All @@ -398,13 +405,6 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,

*new = 0;
*dblock = 0;
if (extlen)
*extlen = 0;

if (create)
down_write(&ip->i_rw_mutex);
else
down_read(&ip->i_rw_mutex);

if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
goto out;
Expand All @@ -421,15 +421,15 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
goto out;
}

find_metapath(ip, lblock, &mp);
find_metapath(ip, lblock, mp);
end_of_metadata = ip->i_di.di_height - 1;

error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
goto out;

for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, bh, x, &mp, create, new, dblock);
lookup_block(ip, bh, x, mp, create, new, dblock);
brelse(bh);
if (!*dblock)
goto out;
Expand All @@ -439,49 +439,95 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
goto out;
}

lookup_block(ip, bh, end_of_metadata, &mp, create, new, dblock);

if (extlen && *dblock) {
*extlen = 1;

if (!*new) {
uint64_t tmp_dblock;
int tmp_new;
unsigned int nptrs;

nptrs = (end_of_metadata) ? sdp->sd_inptrs :
sdp->sd_diptrs;

while (++mp.mp_list[end_of_metadata] < nptrs) {
lookup_block(ip, bh, end_of_metadata, &mp,
0, &tmp_new, &tmp_dblock);

if (*dblock + *extlen != tmp_dblock)
break;

(*extlen)++;
}
}
}

brelse(bh);

*boundary = lookup_block(ip, bh, end_of_metadata, mp, create, new, dblock);
if (*new) {
error = gfs2_meta_inode_buffer(ip, &bh);
struct buffer_head *dibh;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_trans_add_bh(ip->i_gl, bh, 1);
gfs2_dinode_out(&ip->i_di, bh->b_data);
brelse(bh);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
}
}
return bh;
out:
return ERR_PTR(error);
}

out:

static inline void bmap_lock(struct inode *inode, int create)
{
struct gfs2_inode *ip = inode->u.generic_ip;
if (create)
down_write(&ip->i_rw_mutex);
else
down_read(&ip->i_rw_mutex);
}

static inline void bmap_unlock(struct inode *inode, int create)
{
struct gfs2_inode *ip = inode->u.generic_ip;
if (create)
up_write(&ip->i_rw_mutex);
else
up_read(&ip->i_rw_mutex);
}

return error;
int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary)
{
struct metapath mp;
struct buffer_head *bh;
int create = *new;

bmap_lock(inode, create);
bh = gfs2_block_pointers(inode, lblock, new, dblock, boundary, &mp);
bmap_unlock(inode, create);
if (!bh)
return 0;
if (IS_ERR(bh))
return PTR_ERR(bh);
brelse(bh);
return 0;
}

int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
{
struct gfs2_inode *ip = inode->u.generic_ip;
struct gfs2_sbd *sdp = ip->i_sbd;
struct metapath mp;
struct buffer_head *bh;
int boundary;
int create = *new;

BUG_ON(!extlen);
BUG_ON(!dblock);
BUG_ON(!new);

bmap_lock(inode, create);
bh = gfs2_block_pointers(inode, lblock, new, dblock, &boundary, &mp);
*extlen = 1;

if (bh && !IS_ERR(bh) && *dblock && !*new) {
u64 tmp_dblock;
int tmp_new;
unsigned int nptrs;
unsigned end_of_metadata = ip->i_di.di_height - 1;

nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs;
while (++mp.mp_list[end_of_metadata] < nptrs) {
lookup_block(ip, bh, end_of_metadata, &mp, 0, &tmp_new, &tmp_dblock);
if (*dblock + *extlen != tmp_dblock)
break;
(*extlen)++;
}
}
bmap_unlock(inode, create);
if (!bh)
return 0;
if (IS_ERR(bh))
return PTR_ERR(bh);
brelse(bh);
return 0;
}

/**
Expand Down Expand Up @@ -1053,7 +1099,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
}

for (; lblock < lblock_stop; lblock += extlen) {
error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen);
error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
if (error)
return error;

Expand Down
5 changes: 2 additions & 3 deletions trunk/fs/gfs2/bmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ typedef int (*gfs2_unstuffer_t) (struct gfs2_inode * ip,
int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
void *private);

int gfs2_block_map(struct gfs2_inode *ip,
uint64_t lblock, int *new,
uint64_t *dblock, uint32_t *extlen);
int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary);
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);

int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size);
int gfs2_truncatei_resume(struct gfs2_inode *ip);
Expand Down
8 changes: 4 additions & 4 deletions trunk/fs/gfs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,

if (!extlen) {
new = 1;
error = gfs2_block_map(ip, lblock, &new, &dblock,
&extlen);
error = gfs2_extent_map(ip->i_vnode, lblock, &new,
&dblock, &extlen);
if (error)
goto fail;
error = -EIO;
Expand Down Expand Up @@ -314,8 +314,8 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,

if (!extlen) {
new = 0;
error = gfs2_block_map(ip, lblock, &new, &dblock,
&extlen);
error = gfs2_extent_map(ip->i_vnode, lblock, &new,
&dblock, &extlen);
if (error)
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2125,7 +2125,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
mutex_lock(&sdp->sd_invalidate_inodes_mutex);
invalidate_inodes(sdp->sd_vfs);
mutex_unlock(&sdp->sd_invalidate_inodes_mutex);
yield();
msleep(10);
}
}

Expand Down
5 changes: 2 additions & 3 deletions trunk/fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1606,9 +1606,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
curtime = get_seconds();
if (curtime - ip->i_di.di_atime >= quantum) {
gfs2_glock_dq(gh);
gfs2_holder_reinit(LM_ST_EXCLUSIVE,
gh->gh_flags & ~LM_FLAG_ANY,
gh);
gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
gh);
error = gfs2_glock_nq(gh);
if (error)
return error;
Expand Down
4 changes: 2 additions & 2 deletions trunk/fs/gfs2/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
int new = 0;
uint64_t dbn;
int error;
int bdy;

error = gfs2_block_map(sdp->sd_jdesc->jd_inode->u.generic_ip,
lbn, &new, &dbn, NULL);
error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
gfs2_assert_withdraw(sdp, !error && dbn);

return dbn;
Expand Down
Loading

0 comments on commit 266fc5f

Please sign in to comment.