aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r--fs/ocfs2/super.c104
1 files changed, 87 insertions, 17 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 4e009ad303a1..a8a0ca44f88f 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -178,6 +178,8 @@ enum {
178 Opt_noacl, 178 Opt_noacl,
179 Opt_usrquota, 179 Opt_usrquota,
180 Opt_grpquota, 180 Opt_grpquota,
181 Opt_coherency_buffered,
182 Opt_coherency_full,
181 Opt_resv_level, 183 Opt_resv_level,
182 Opt_dir_resv_level, 184 Opt_dir_resv_level,
183 Opt_err, 185 Opt_err,
@@ -207,6 +209,8 @@ static const match_table_t tokens = {
207 {Opt_noacl, "noacl"}, 209 {Opt_noacl, "noacl"},
208 {Opt_usrquota, "usrquota"}, 210 {Opt_usrquota, "usrquota"},
209 {Opt_grpquota, "grpquota"}, 211 {Opt_grpquota, "grpquota"},
212 {Opt_coherency_buffered, "coherency=buffered"},
213 {Opt_coherency_full, "coherency=full"},
210 {Opt_resv_level, "resv_level=%u"}, 214 {Opt_resv_level, "resv_level=%u"},
211 {Opt_dir_resv_level, "dir_resv_level=%u"}, 215 {Opt_dir_resv_level, "dir_resv_level=%u"},
212 {Opt_err, NULL} 216 {Opt_err, NULL}
@@ -516,11 +520,11 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
516 520
517 mlog_entry_void(); 521 mlog_entry_void();
518 522
519 for (i = 0; i < NUM_SYSTEM_INODES; i++) { 523 for (i = 0; i < NUM_GLOBAL_SYSTEM_INODES; i++) {
520 inode = osb->system_inodes[i]; 524 inode = osb->global_system_inodes[i];
521 if (inode) { 525 if (inode) {
522 iput(inode); 526 iput(inode);
523 osb->system_inodes[i] = NULL; 527 osb->global_system_inodes[i] = NULL;
524 } 528 }
525 } 529 }
526 530
@@ -536,6 +540,20 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
536 osb->root_inode = NULL; 540 osb->root_inode = NULL;
537 } 541 }
538 542
543 if (!osb->local_system_inodes)
544 goto out;
545
546 for (i = 0; i < NUM_LOCAL_SYSTEM_INODES * osb->max_slots; i++) {
547 if (osb->local_system_inodes[i]) {
548 iput(osb->local_system_inodes[i]);
549 osb->local_system_inodes[i] = NULL;
550 }
551 }
552
553 kfree(osb->local_system_inodes);
554 osb->local_system_inodes = NULL;
555
556out:
539 mlog_exit(0); 557 mlog_exit(0);
540} 558}
541 559
@@ -1452,6 +1470,12 @@ static int ocfs2_parse_options(struct super_block *sb,
1452 case Opt_grpquota: 1470 case Opt_grpquota:
1453 mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; 1471 mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA;
1454 break; 1472 break;
1473 case Opt_coherency_buffered:
1474 mopt->mount_opt |= OCFS2_MOUNT_COHERENCY_BUFFERED;
1475 break;
1476 case Opt_coherency_full:
1477 mopt->mount_opt &= ~OCFS2_MOUNT_COHERENCY_BUFFERED;
1478 break;
1455 case Opt_acl: 1479 case Opt_acl:
1456 mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; 1480 mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
1457 mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL; 1481 mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL;
@@ -1563,6 +1587,11 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1563 if (opts & OCFS2_MOUNT_GRPQUOTA) 1587 if (opts & OCFS2_MOUNT_GRPQUOTA)
1564 seq_printf(s, ",grpquota"); 1588 seq_printf(s, ",grpquota");
1565 1589
1590 if (opts & OCFS2_MOUNT_COHERENCY_BUFFERED)
1591 seq_printf(s, ",coherency=buffered");
1592 else
1593 seq_printf(s, ",coherency=full");
1594
1566 if (opts & OCFS2_MOUNT_NOUSERXATTR) 1595 if (opts & OCFS2_MOUNT_NOUSERXATTR)
1567 seq_printf(s, ",nouser_xattr"); 1596 seq_printf(s, ",nouser_xattr");
1568 else 1597 else
@@ -2017,6 +2046,36 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
2017 return 0; 2046 return 0;
2018} 2047}
2019 2048
2049/* Make sure entire volume is addressable by our journal. Requires
2050 osb_clusters_at_boot to be valid and for the journal to have been
2051 initialized by ocfs2_journal_init(). */
2052static int ocfs2_journal_addressable(struct ocfs2_super *osb)
2053{
2054 int status = 0;
2055 u64 max_block =
2056 ocfs2_clusters_to_blocks(osb->sb,
2057 osb->osb_clusters_at_boot) - 1;
2058
2059 /* 32-bit block number is always OK. */
2060 if (max_block <= (u32)~0ULL)
2061 goto out;
2062
2063 /* Volume is "huge", so see if our journal is new enough to
2064 support it. */
2065 if (!(OCFS2_HAS_COMPAT_FEATURE(osb->sb,
2066 OCFS2_FEATURE_COMPAT_JBD2_SB) &&
2067 jbd2_journal_check_used_features(osb->journal->j_journal, 0, 0,
2068 JBD2_FEATURE_INCOMPAT_64BIT))) {
2069 mlog(ML_ERROR, "The journal cannot address the entire volume. "
2070 "Enable the 'block64' journal option with tunefs.ocfs2");
2071 status = -EFBIG;
2072 goto out;
2073 }
2074
2075 out:
2076 return status;
2077}
2078
2020static int ocfs2_initialize_super(struct super_block *sb, 2079static int ocfs2_initialize_super(struct super_block *sb,
2021 struct buffer_head *bh, 2080 struct buffer_head *bh,
2022 int sector_size, 2081 int sector_size,
@@ -2029,6 +2088,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
2029 struct ocfs2_journal *journal; 2088 struct ocfs2_journal *journal;
2030 __le32 uuid_net_key; 2089 __le32 uuid_net_key;
2031 struct ocfs2_super *osb; 2090 struct ocfs2_super *osb;
2091 u64 total_blocks;
2032 2092
2033 mlog_entry_void(); 2093 mlog_entry_void();
2034 2094
@@ -2087,6 +2147,15 @@ static int ocfs2_initialize_super(struct super_block *sb,
2087 snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", 2147 snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
2088 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); 2148 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
2089 2149
2150 osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
2151 if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
2152 mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
2153 osb->max_slots);
2154 status = -EINVAL;
2155 goto bail;
2156 }
2157 mlog(0, "max_slots for this device: %u\n", osb->max_slots);
2158
2090 ocfs2_orphan_scan_init(osb); 2159 ocfs2_orphan_scan_init(osb);
2091 2160
2092 status = ocfs2_recovery_init(osb); 2161 status = ocfs2_recovery_init(osb);
@@ -2125,15 +2194,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
2125 goto bail; 2194 goto bail;
2126 } 2195 }
2127 2196
2128 osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
2129 if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
2130 mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
2131 osb->max_slots);
2132 status = -EINVAL;
2133 goto bail;
2134 }
2135 mlog(0, "max_slots for this device: %u\n", osb->max_slots);
2136
2137 osb->slot_recovery_generations = 2197 osb->slot_recovery_generations =
2138 kcalloc(osb->max_slots, sizeof(*osb->slot_recovery_generations), 2198 kcalloc(osb->max_slots, sizeof(*osb->slot_recovery_generations),
2139 GFP_KERNEL); 2199 GFP_KERNEL);
@@ -2243,11 +2303,15 @@ static int ocfs2_initialize_super(struct super_block *sb,
2243 goto bail; 2303 goto bail;
2244 } 2304 }
2245 2305
2246 if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1) 2306 total_blocks = ocfs2_clusters_to_blocks(osb->sb,
2247 > (u32)~0UL) { 2307 le32_to_cpu(di->i_clusters));
2248 mlog(ML_ERROR, "Volume might try to write to blocks beyond " 2308
2249 "what jbd can address in 32 bits.\n"); 2309 status = generic_check_addressable(osb->sb->s_blocksize_bits,
2250 status = -EINVAL; 2310 total_blocks);
2311 if (status) {
2312 mlog(ML_ERROR, "Volume too large "
2313 "to mount safely on this system");
2314 status = -EFBIG;
2251 goto bail; 2315 goto bail;
2252 } 2316 }
2253 2317
@@ -2409,6 +2473,12 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
2409 goto finally; 2473 goto finally;
2410 } 2474 }
2411 2475
2476 /* Now that journal has been initialized, check to make sure
2477 entire volume is addressable. */
2478 status = ocfs2_journal_addressable(osb);
2479 if (status)
2480 goto finally;
2481
2412 /* If the journal was unmounted cleanly then we don't want to 2482 /* If the journal was unmounted cleanly then we don't want to
2413 * recover anything. Otherwise, journal_load will do that 2483 * recover anything. Otherwise, journal_load will do that
2414 * dirty work for us :) */ 2484 * dirty work for us :) */