Commit 12bac708 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
  GFS2: Ensure that the inode goal block settings are updated
  GFS2: Fix bug in block allocation
  bitops: Add __ffs64 bitop
parents 60911731 d9ba7615
...@@ -212,8 +212,7 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len, ...@@ -212,8 +212,7 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,
if (tmp == 0) if (tmp == 0)
return BFITNOENT; return BFITNOENT;
ptr--; ptr--;
bit = fls64(tmp); bit = __ffs64(tmp);
bit--; /* fls64 always adds one to the bit count */
bit /= 2; /* two bits per entry in the bitmap */ bit /= 2; /* two bits per entry in the bitmap */
return (((const unsigned char *)ptr - buf) * GFS2_NBBY) + bit; return (((const unsigned char *)ptr - buf) * GFS2_NBBY) + bit;
} }
...@@ -1445,10 +1444,12 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, ...@@ -1445,10 +1444,12 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
struct gfs2_alloc *al = ip->i_alloc; struct gfs2_alloc *al = ip->i_alloc;
struct gfs2_rgrpd *rgd = al->al_rgd; struct gfs2_rgrpd *rgd = al->al_rgd;
u32 goal, blk; u32 goal, blk;
u64 block; u64 block;
int error;
if (rgrp_contains_block(rgd, ip->i_goal)) if (rgrp_contains_block(rgd, ip->i_goal))
goal = ip->i_goal - rgd->rd_data0; goal = ip->i_goal - rgd->rd_data0;
...@@ -1461,7 +1462,13 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) ...@@ -1461,7 +1462,13 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
rgd->rd_last_alloc = blk; rgd->rd_last_alloc = blk;
block = rgd->rd_data0 + blk; block = rgd->rd_data0 + blk;
ip->i_goal = block; ip->i_goal = block;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error == 0) {
struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal);
brelse(dibh);
}
gfs2_assert_withdraw(sdp, rgd->rd_free >= *n); gfs2_assert_withdraw(sdp, rgd->rd_free >= *n);
rgd->rd_free -= *n; rgd->rd_free -= *n;
......
...@@ -112,6 +112,25 @@ static inline unsigned fls_long(unsigned long l) ...@@ -112,6 +112,25 @@ static inline unsigned fls_long(unsigned long l)
return fls64(l); return fls64(l);
} }
/**
* __ffs64 - find first set bit in a 64 bit word
* @word: The 64 bit word
*
* On 64 bit arches this is a synomyn for __ffs
* The result is not defined if no bits are set, so check that @word
* is non-zero before calling this.
*/
static inline unsigned long __ffs64(u64 word)
{
#if BITS_PER_LONG == 32
if (((u32)word) == 0UL)
return __ffs((u32)(word >> 32)) + 32;
#elif BITS_PER_LONG != 64
#error BITS_PER_LONG not 32 or 64
#endif
return __ffs((unsigned long)word);
}
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifdef CONFIG_GENERIC_FIND_FIRST_BIT #ifdef CONFIG_GENERIC_FIND_FIRST_BIT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment