mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
gfs2: Add a next-resource-group pointer to resource groups
Add a new rg_skip field to struct gfs2_rgrp, replacing __pad. The rg_skip field has the following meaning: - If rg_skip is zero, it is considered unset and not useful. - If rg_skip is non-zero, its value will be the number of blocks between this rgrp's address and the next rgrp's address. This can be used as a hint by fsck.gfs2 when rebuilding a bad rindex, for example. This will provide less dependency on the rindex in future, and allow tools such as fsck.gfs2 to iterate the resource groups without keeping the rindex around. The field is updated in gfs2_rgrp_out() so that existing file systems will have it set. This means that any resource groups that aren't ever written will not be updated. The final rgrp is a special case as there is no next rgrp, so it will always have a rg_skip of 0 (unless the fs is extended). Before this patch, gfs2_rgrp_out() zeroes the __pad field explicitly, so the rg_skip field can get set back to 0 in cases where nodes with and without this patch are mixed in a cluster. In some cases, the field may bounce between being set by one node and then zeroed by another which may harm performance slightly, e.g. when two nodes create many small files. In testing this situation is rare but it becomes more likely as the filesystem fills up and there are fewer resource groups to choose from. The problem goes away when all nodes are running with this patch. Dipping into the space currently occupied by the rg_reserved field would have resulted in the same problem as it is also explicitly zeroed, so unfortunately there is no other way around it. Signed-off-by: Andrew Price <anprice@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
parent
9aa0159327
commit
65adc27375
@ -1044,12 +1044,16 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf)
|
||||
|
||||
static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
|
||||
{
|
||||
struct gfs2_rgrpd *next = gfs2_rgrpd_get_next(rgd);
|
||||
struct gfs2_rgrp *str = buf;
|
||||
|
||||
str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK);
|
||||
str->rg_free = cpu_to_be32(rgd->rd_free);
|
||||
str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes);
|
||||
str->__pad = cpu_to_be32(0);
|
||||
if (next == NULL)
|
||||
str->rg_skip = 0;
|
||||
else if (next->rd_addr > rgd->rd_addr)
|
||||
str->rg_skip = cpu_to_be32(next->rd_addr - rgd->rd_addr);
|
||||
str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration);
|
||||
memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
|
||||
}
|
||||
|
@ -187,7 +187,10 @@ struct gfs2_rgrp {
|
||||
__be32 rg_flags;
|
||||
__be32 rg_free;
|
||||
__be32 rg_dinodes;
|
||||
__be32 __pad;
|
||||
union {
|
||||
__be32 __pad;
|
||||
__be32 rg_skip; /* Distance to the next rgrp in fs blocks */
|
||||
};
|
||||
__be64 rg_igeneration;
|
||||
|
||||
__u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
|
||||
|
Loading…
Reference in New Issue
Block a user