[Ocfs2-commits] mfasheh commits r2926 - branches/ocfs2-1.2/fs/ocfs2
svn-commits@oss.oracle.com
svn-commits at oss.oracle.com
Wed Jul 12 15:12:45 CDT 2006
Author: mfasheh
Signed-off-by: smushran
Date: 2006-07-12 15:12:44 -0500 (Wed, 12 Jul 2006)
New Revision: 2926
Modified:
branches/ocfs2-1.2/fs/ocfs2/ocfs2.h
branches/ocfs2-1.2/fs/ocfs2/proc.c
branches/ocfs2-1.2/fs/ocfs2/suballoc.c
branches/ocfs2-1.2/fs/ocfs2/super.c
Log:
Better group descriptor consistency checks:
Try to catch corrupted group descriptors with some stronger checks placed in
a couple of strategic locations. Detect a failed resizefs and refuse to
allocate past what bitmap i_clusters allows.
Signed-off-by: smushran
Modified: branches/ocfs2-1.2/fs/ocfs2/ocfs2.h
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/ocfs2.h 2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/ocfs2.h 2006-07-12 20:12:44 UTC (rev 2926)
@@ -210,7 +210,6 @@
struct ocfs2_node_map recovery_map;
struct ocfs2_node_map umount_map;
- u32 num_clusters;
u64 root_blkno;
u64 system_dir_blkno;
u64 bitmap_blkno;
Modified: branches/ocfs2-1.2/fs/ocfs2/proc.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/proc.c 2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/proc.c 2006-07-12 20:12:44 UTC (rev 2926)
@@ -75,12 +75,6 @@
int count,
int *eof,
void *data);
-static int ocfs2_proc_statistics(char *page,
- char **start,
- off_t off,
- int count,
- int *eof,
- void *data);
static int ocfs2_proc_device(char *page,
char **start,
off_t off,
@@ -125,7 +119,6 @@
{ "nodenum", NULL, ocfs2_proc_nodenum, NULL, S_IFREG | S_IRUGO, },
{ "uuid", NULL, ocfs2_proc_uuid, NULL, S_IFREG | S_IRUGO, },
{ "slotnum", NULL, ocfs2_proc_slotnum, NULL, S_IFREG | S_IRUGO, },
- { "statistics", NULL, ocfs2_proc_statistics, NULL, S_IFREG | S_IRUGO, },
{ "device", NULL, ocfs2_proc_device, NULL, S_IFREG | S_IRUGO, },
{ "nodes", NULL, ocfs2_proc_nodes, NULL, S_IFREG | S_IRUGO, },
{ "allocstat", NULL, ocfs2_proc_alloc_stat, NULL, S_IFREG | S_IRUGO, },
@@ -378,31 +371,6 @@
return ret;
}
-static int ocfs2_proc_statistics(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
- int ret = 0;
- struct ocfs2_super *osb = data;
-
- mlog_entry_void();
-
-#define PROC_STATS \
- "Number of nodes : %u\n" \
- "Cluster size : %d\n" \
- "Volume size : %"MLFu64"\n" \
- "Open Transactions: : %u\n"
-
- len = sprintf(page, PROC_STATS, osb->num_nodes, osb->s_clustersize,
- ocfs2_clusters_to_bytes(osb->sb, osb->num_clusters),
- atomic_read(&osb->journal->j_num_trans));
-
- ret = ocfs2_proc_calc_metrics(page, start, off, count, eof, len);
-
- mlog_exit(ret);
- return ret;
-}
-
static int ocfs2_proc_device(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
Modified: branches/ocfs2-1.2/fs/ocfs2/suballoc.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/suballoc.c 2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/suballoc.c 2006-07-12 20:12:44 UTC (rev 2926)
@@ -85,11 +85,6 @@
u64 *bg_blkno);
static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
int nr);
-static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
- struct buffer_head *bg_bh,
- unsigned int bits_wanted,
- u16 *bit_off,
- u16 *bits_found);
static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle,
struct inode *alloc_inode,
struct ocfs2_group_desc *bg,
@@ -143,6 +138,64 @@
return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);
}
+/* somewhat more expensive than our other checks, so use sparingly. */
+static int ocfs2_check_group_descriptor(struct super_block *sb,
+ struct ocfs2_dinode *di,
+ struct ocfs2_group_desc *gd)
+{
+ unsigned int max_bits;
+
+ if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {
+ OCFS2_RO_ON_INVALID_GROUP_DESC(sb, gd);
+ return -EIO;
+ }
+
+ if (di->i_blkno != gd->bg_parent_dinode) {
+ ocfs2_error(sb, "Group descriptor # %llu has bad parent "
+ "pointer (%llu, expected %llu)",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ (unsigned long long)le64_to_cpu(gd->bg_parent_dinode),
+ (unsigned long long)le64_to_cpu(di->i_blkno));
+ return -EIO;
+ }
+
+ max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc);
+ if (le16_to_cpu(gd->bg_bits) > max_bits) {
+ ocfs2_error(sb, "Group descriptor # %llu has bit count of %u",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_bits));
+ return -EIO;
+ }
+
+ if (le16_to_cpu(gd->bg_chain) >=
+ le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) {
+ ocfs2_error(sb, "Group descriptor # %llu has bad chain %u",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_chain));
+ return -EIO;
+ }
+
+ if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) {
+ ocfs2_error(sb, "Group descriptor # %llu has bit count %u but "
+ "claims that %u are free",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_bits),
+ le16_to_cpu(gd->bg_free_bits_count));
+ return -EIO;
+ }
+
+ if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
+ ocfs2_error(sb, "Group descriptor # %llu has bit count %u but "
+ "max bitmap bits of %u",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_bits),
+ 8 * le16_to_cpu(gd->bg_size));
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle,
struct inode *alloc_inode,
struct buffer_head *bg_bh,
@@ -662,6 +715,7 @@
static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
struct buffer_head *bg_bh,
unsigned int bits_wanted,
+ unsigned int total_bits,
u16 *bit_off,
u16 *bits_found)
{
@@ -678,10 +732,8 @@
found = start = best_offset = best_size = 0;
bitmap = bg->bg_bitmap;
- while((offset = ocfs2_find_next_zero_bit(bitmap,
- le16_to_cpu(bg->bg_bits),
- start)) != -1) {
- if (offset == le16_to_cpu(bg->bg_bits))
+ while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) {
+ if (offset == total_bits)
break;
if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) {
@@ -909,14 +961,35 @@
{
int search = -ENOSPC;
int ret;
- struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data;
+ struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *) group_bh->b_data;
u16 tmp_off, tmp_found;
+ unsigned int max_bits, gd_cluster_off;
BUG_ON(!ocfs2_is_cluster_bitmap(inode));
- if (bg->bg_free_bits_count) {
+ if (gd->bg_free_bits_count) {
+ max_bits = le16_to_cpu(gd->bg_bits);
+
+ /* Tail groups in cluster bitmaps which aren't cpg
+ * aligned are prone to partial extention by a failed
+ * fs resize. If the file system resize never got to
+ * update the dinode cluster count, then we don't want
+ * to trust any clusters past it, regardless of what
+ * the group descriptor says. */
+ gd_cluster_off = ocfs2_blocks_to_clusters(inode->i_sb,
+ le64_to_cpu(gd->bg_blkno));
+ if ((gd_cluster_off + max_bits) >
+ OCFS2_I(inode)->ip_clusters) {
+ max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off;
+ mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n",
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_bits),
+ OCFS2_I(inode)->ip_clusters, max_bits);
+ }
+
ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
group_bh, bits_wanted,
+ max_bits,
&tmp_off, &tmp_found);
if (ret)
return ret;
@@ -949,6 +1022,7 @@
if (bg->bg_free_bits_count)
ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
group_bh, bits_wanted,
+ le16_to_cpu(bg->bg_bits),
bit_off, bits_found);
return ret;
@@ -985,9 +1059,9 @@
goto bail;
}
bg = (struct ocfs2_group_desc *) group_bh->b_data;
- if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
- OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
- status = -EIO;
+ status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg);
+ if (status) {
+ mlog_errno(status);
goto bail;
}
@@ -1015,9 +1089,9 @@
goto bail;
}
bg = (struct ocfs2_group_desc *) group_bh->b_data;
- if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
- OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
- status = -EIO;
+ status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg);
+ if (status) {
+ mlog_errno(status);
goto bail;
}
}
@@ -1492,9 +1566,9 @@
}
group = (struct ocfs2_group_desc *) group_bh->b_data;
- if (!OCFS2_IS_VALID_GROUP_DESC(group)) {
- OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, group);
- status = -EIO;
+ status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group);
+ if (status) {
+ mlog_errno(status);
goto bail;
}
BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits));
Modified: branches/ocfs2-1.2/fs/ocfs2/super.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/super.c 2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/super.c 2006-07-12 20:12:44 UTC (rev 2926)
@@ -1485,8 +1485,13 @@
osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno;
+ /* We don't have a cluster lock on the bitmap here because
+ * we're only interested in static information and the extra
+ * complexity at mount time isn't worth it. Don't pass the
+ * inode in to the read function though as we don't want it to
+ * be put in the cache. */
status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0,
- inode);
+ NULL);
iput(inode);
if (status < 0) {
mlog_errno(status);
@@ -1495,7 +1500,6 @@
di = (struct ocfs2_dinode *) bitmap_bh->b_data;
osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg);
- osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total);
brelse(bitmap_bh);
mlog(0, "cluster bitmap inode: %"MLFu64", clusters per group: %u\n",
osb->bitmap_blkno, osb->bitmap_cpg);
More information about the Ocfs2-commits
mailing list