cluster: RHEL59 - gfs2_convert: mask out proper bits when identifying symlinks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=7c1eff97fde...
Commit: 7c1eff97fde6b899904a97e366380a470c3f50a3
Parent: 07b91f6a29c3340f42c1d3bd5d759c55f17298f2
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Dec 19 07:47:15 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:58 2013 -0500
gfs2_convert: mask out proper bits when identifying symlinks
This patch masks out the proper file type bit in order to
distinguish files from symlinks. Include stat.h defines:
So the check for "di_mode & S_IFLNK" will match regular files,
not just symlinks. The problem was that gfs2_convert was matching
regular files and treating them as symlinks, which destroyed
the di_blocks field in the dinode. The patch also has some minor
cleanups.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 13 ++++++-------
1 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 206adfb..7ba30e9 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -826,7 +826,6 @@ static int has_cdpn(const char *str)
static int fix_cdpn_symlink(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh, struct gfs2_inode *ip)
{
- int ret = 0;
char *linkptr = NULL;
if (ip->i_di.di_height != 0)
@@ -847,7 +846,7 @@ static int fix_cdpn_symlink(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh, s
(osi_list_t *)&cdpns_to_fix);
}
- return ret;
+ return 0;
}
/*
@@ -862,7 +861,7 @@ static int fix_cdpn_symlink(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh, s
*/
static int fix_xattr(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh, struct gfs2_inode *ip)
{
- int ret = 0, len, old_hdr_sz, new_hdr_sz;
+ int len, old_hdr_sz, new_hdr_sz;
struct gfs2_buffer_head *eabh;
char *buf;
@@ -885,7 +884,7 @@ static int fix_xattr(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh, struct g
}
brelse(eabh);
- return ret;
+ return 0;
}
/* ------------------------------------------------------------------------- */
@@ -904,8 +903,8 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode_was_gfs1 = (inode->i_di.di_num.no_formal_ino ==
inode->i_di.di_num.no_addr);
/* Fix the inode number: */
- inode->i_di.di_num.no_formal_ino = sbp->md.next_inum; ;
-
+ inode->i_di.di_num.no_formal_ino = sbp->md.next_inum;
+
/* Fix the inode type: gfs1 uses di_type, gfs2 uses di_mode. */
inode->i_di.di_mode &= ~S_IFMT;
switch (inode->i_di.__pad1) { /* formerly di_type */
@@ -971,7 +970,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
if (adjust_indirect_blocks(sbp, inode))
return -1;
/* Check for cdpns */
- if (inode->i_di.di_mode & S_IFLNK) {
+ if (S_ISLNK(inode->i_di.di_mode)) {
ret = fix_cdpn_symlink(sbp, bh, inode);
if (ret)
return -1;
10 years, 11 months
cluster: RHEL59 - gfs2_convert: clear out old di_mode before setting it
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=07b91f6a29c...
Commit: 07b91f6a29c3340f42c1d3bd5d759c55f17298f2
Parent: 6bd4127590889ecfb8c27da15f633dfbb688be3f
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Dec 18 14:14:08 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:51 2013 -0500
gfs2_convert: clear out old di_mode before setting it
This patch clears the dinode 'di_mode' inode type field before
setting it based on the GFS1 value. In rare circumstances
(e.g. fsck.gfs2 ran on a GFS1 file system and created lost+found
with both GFS1 and GFS2 data) di_mode might have an old value.
In these cases, simply doing a logical 'or' with the correct
value produces an invalid value. Zeroing it out beforehand ensures
it is set correctly based on the GFS1 type.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 074d1ee..206adfb 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -907,6 +907,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_num.no_formal_ino = sbp->md.next_inum; ;
/* Fix the inode type: gfs1 uses di_type, gfs2 uses di_mode. */
+ inode->i_di.di_mode &= ~S_IFMT;
switch (inode->i_di.__pad1) { /* formerly di_type */
case GFS_FILE_DIR: /* directory */
inode->i_di.di_mode |= S_IFDIR;
10 years, 11 months
cluster: RHEL59 - gfs2_convert: calculate height 1 for small files that were once big
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=6bd41275908...
Commit: 6bd4127590889ecfb8c27da15f633dfbb688be3f
Parent: 1b9e718d34f4ff29b41606d26e37e3a6e1fd59b6
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Dec 17 15:11:34 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:43 2013 -0500
gfs2_convert: calculate height 1 for small files that were once big
This patch changes function calc_gfs2_tree_height so that it gives
a height of 1 to small files that once were big. The problems here
is with files that were once big (needed two levels of indirection
(height 2)) and then are truncated to a tiny non-zero size
(ordinarily, they would be stuffed, but due to the growth followed
by truncate, they're still at height 2). The required GFS2 height is
zero, whereas the GFS1 height is 2. After the conversion the file
will not really be stuffed, because function fix_metatree will
unstuff the dinode as part of its conversion. So at least it will
be at height 1. The problem is that if we don't fix the 0 height to
its proper value of 1, fix_ind_reg_or_dir gets called with gfs2_hgt=0,
which then calls mp_gfs1_to_gfs2, which then tries to set:
gfs2factor[gfs2_h - 1] = 1ull. This results in a negative index of the
array.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index fa0d230..074d1ee 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -266,6 +266,12 @@ static unsigned int calc_gfs2_tree_height(struct gfs2_inode *ip, uint64_t size)
for (height = 0; height < max; height++)
if (arr[height] >= size)
break;
+ /* If calc_gfs2_tree_height was called, the dinode is not stuffed or
+ we would have returned before this point. After the call, a call is
+ made to fix_metatree, which unstuffs the dinode. Therefore, the
+ smallest height that can result after this call is 1. */
+ if (!height)
+ height = 1;
return height;
}
10 years, 11 months
cluster: RHEL59 - gfs2_convert: Use proper header size when reordering meta pointers
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1b9e718d34f...
Commit: 1b9e718d34f4ff29b41606d26e37e3a6e1fd59b6
Parent: 2d7737fad8a178153d0b8495ac4ebe995a6d5a32
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Dec 17 15:01:02 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:36 2013 -0500
gfs2_convert: Use proper header size when reordering meta pointers
This patch changes function fix_metatree to use a proper metadata
header size. Before, it was using sizeof(struct gfs2_meta_header).
That's correct in almost all cases. But if you make a big file,
such that it goes into height==2 (two levels of indirection), then
truncate the file back to where it only would normally only need
height==1, then run gfs2_convert, it gets into trouble. That's
because you have a small file size, which calculates a much smaller
number of GFS2 pointers needed, due to the truncation. Function
fix_metatree will ensure at least one level of indirection by
unstuffing the converted dinode, but we need to start pushing out
the pointers onto the dinode's buffer, and for that, we need to
calculate the right header size.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index b0d7af0..fa0d230 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -350,7 +350,8 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip,
gfs2_meta_header_out(&mh, bh);
}
- hdrsize = sizeof(struct gfs2_meta_header);
+ hdrsize = blk->height ? sizeof(struct gfs2_meta_header) :
+ sizeof(struct gfs2_dinode);
if (amount > sbp->bsize - hdrsize - ptramt)
amount = sbp->bsize - hdrsize - ptramt;
10 years, 11 months
cluster: RHEL59 - gfs2_convert: remember number of blocks when converting quotas
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=2d7737fad8a...
Commit: 2d7737fad8a178153d0b8495ac4ebe995a6d5a32
Parent: e74cc1bf79a4826b70cd058a5128c8ba9d17b1a6
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Dec 17 14:56:16 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:27 2013 -0500
gfs2_convert: remember number of blocks when converting quotas
This patch changes function copy_quotas so that it properly copies
the di_blocks field from the GFS1 quotas file to its new GFS2 file.
If the quota file had a non-trivial size, gfs2_convert was copying
all the data and pointers, but not properly setting the di_blocks.
This ordinarily isn't tragic because the file is never deleted, but
it did flag fsck.gfs2 errors.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 8b57526..b0d7af0 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -2032,6 +2032,7 @@ static void copy_quotas(struct gfs2_sbd *sdp)
nq_ip->i_di.di_height = oq_ip->i_di.di_height;
nq_ip->i_di.di_size = oq_ip->i_di.di_size;
+ nq_ip->i_di.di_blocks = oq_ip->i_di.di_blocks;
memcpy(nq_ip->i_bh->b_data + sizeof(struct gfs2_dinode),
oq_ip->i_bh->b_data + sizeof(struct gfs2_dinode),
sdp->bsize - sizeof(struct gfs2_dinode));
10 years, 11 months
cluster: RHEL59 - gfs2_convert: mark buffer dirty when switching dirs from meta to data
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=e74cc1bf79a...
Commit: e74cc1bf79a4826b70cd058a5128c8ba9d17b1a6
Parent: d760b55214744e92dd556fc3d07326aa776ce0d8
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Dec 17 14:47:50 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:16 2013 -0500
gfs2_convert: mark buffer dirty when switching dirs from meta to data
This patch changes function inode_renumber so that it properly marks
the rgrp bitmap dirty after switching bits from "meta" to "data".
This happens when directory leaf, hash table, eattr, etc. blocks come
in from GFS1 as "meta" and need to be switched to GFS2 as "data".
In GFS2, only dinodes get the "meta" designation. This conversion was
taking place, but the code broke out of the loop before properly
marking the buffer as modified. So if no other modifications were
done to that bitmap, the bitmap change would be forgotten.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index f620e12..8b57526 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1060,10 +1060,10 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
~(0x03 << (GFS2_BIT_SIZE * byte_bit));
rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
(0x01 << (GFS2_BIT_SIZE * byte_bit));
+ bmodified(rgd->bh[blk]);
break;
}
bitmap_byte -= (sbp->bsize - buf_offset);
- bmodified(rgd->bh[blk]);
}
}
brelse(bh);
10 years, 11 months
cluster: RHEL59 - gfs2_convert: mark rgrp bitmaps dirty when converting
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=d760b552147...
Commit: d760b55214744e92dd556fc3d07326aa776ce0d8
Parent: 9ccbdd996938e5e5cd9f247ffbd1aace87eb7641
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Dec 17 14:43:04 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Jun 3 12:51:10 2013 -0500
gfs2_convert: mark rgrp bitmaps dirty when converting
This patch changes gfs2_convert function convert_bitmaps so that
it marks the affected rgrp buffers as modified when bitmap bits
are switched from unlinked metadata to free blocks.
rhbz#887374
---
gfs2/convert/gfs2_convert.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index b9e034c..f620e12 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -194,8 +194,10 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
for (y = 0; y < GFS2_NBBY; y++) {
state = (rg->bh[blk]->b_data[x] >>
(GFS2_BIT_SIZE * y)) & 0x03;
- if (state == 0x02) /* unallocated metadata state invalid */
+ if (state == 0x02) {/* unallocated metadata state invalid */
rg->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+ bmodified(rg->bh[blk]);
+ }
}
}
}/* convert_bitmaps */
10 years, 11 months