* [Cluster-devel] [GFS2] More cleanup/bug fixes
@ 2008-02-12 15:33 swhiteho
2008-02-12 15:33 ` [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent swhiteho
0 siblings, 1 reply; 5+ messages in thread
From: swhiteho @ 2008-02-12 15:33 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
This set has a few more cleanups and bug fixes relating to my current
project of updating the block map code. There will be more to follow
in a few days,
Steve.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent
2008-02-12 15:33 [Cluster-devel] [GFS2] More cleanup/bug fixes swhiteho
@ 2008-02-12 15:33 ` swhiteho
2008-02-12 15:33 ` [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode swhiteho
0 siblings, 1 reply; 5+ messages in thread
From: swhiteho @ 2008-02-12 15:33 UTC (permalink / raw)
To: cluster-devel.redhat.com
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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode
2008-02-12 15:33 ` [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent swhiteho
@ 2008-02-12 15:33 ` swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call swhiteho
0 siblings, 1 reply; 5+ messages in thread
From: swhiteho @ 2008-02-12 15:33 UTC (permalink / raw)
To: cluster-devel.redhat.com
From: Steven Whitehouse <swhiteho@redhat.com>
The blocks counter is almost a duplicate of the i_blocks
field in the VFS inode. The only difference is that i_blocks
can be only 32bits long for 32bit arch without large single file
support. Since GFS2 doesn't handle the non-large single file
case (for 32 bit anyway) this adds a new config dependency on
64BIT || LSF. This has always been the case, however we've never
explicitly said so before.
Even if we do add support for the non-LSF case, we will still
not require this field to be duplicated since we will not be
able to access oversized files anyway.
So the net result of all this is that we shave 8 bytes from a gfs2_inode
and get our config deps correct.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index de8e64c..d147b53 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -1,6 +1,6 @@
config GFS2_FS
tristate "GFS2 file system support"
- depends on EXPERIMENTAL
+ depends on EXPERIMENTAL && (64BIT || LSF)
select FS_POSIX_ACL
select CRC32
help
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 6780aa5..e27e660 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -161,9 +161,8 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
if (ip->i_di.di_size) {
*(__be64 *)(di + 1) = cpu_to_be64(block);
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
- di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
+ di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
}
ip->i_height = 1;
@@ -238,10 +237,9 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
*(__be64 *)(di + 1) = cpu_to_be64(bn);
ip->i_height += new_height;
- ip->i_di.di_blocks += new_height;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, new_height);
di->di_height = cpu_to_be16(ip->i_height);
- di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
+ di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
brelse(dibh);
return error;
}
@@ -380,8 +378,7 @@ static int lookup_block(struct gfs2_inode *ip, unsigned int height,
gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[height], 1);
*ptr = cpu_to_be64(*block);
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
*new = 1;
return 0;
@@ -779,10 +776,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
}
*p = 0;
- if (!ip->i_di.di_blocks)
- gfs2_consist_inode(ip);
- ip->i_di.di_blocks--;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, -1);
}
if (bstart) {
if (metadata)
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 93a2e6a..862aa32 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -906,8 +906,7 @@ static int dir_make_exhash(struct inode *inode)
*lp = cpu_to_be64(bn);
dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2;
- dip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&dip->i_inode);
+ gfs2_add_inode_blocks(&dip->i_inode, 1);
dip->i_di.di_flags |= GFS2_DIF_EXHASH;
for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
@@ -1045,8 +1044,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
error = gfs2_meta_inode_buffer(dip, &dibh);
if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
gfs2_trans_add_bh(dip->i_gl, dibh, 1);
- dip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&dip->i_inode);
+ gfs2_add_inode_blocks(&dip->i_inode, 1);
gfs2_dinode_out(dip, dibh->b_data);
brelse(dibh);
}
@@ -1580,8 +1578,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
if (error)
return error;
gfs2_trans_add_bh(ip->i_gl, bh, 1);
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
gfs2_dinode_out(ip, bh->b_data);
brelse(bh);
return 0;
@@ -1922,11 +1919,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
brelse(bh);
gfs2_free_meta(dip, blk, 1);
-
- if (!dip->i_di.di_blocks)
- gfs2_consist_inode(dip);
- dip->i_di.di_blocks--;
- gfs2_set_inode_blocks(&dip->i_inode);
+ gfs2_add_inode_blocks(&dip->i_inode, -1);
}
error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index 0e79cd5..76ead1a 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -277,10 +277,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
}
*dataptrs = 0;
- if (!ip->i_di.di_blocks)
- gfs2_consist_inode(ip);
- ip->i_di.di_blocks--;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, -1);
}
if (bstart)
gfs2_free_meta(ip, bstart, blen);
@@ -598,8 +595,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
ea->ea_flags = GFS2_EAFLAG_LAST;
ea->ea_num_ptrs = 0;
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
return 0;
}
@@ -651,8 +647,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
gfs2_trans_add_bh(ip->i_gl, bh, 1);
gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
data_len;
@@ -980,8 +975,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
*eablk = cpu_to_be64(ip->i_di.di_eattr);
ip->i_di.di_eattr = blk;
ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT;
- ip->i_di.di_blocks++;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, 1);
eablk++;
}
@@ -1389,10 +1383,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
}
*eablk = 0;
- if (!ip->i_di.di_blocks)
- gfs2_consist_inode(ip);
- ip->i_di.di_blocks--;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, -1);
}
if (bstart)
gfs2_free_meta(ip, bstart, blen);
@@ -1444,10 +1435,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
gfs2_free_meta(ip, ip->i_di.di_eattr, 1);
ip->i_di.di_eattr = 0;
- if (!ip->i_di.di_blocks)
- gfs2_consist_inode(ip);
- ip->i_di.di_blocks--;
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_add_inode_blocks(&ip->i_inode, -1);
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 898b456..4ba2ea6 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -239,7 +239,6 @@ enum {
struct gfs2_dinode_host {
u64 di_size; /* number of bytes in file */
- u64 di_blocks; /* number of blocks in file */
u64 di_generation; /* generation number for NFS */
u32 di_flags; /* GFS2_DIF_... */
/* These only apply to directories */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index c3fe8aa..5f50dd5 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -273,8 +273,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink);
di->di_size = be64_to_cpu(str->di_size);
i_size_write(&ip->i_inode, di->di_size);
- di->di_blocks = be64_to_cpu(str->di_blocks);
- gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
@@ -344,7 +343,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip)
struct gfs2_rgrpd *rgd;
int error;
- if (ip->i_di.di_blocks != 1) {
+ if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
if (gfs2_consist_inode(ip))
gfs2_dinode_print(ip);
return -EIO;
@@ -1398,7 +1397,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
str->di_size = cpu_to_be64(di->di_size);
- str->di_blocks = cpu_to_be64(di->di_blocks);
+ str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
@@ -1430,8 +1429,8 @@ void gfs2_dinode_print(const struct gfs2_inode *ip)
printk(KERN_INFO " no_addr = %llu\n",
(unsigned long long)ip->i_no_addr);
printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size);
- printk(KERN_INFO " di_blocks = %llu\n",
- (unsigned long long)di->di_blocks);
+ printk(KERN_INFO " blocks = %llu\n",
+ (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode));
printk(KERN_INFO " i_goal = %llu\n",
(unsigned long long)ip->i_goal);
printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags);
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index db73868..580da45 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -10,6 +10,8 @@
#ifndef __INODE_DOT_H__
#define __INODE_DOT_H__
+#include "util.h"
+
static inline int gfs2_is_stuffed(const struct gfs2_inode *ip)
{
return !ip->i_height;
@@ -37,13 +39,25 @@ static inline int gfs2_is_dir(const struct gfs2_inode *ip)
return S_ISDIR(ip->i_inode.i_mode);
}
-static inline void gfs2_set_inode_blocks(struct inode *inode)
+static inline void gfs2_set_inode_blocks(struct inode *inode, u64 blocks)
+{
+ inode->i_blocks = blocks <<
+ (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
+}
+
+static inline u64 gfs2_get_inode_blocks(const struct inode *inode)
{
- struct gfs2_inode *ip = GFS2_I(inode);
- inode->i_blocks = ip->i_di.di_blocks <<
+ return inode->i_blocks >>
(GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
}
+static inline void gfs2_add_inode_blocks(struct inode *inode, s64 change)
+{
+ gfs2_assert(GFS2_SB(inode), (change >= 0 || inode->i_blocks > -change));
+ change *= (GFS2_SB(inode)->sd_sb.sb_bsize/GFS2_BASIC_BLOCK);
+ inode->i_blocks += change;
+}
+
static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr,
u64 no_formal_ino)
{
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index e874129..301c945 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -981,8 +981,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
brelse(dibh);
if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
- gfs2_quota_change(ip, -ip->i_di.di_blocks, ouid, ogid);
- gfs2_quota_change(ip, ip->i_di.di_blocks, nuid, ngid);
+ u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
+ gfs2_quota_change(ip, -blocks, ouid, ogid);
+ gfs2_quota_change(ip, blocks, nuid, ngid);
}
out_end_trans:
--
1.5.1.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call
2008-02-12 15:33 ` [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode swhiteho
@ 2008-02-12 15:34 ` swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 4/4] [GFS2] Fix bug where we called drop_bh incorrectly swhiteho
0 siblings, 1 reply; 5+ messages in thread
From: swhiteho @ 2008-02-12 15:34 UTC (permalink / raw)
To: cluster-devel.redhat.com
From: Steven Whitehouse <swhiteho@redhat.com>
In the case that we needed to grow the height of the metadata tree
we were looking up the inode buffer and then brelse()ing it despite
the fact that it is needed later in the block map process.
This patch ensures that we look up the inode's buffer once and only
once during the block map process.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index e27e660..f1f38ca 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -188,50 +188,45 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
{
struct gfs2_inode *ip = GFS2_I(inode);
unsigned new_height = height - ip->i_height;
- struct buffer_head *dibh;
+ struct buffer_head *dibh = mp->mp_bh[0];
struct gfs2_dinode *di;
- int error;
__be64 *bp;
u64 bn;
unsigned n, i = 0;
- if (height <= ip->i_height)
- return 0;
-
- error = gfs2_meta_inode_buffer(ip, &dibh);
- if (error)
- return error;
+ BUG_ON(height <= ip->i_height);
do {
n = new_height - i;
bn = gfs2_alloc_block(ip, &n);
gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, n);
do {
- mp->mp_bh[i] = gfs2_meta_new(ip->i_gl, bn++);
- gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i], 1);
+ mp->mp_bh[i + 1] = gfs2_meta_new(ip->i_gl, bn++);
+ gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i + 1], 1);
i++;
} while(i < n);
} while(i < new_height);
n = 0;
- bn = mp->mp_bh[0]->b_blocknr;
+ bn = mp->mp_bh[1]->b_blocknr;
if (new_height > 1) {
for(; n < new_height-1; n++) {
- gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN,
+ gfs2_metatype_set(mp->mp_bh[n + 1], GFS2_METATYPE_IN,
GFS2_FORMAT_IN);
- gfs2_buffer_clear_tail(mp->mp_bh[n],
+ gfs2_buffer_clear_tail(mp->mp_bh[n + 1],
sizeof(struct gfs2_meta_header));
- bp = (__be64 *)(mp->mp_bh[n]->b_data +
+ bp = (__be64 *)(mp->mp_bh[n + 1]->b_data +
sizeof(struct gfs2_meta_header));
- *bp = cpu_to_be64(mp->mp_bh[n+1]->b_blocknr);
- brelse(mp->mp_bh[n]);
- mp->mp_bh[n] = NULL;
+ *bp = cpu_to_be64(mp->mp_bh[n+2]->b_blocknr);
+ brelse(mp->mp_bh[n+1]);
+ mp->mp_bh[n+1] = NULL;
}
}
- gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
- gfs2_buffer_copy_tail(mp->mp_bh[n], sizeof(struct gfs2_meta_header),
+ gfs2_metatype_set(mp->mp_bh[n+1], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
+ gfs2_buffer_copy_tail(mp->mp_bh[n+1], sizeof(struct gfs2_meta_header),
dibh, sizeof(struct gfs2_dinode));
- brelse(mp->mp_bh[n]);
+ brelse(mp->mp_bh[n+1]);
+ mp->mp_bh[n+1] = NULL;
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
di = (struct gfs2_dinode *)dibh->b_data;
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
@@ -240,8 +235,7 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
gfs2_add_inode_blocks(&ip->i_inode, new_height);
di->di_height = cpu_to_be16(ip->i_height);
di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
- brelse(dibh);
- return error;
+ return 0;
}
/**
@@ -391,11 +385,7 @@ static int lookup_metapath(struct inode *inode, struct metapath *mp,
struct gfs2_inode *ip = GFS2_I(inode);
unsigned int end_of_metadata = ip->i_height - 1;
unsigned int x;
- int ret = gfs2_meta_inode_buffer(ip, &bh);
- if (ret)
- return ret;
-
- mp->mp_bh[0] = bh;
+ int ret;
for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, x, mp, create, new, dblock);
@@ -515,6 +505,10 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
}
size = (lblock + 1) * bsize;
+ error = gfs2_meta_inode_buffer(ip, &mp.mp_bh[0]);
+ if (error)
+ goto out_fail;
+
if (size > arr[ip->i_height]) {
u8 height = ip->i_height;
if (!create)
--
1.5.1.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 4/4] [GFS2] Fix bug where we called drop_bh incorrectly
2008-02-12 15:34 ` [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call swhiteho
@ 2008-02-12 15:34 ` swhiteho
0 siblings, 0 replies; 5+ messages in thread
From: swhiteho @ 2008-02-12 15:34 UTC (permalink / raw)
To: cluster-devel.redhat.com
From: Steven Whitehouse <swhiteho@redhat.com>
As a result of an earlier patch, drop_bh was being called in cases
when it shouldn't have been. Since we never have a gh in the drop
case and we always have a gh in the promote case, we can use that
extra information to tell which case has been seen.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Bob Peterson <rpeterso@redhat.com>
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index d00dc37..63981e2 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -765,7 +765,6 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
{
struct gfs2_sbd *sdp = gl->gl_sbd;
const struct gfs2_glock_operations *glops = gl->gl_ops;
- struct gfs2_holder *gh = gl->gl_req_gh;
gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -776,23 +775,11 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);
- if (gh) {
- spin_lock(&gl->gl_spin);
- list_del_init(&gh->gh_list);
- gh->gh_error = 0;
- spin_unlock(&gl->gl_spin);
- }
-
spin_lock(&gl->gl_spin);
gfs2_demote_wake(gl);
- gl->gl_req_gh = NULL;
clear_bit(GLF_LOCK, &gl->gl_flags);
spin_unlock(&gl->gl_spin);
-
gfs2_glock_put(gl);
-
- if (gh)
- gfs2_holder_wake(gh);
}
/**
@@ -810,7 +797,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
int prev_state = gl->gl_state;
int op_done = 1;
- if ((ret & LM_OUT_ST_MASK) == LM_ST_UNLOCKED) {
+ if (!gh && (ret & LM_OUT_ST_MASK) == LM_ST_UNLOCKED) {
drop_bh(gl, ret);
return;
}
--
1.5.1.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-02-12 15:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-12 15:33 [Cluster-devel] [GFS2] More cleanup/bug fixes swhiteho
2008-02-12 15:33 ` [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent swhiteho
2008-02-12 15:33 ` [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 4/4] [GFS2] Fix bug where we called drop_bh incorrectly swhiteho
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).