diff options
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 208 |
1 files changed, 122 insertions, 86 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index bec75aff3d9f..df63ba20ae90 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -40,8 +40,7 @@ | |||
40 | #include <linux/crc32.h> | 40 | #include <linux/crc32.h> |
41 | #include <linux/debugfs.h> | 41 | #include <linux/debugfs.h> |
42 | #include <linux/mount.h> | 42 | #include <linux/mount.h> |
43 | 43 | #include <linux/seq_file.h> | |
44 | #include <cluster/nodemanager.h> | ||
45 | 44 | ||
46 | #define MLOG_MASK_PREFIX ML_SUPER | 45 | #define MLOG_MASK_PREFIX ML_SUPER |
47 | #include <cluster/masklog.h> | 46 | #include <cluster/masklog.h> |
@@ -88,6 +87,7 @@ struct mount_options | |||
88 | unsigned int atime_quantum; | 87 | unsigned int atime_quantum; |
89 | signed short slot; | 88 | signed short slot; |
90 | unsigned int localalloc_opt; | 89 | unsigned int localalloc_opt; |
90 | char cluster_stack[OCFS2_STACK_LABEL_LEN + 1]; | ||
91 | }; | 91 | }; |
92 | 92 | ||
93 | static int ocfs2_parse_options(struct super_block *sb, char *options, | 93 | static int ocfs2_parse_options(struct super_block *sb, char *options, |
@@ -109,7 +109,6 @@ static int ocfs2_sync_fs(struct super_block *sb, int wait); | |||
109 | static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb); | 109 | static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb); |
110 | static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb); | 110 | static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb); |
111 | static void ocfs2_release_system_inodes(struct ocfs2_super *osb); | 111 | static void ocfs2_release_system_inodes(struct ocfs2_super *osb); |
112 | static int ocfs2_fill_local_node_info(struct ocfs2_super *osb); | ||
113 | static int ocfs2_check_volume(struct ocfs2_super *osb); | 112 | static int ocfs2_check_volume(struct ocfs2_super *osb); |
114 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, | 113 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, |
115 | struct buffer_head *bh, | 114 | struct buffer_head *bh, |
@@ -154,6 +153,7 @@ enum { | |||
154 | Opt_commit, | 153 | Opt_commit, |
155 | Opt_localalloc, | 154 | Opt_localalloc, |
156 | Opt_localflocks, | 155 | Opt_localflocks, |
156 | Opt_stack, | ||
157 | Opt_err, | 157 | Opt_err, |
158 | }; | 158 | }; |
159 | 159 | ||
@@ -172,6 +172,7 @@ static match_table_t tokens = { | |||
172 | {Opt_commit, "commit=%u"}, | 172 | {Opt_commit, "commit=%u"}, |
173 | {Opt_localalloc, "localalloc=%d"}, | 173 | {Opt_localalloc, "localalloc=%d"}, |
174 | {Opt_localflocks, "localflocks"}, | 174 | {Opt_localflocks, "localflocks"}, |
175 | {Opt_stack, "cluster_stack=%s"}, | ||
175 | {Opt_err, NULL} | 176 | {Opt_err, NULL} |
176 | }; | 177 | }; |
177 | 178 | ||
@@ -551,8 +552,17 @@ static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) | |||
551 | } | 552 | } |
552 | } | 553 | } |
553 | 554 | ||
555 | if (ocfs2_userspace_stack(osb)) { | ||
556 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
557 | mlog(ML_ERROR, "Userspace stack expected, but " | ||
558 | "o2cb heartbeat arguments passed to mount\n"); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | } | ||
562 | |||
554 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | 563 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { |
555 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb)) { | 564 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb) && |
565 | !ocfs2_userspace_stack(osb)) { | ||
556 | mlog(ML_ERROR, "Heartbeat has to be started to mount " | 566 | mlog(ML_ERROR, "Heartbeat has to be started to mount " |
557 | "a read-write clustered device.\n"); | 567 | "a read-write clustered device.\n"); |
558 | return -EINVAL; | 568 | return -EINVAL; |
@@ -562,6 +572,35 @@ static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) | |||
562 | return 0; | 572 | return 0; |
563 | } | 573 | } |
564 | 574 | ||
575 | /* | ||
576 | * If we're using a userspace stack, mount should have passed | ||
577 | * a name that matches the disk. If not, mount should not | ||
578 | * have passed a stack. | ||
579 | */ | ||
580 | static int ocfs2_verify_userspace_stack(struct ocfs2_super *osb, | ||
581 | struct mount_options *mopt) | ||
582 | { | ||
583 | if (!ocfs2_userspace_stack(osb) && mopt->cluster_stack[0]) { | ||
584 | mlog(ML_ERROR, | ||
585 | "cluster stack passed to mount, but this filesystem " | ||
586 | "does not support it\n"); | ||
587 | return -EINVAL; | ||
588 | } | ||
589 | |||
590 | if (ocfs2_userspace_stack(osb) && | ||
591 | strncmp(osb->osb_cluster_stack, mopt->cluster_stack, | ||
592 | OCFS2_STACK_LABEL_LEN)) { | ||
593 | mlog(ML_ERROR, | ||
594 | "cluster stack passed to mount (\"%s\") does not " | ||
595 | "match the filesystem (\"%s\")\n", | ||
596 | mopt->cluster_stack, | ||
597 | osb->osb_cluster_stack); | ||
598 | return -EINVAL; | ||
599 | } | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
565 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | 604 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) |
566 | { | 605 | { |
567 | struct dentry *root; | 606 | struct dentry *root; |
@@ -579,15 +618,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
579 | goto read_super_error; | 618 | goto read_super_error; |
580 | } | 619 | } |
581 | 620 | ||
582 | /* for now we only have one cluster/node, make sure we see it | ||
583 | * in the heartbeat universe */ | ||
584 | if (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
585 | if (!o2hb_check_local_node_heartbeating()) { | ||
586 | status = -EINVAL; | ||
587 | goto read_super_error; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /* probe for superblock */ | 621 | /* probe for superblock */ |
592 | status = ocfs2_sb_probe(sb, &bh, §or_size); | 622 | status = ocfs2_sb_probe(sb, &bh, §or_size); |
593 | if (status < 0) { | 623 | if (status < 0) { |
@@ -609,6 +639,10 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
609 | osb->osb_commit_interval = parsed_options.commit_interval; | 639 | osb->osb_commit_interval = parsed_options.commit_interval; |
610 | osb->local_alloc_size = parsed_options.localalloc_opt; | 640 | osb->local_alloc_size = parsed_options.localalloc_opt; |
611 | 641 | ||
642 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); | ||
643 | if (status) | ||
644 | goto read_super_error; | ||
645 | |||
612 | sb->s_magic = OCFS2_SUPER_MAGIC; | 646 | sb->s_magic = OCFS2_SUPER_MAGIC; |
613 | 647 | ||
614 | /* Hard readonly mode only if: bdev_read_only, MS_RDONLY, | 648 | /* Hard readonly mode only if: bdev_read_only, MS_RDONLY, |
@@ -694,7 +728,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
694 | if (ocfs2_mount_local(osb)) | 728 | if (ocfs2_mount_local(osb)) |
695 | snprintf(nodestr, sizeof(nodestr), "local"); | 729 | snprintf(nodestr, sizeof(nodestr), "local"); |
696 | else | 730 | else |
697 | snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num); | 731 | snprintf(nodestr, sizeof(nodestr), "%u", osb->node_num); |
698 | 732 | ||
699 | printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) " | 733 | printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) " |
700 | "with %s data mode.\n", | 734 | "with %s data mode.\n", |
@@ -763,6 +797,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
763 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | 797 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; |
764 | mopt->slot = OCFS2_INVALID_SLOT; | 798 | mopt->slot = OCFS2_INVALID_SLOT; |
765 | mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE; | 799 | mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE; |
800 | mopt->cluster_stack[0] = '\0'; | ||
766 | 801 | ||
767 | if (!options) { | 802 | if (!options) { |
768 | status = 1; | 803 | status = 1; |
@@ -864,6 +899,25 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
864 | if (!is_remount) | 899 | if (!is_remount) |
865 | mopt->mount_opt |= OCFS2_MOUNT_LOCALFLOCKS; | 900 | mopt->mount_opt |= OCFS2_MOUNT_LOCALFLOCKS; |
866 | break; | 901 | break; |
902 | case Opt_stack: | ||
903 | /* Check both that the option we were passed | ||
904 | * is of the right length and that it is a proper | ||
905 | * string of the right length. | ||
906 | */ | ||
907 | if (((args[0].to - args[0].from) != | ||
908 | OCFS2_STACK_LABEL_LEN) || | ||
909 | (strnlen(args[0].from, | ||
910 | OCFS2_STACK_LABEL_LEN) != | ||
911 | OCFS2_STACK_LABEL_LEN)) { | ||
912 | mlog(ML_ERROR, | ||
913 | "Invalid cluster_stack option\n"); | ||
914 | status = 0; | ||
915 | goto bail; | ||
916 | } | ||
917 | memcpy(mopt->cluster_stack, args[0].from, | ||
918 | OCFS2_STACK_LABEL_LEN); | ||
919 | mopt->cluster_stack[OCFS2_STACK_LABEL_LEN] = '\0'; | ||
920 | break; | ||
867 | default: | 921 | default: |
868 | mlog(ML_ERROR, | 922 | mlog(ML_ERROR, |
869 | "Unrecognized mount option \"%s\" " | 923 | "Unrecognized mount option \"%s\" " |
@@ -922,6 +976,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
922 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) | 976 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) |
923 | seq_printf(s, ",localflocks,"); | 977 | seq_printf(s, ",localflocks,"); |
924 | 978 | ||
979 | if (osb->osb_cluster_stack[0]) | ||
980 | seq_printf(s, ",cluster_stack=%.*s", OCFS2_STACK_LABEL_LEN, | ||
981 | osb->osb_cluster_stack); | ||
982 | |||
925 | return 0; | 983 | return 0; |
926 | } | 984 | } |
927 | 985 | ||
@@ -957,6 +1015,8 @@ static int __init ocfs2_init(void) | |||
957 | mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n"); | 1015 | mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n"); |
958 | } | 1016 | } |
959 | 1017 | ||
1018 | ocfs2_set_locking_protocol(); | ||
1019 | |||
960 | leave: | 1020 | leave: |
961 | if (status < 0) { | 1021 | if (status < 0) { |
962 | ocfs2_free_mem_caches(); | 1022 | ocfs2_free_mem_caches(); |
@@ -1132,31 +1192,6 @@ static int ocfs2_get_sector(struct super_block *sb, | |||
1132 | return 0; | 1192 | return 0; |
1133 | } | 1193 | } |
1134 | 1194 | ||
1135 | /* ocfs2 1.0 only allows one cluster and node identity per kernel image. */ | ||
1136 | static int ocfs2_fill_local_node_info(struct ocfs2_super *osb) | ||
1137 | { | ||
1138 | int status; | ||
1139 | |||
1140 | /* XXX hold a ref on the node while mounte? easy enough, if | ||
1141 | * desirable. */ | ||
1142 | if (ocfs2_mount_local(osb)) | ||
1143 | osb->node_num = 0; | ||
1144 | else | ||
1145 | osb->node_num = o2nm_this_node(); | ||
1146 | |||
1147 | if (osb->node_num == O2NM_MAX_NODES) { | ||
1148 | mlog(ML_ERROR, "could not find this host's node number\n"); | ||
1149 | status = -ENOENT; | ||
1150 | goto bail; | ||
1151 | } | ||
1152 | |||
1153 | mlog(0, "I am node %d\n", osb->node_num); | ||
1154 | |||
1155 | status = 0; | ||
1156 | bail: | ||
1157 | return status; | ||
1158 | } | ||
1159 | |||
1160 | static int ocfs2_mount_volume(struct super_block *sb) | 1195 | static int ocfs2_mount_volume(struct super_block *sb) |
1161 | { | 1196 | { |
1162 | int status = 0; | 1197 | int status = 0; |
@@ -1168,12 +1203,6 @@ static int ocfs2_mount_volume(struct super_block *sb) | |||
1168 | if (ocfs2_is_hard_readonly(osb)) | 1203 | if (ocfs2_is_hard_readonly(osb)) |
1169 | goto leave; | 1204 | goto leave; |
1170 | 1205 | ||
1171 | status = ocfs2_fill_local_node_info(osb); | ||
1172 | if (status < 0) { | ||
1173 | mlog_errno(status); | ||
1174 | goto leave; | ||
1175 | } | ||
1176 | |||
1177 | status = ocfs2_dlm_init(osb); | 1206 | status = ocfs2_dlm_init(osb); |
1178 | if (status < 0) { | 1207 | if (status < 0) { |
1179 | mlog_errno(status); | 1208 | mlog_errno(status); |
@@ -1224,18 +1253,9 @@ leave: | |||
1224 | return status; | 1253 | return status; |
1225 | } | 1254 | } |
1226 | 1255 | ||
1227 | /* we can't grab the goofy sem lock from inside wait_event, so we use | ||
1228 | * memory barriers to make sure that we'll see the null task before | ||
1229 | * being woken up */ | ||
1230 | static int ocfs2_recovery_thread_running(struct ocfs2_super *osb) | ||
1231 | { | ||
1232 | mb(); | ||
1233 | return osb->recovery_thread_task != NULL; | ||
1234 | } | ||
1235 | |||
1236 | static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | 1256 | static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) |
1237 | { | 1257 | { |
1238 | int tmp; | 1258 | int tmp, hangup_needed = 0; |
1239 | struct ocfs2_super *osb = NULL; | 1259 | struct ocfs2_super *osb = NULL; |
1240 | char nodestr[8]; | 1260 | char nodestr[8]; |
1241 | 1261 | ||
@@ -1249,25 +1269,16 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1249 | 1269 | ||
1250 | ocfs2_truncate_log_shutdown(osb); | 1270 | ocfs2_truncate_log_shutdown(osb); |
1251 | 1271 | ||
1252 | /* disable any new recovery threads and wait for any currently | 1272 | /* This will disable recovery and flush any recovery work. */ |
1253 | * running ones to exit. Do this before setting the vol_state. */ | 1273 | ocfs2_recovery_exit(osb); |
1254 | mutex_lock(&osb->recovery_lock); | ||
1255 | osb->disable_recovery = 1; | ||
1256 | mutex_unlock(&osb->recovery_lock); | ||
1257 | wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb)); | ||
1258 | |||
1259 | /* At this point, we know that no more recovery threads can be | ||
1260 | * launched, so wait for any recovery completion work to | ||
1261 | * complete. */ | ||
1262 | flush_workqueue(ocfs2_wq); | ||
1263 | 1274 | ||
1264 | ocfs2_journal_shutdown(osb); | 1275 | ocfs2_journal_shutdown(osb); |
1265 | 1276 | ||
1266 | ocfs2_sync_blockdev(sb); | 1277 | ocfs2_sync_blockdev(sb); |
1267 | 1278 | ||
1268 | /* No dlm means we've failed during mount, so skip all the | 1279 | /* No cluster connection means we've failed during mount, so skip |
1269 | * steps which depended on that to complete. */ | 1280 | * all the steps which depended on that to complete. */ |
1270 | if (osb->dlm) { | 1281 | if (osb->cconn) { |
1271 | tmp = ocfs2_super_lock(osb, 1); | 1282 | tmp = ocfs2_super_lock(osb, 1); |
1272 | if (tmp < 0) { | 1283 | if (tmp < 0) { |
1273 | mlog_errno(tmp); | 1284 | mlog_errno(tmp); |
@@ -1278,25 +1289,34 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1278 | if (osb->slot_num != OCFS2_INVALID_SLOT) | 1289 | if (osb->slot_num != OCFS2_INVALID_SLOT) |
1279 | ocfs2_put_slot(osb); | 1290 | ocfs2_put_slot(osb); |
1280 | 1291 | ||
1281 | if (osb->dlm) | 1292 | if (osb->cconn) |
1282 | ocfs2_super_unlock(osb, 1); | 1293 | ocfs2_super_unlock(osb, 1); |
1283 | 1294 | ||
1284 | ocfs2_release_system_inodes(osb); | 1295 | ocfs2_release_system_inodes(osb); |
1285 | 1296 | ||
1286 | if (osb->dlm) | 1297 | /* |
1287 | ocfs2_dlm_shutdown(osb); | 1298 | * If we're dismounting due to mount error, mount.ocfs2 will clean |
1299 | * up heartbeat. If we're a local mount, there is no heartbeat. | ||
1300 | * If we failed before we got a uuid_str yet, we can't stop | ||
1301 | * heartbeat. Otherwise, do it. | ||
1302 | */ | ||
1303 | if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str) | ||
1304 | hangup_needed = 1; | ||
1305 | |||
1306 | if (osb->cconn) | ||
1307 | ocfs2_dlm_shutdown(osb, hangup_needed); | ||
1288 | 1308 | ||
1289 | debugfs_remove(osb->osb_debug_root); | 1309 | debugfs_remove(osb->osb_debug_root); |
1290 | 1310 | ||
1291 | if (!mnt_err) | 1311 | if (hangup_needed) |
1292 | ocfs2_stop_heartbeat(osb); | 1312 | ocfs2_cluster_hangup(osb->uuid_str, strlen(osb->uuid_str)); |
1293 | 1313 | ||
1294 | atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); | 1314 | atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); |
1295 | 1315 | ||
1296 | if (ocfs2_mount_local(osb)) | 1316 | if (ocfs2_mount_local(osb)) |
1297 | snprintf(nodestr, sizeof(nodestr), "local"); | 1317 | snprintf(nodestr, sizeof(nodestr), "local"); |
1298 | else | 1318 | else |
1299 | snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num); | 1319 | snprintf(nodestr, sizeof(nodestr), "%u", osb->node_num); |
1300 | 1320 | ||
1301 | printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n", | 1321 | printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n", |
1302 | osb->dev_str, nodestr); | 1322 | osb->dev_str, nodestr); |
@@ -1355,7 +1375,6 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1355 | sb->s_fs_info = osb; | 1375 | sb->s_fs_info = osb; |
1356 | sb->s_op = &ocfs2_sops; | 1376 | sb->s_op = &ocfs2_sops; |
1357 | sb->s_export_op = &ocfs2_export_ops; | 1377 | sb->s_export_op = &ocfs2_export_ops; |
1358 | osb->osb_locking_proto = ocfs2_locking_protocol; | ||
1359 | sb->s_time_gran = 1; | 1378 | sb->s_time_gran = 1; |
1360 | sb->s_flags |= MS_NOATIME; | 1379 | sb->s_flags |= MS_NOATIME; |
1361 | /* this is needed to support O_LARGEFILE */ | 1380 | /* this is needed to support O_LARGEFILE */ |
@@ -1368,7 +1387,6 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1368 | osb->s_sectsize_bits = blksize_bits(sector_size); | 1387 | osb->s_sectsize_bits = blksize_bits(sector_size); |
1369 | BUG_ON(!osb->s_sectsize_bits); | 1388 | BUG_ON(!osb->s_sectsize_bits); |
1370 | 1389 | ||
1371 | init_waitqueue_head(&osb->recovery_event); | ||
1372 | spin_lock_init(&osb->dc_task_lock); | 1390 | spin_lock_init(&osb->dc_task_lock); |
1373 | init_waitqueue_head(&osb->dc_event); | 1391 | init_waitqueue_head(&osb->dc_event); |
1374 | osb->dc_work_sequence = 0; | 1392 | osb->dc_work_sequence = 0; |
@@ -1376,6 +1394,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1376 | INIT_LIST_HEAD(&osb->blocked_lock_list); | 1394 | INIT_LIST_HEAD(&osb->blocked_lock_list); |
1377 | osb->blocked_lock_count = 0; | 1395 | osb->blocked_lock_count = 0; |
1378 | spin_lock_init(&osb->osb_lock); | 1396 | spin_lock_init(&osb->osb_lock); |
1397 | ocfs2_init_inode_steal_slot(osb); | ||
1379 | 1398 | ||
1380 | atomic_set(&osb->alloc_stats.moves, 0); | 1399 | atomic_set(&osb->alloc_stats.moves, 0); |
1381 | atomic_set(&osb->alloc_stats.local_data, 0); | 1400 | atomic_set(&osb->alloc_stats.local_data, 0); |
@@ -1388,24 +1407,23 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1388 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", | 1407 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", |
1389 | MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); | 1408 | MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); |
1390 | 1409 | ||
1391 | mutex_init(&osb->recovery_lock); | 1410 | status = ocfs2_recovery_init(osb); |
1392 | 1411 | if (status) { | |
1393 | osb->disable_recovery = 0; | 1412 | mlog(ML_ERROR, "Unable to initialize recovery state\n"); |
1394 | osb->recovery_thread_task = NULL; | 1413 | mlog_errno(status); |
1414 | goto bail; | ||
1415 | } | ||
1395 | 1416 | ||
1396 | init_waitqueue_head(&osb->checkpoint_event); | 1417 | init_waitqueue_head(&osb->checkpoint_event); |
1397 | atomic_set(&osb->needs_checkpoint, 0); | 1418 | atomic_set(&osb->needs_checkpoint, 0); |
1398 | 1419 | ||
1399 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | 1420 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; |
1400 | 1421 | ||
1401 | osb->node_num = O2NM_INVALID_NODE_NUM; | ||
1402 | osb->slot_num = OCFS2_INVALID_SLOT; | 1422 | osb->slot_num = OCFS2_INVALID_SLOT; |
1403 | 1423 | ||
1404 | osb->local_alloc_state = OCFS2_LA_UNUSED; | 1424 | osb->local_alloc_state = OCFS2_LA_UNUSED; |
1405 | osb->local_alloc_bh = NULL; | 1425 | osb->local_alloc_bh = NULL; |
1406 | 1426 | ||
1407 | ocfs2_setup_hb_callbacks(osb); | ||
1408 | |||
1409 | init_waitqueue_head(&osb->osb_mount_event); | 1427 | init_waitqueue_head(&osb->osb_mount_event); |
1410 | 1428 | ||
1411 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); | 1429 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); |
@@ -1455,6 +1473,25 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1455 | goto bail; | 1473 | goto bail; |
1456 | } | 1474 | } |
1457 | 1475 | ||
1476 | if (ocfs2_userspace_stack(osb)) { | ||
1477 | memcpy(osb->osb_cluster_stack, | ||
1478 | OCFS2_RAW_SB(di)->s_cluster_info.ci_stack, | ||
1479 | OCFS2_STACK_LABEL_LEN); | ||
1480 | osb->osb_cluster_stack[OCFS2_STACK_LABEL_LEN] = '\0'; | ||
1481 | if (strlen(osb->osb_cluster_stack) != OCFS2_STACK_LABEL_LEN) { | ||
1482 | mlog(ML_ERROR, | ||
1483 | "couldn't mount because of an invalid " | ||
1484 | "cluster stack label (%s) \n", | ||
1485 | osb->osb_cluster_stack); | ||
1486 | status = -EINVAL; | ||
1487 | goto bail; | ||
1488 | } | ||
1489 | } else { | ||
1490 | /* The empty string is identical with classic tools that | ||
1491 | * don't know about s_cluster_info. */ | ||
1492 | osb->osb_cluster_stack[0] = '\0'; | ||
1493 | } | ||
1494 | |||
1458 | get_random_bytes(&osb->s_next_generation, sizeof(u32)); | 1495 | get_random_bytes(&osb->s_next_generation, sizeof(u32)); |
1459 | 1496 | ||
1460 | /* FIXME | 1497 | /* FIXME |
@@ -1724,8 +1761,7 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb) | |||
1724 | 1761 | ||
1725 | /* This function assumes that the caller has the main osb resource */ | 1762 | /* This function assumes that the caller has the main osb resource */ |
1726 | 1763 | ||
1727 | if (osb->slot_info) | 1764 | ocfs2_free_slot_info(osb); |
1728 | ocfs2_free_slot_info(osb->slot_info); | ||
1729 | 1765 | ||
1730 | kfree(osb->osb_orphan_wipes); | 1766 | kfree(osb->osb_orphan_wipes); |
1731 | /* FIXME | 1767 | /* FIXME |