| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* -*- mode: c; c-basic-offset: 8; -*- |
|---|
| 2 | 3 | * vim: noexpandtab sw=8 ts=8 sts=0: |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * load/unload driver, mount/dismount volumes |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Copyright (C) 2002, 2004 Oracle. All rights reserved. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or |
|---|
| 11 | | - * modify it under the terms of the GNU General Public |
|---|
| 12 | | - * License as published by the Free Software Foundation; either |
|---|
| 13 | | - * version 2 of the License, or (at your option) any later version. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 18 | | - * General Public License for more details. |
|---|
| 19 | | - * |
|---|
| 20 | | - * You should have received a copy of the GNU General Public |
|---|
| 21 | | - * License along with this program; if not, write to the |
|---|
| 22 | | - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|---|
| 23 | | - * Boston, MA 021110-1307, USA. |
|---|
| 24 | 10 | */ |
|---|
| 25 | 11 | |
|---|
| 26 | 12 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 85 | 71 | |
|---|
| 86 | 72 | MODULE_AUTHOR("Oracle"); |
|---|
| 87 | 73 | MODULE_LICENSE("GPL"); |
|---|
| 74 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 88 | 75 | MODULE_DESCRIPTION("OCFS2 cluster file system"); |
|---|
| 89 | 76 | |
|---|
| 90 | 77 | struct mount_options |
|---|
| .. | .. |
|---|
| 134 | 121 | int block, |
|---|
| 135 | 122 | int sect_size); |
|---|
| 136 | 123 | static struct inode *ocfs2_alloc_inode(struct super_block *sb); |
|---|
| 137 | | -static void ocfs2_destroy_inode(struct inode *inode); |
|---|
| 124 | +static void ocfs2_free_inode(struct inode *inode); |
|---|
| 138 | 125 | static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend); |
|---|
| 139 | 126 | static int ocfs2_enable_quotas(struct ocfs2_super *osb); |
|---|
| 140 | 127 | static void ocfs2_disable_quotas(struct ocfs2_super *osb); |
|---|
| .. | .. |
|---|
| 147 | 134 | static const struct super_operations ocfs2_sops = { |
|---|
| 148 | 135 | .statfs = ocfs2_statfs, |
|---|
| 149 | 136 | .alloc_inode = ocfs2_alloc_inode, |
|---|
| 150 | | - .destroy_inode = ocfs2_destroy_inode, |
|---|
| 137 | + .free_inode = ocfs2_free_inode, |
|---|
| 151 | 138 | .drop_inode = ocfs2_drop_inode, |
|---|
| 152 | 139 | .evict_inode = ocfs2_evict_inode, |
|---|
| 153 | 140 | .sync_fs = ocfs2_sync_fs, |
|---|
| .. | .. |
|---|
| 234 | 221 | int i, out = 0; |
|---|
| 235 | 222 | unsigned long flags; |
|---|
| 236 | 223 | |
|---|
| 237 | | - out += snprintf(buf + out, len - out, |
|---|
| 224 | + out += scnprintf(buf + out, len - out, |
|---|
| 238 | 225 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", |
|---|
| 239 | 226 | "Device", osb->dev_str, osb->uuid_str, |
|---|
| 240 | 227 | osb->fs_generation, osb->vol_label); |
|---|
| 241 | 228 | |
|---|
| 242 | | - out += snprintf(buf + out, len - out, |
|---|
| 229 | + out += scnprintf(buf + out, len - out, |
|---|
| 243 | 230 | "%10s => State: %d Flags: 0x%lX\n", "Volume", |
|---|
| 244 | 231 | atomic_read(&osb->vol_state), osb->osb_flags); |
|---|
| 245 | 232 | |
|---|
| 246 | | - out += snprintf(buf + out, len - out, |
|---|
| 233 | + out += scnprintf(buf + out, len - out, |
|---|
| 247 | 234 | "%10s => Block: %lu Cluster: %d\n", "Sizes", |
|---|
| 248 | 235 | osb->sb->s_blocksize, osb->s_clustersize); |
|---|
| 249 | 236 | |
|---|
| 250 | | - out += snprintf(buf + out, len - out, |
|---|
| 237 | + out += scnprintf(buf + out, len - out, |
|---|
| 251 | 238 | "%10s => Compat: 0x%X Incompat: 0x%X " |
|---|
| 252 | 239 | "ROcompat: 0x%X\n", |
|---|
| 253 | 240 | "Features", osb->s_feature_compat, |
|---|
| 254 | 241 | osb->s_feature_incompat, osb->s_feature_ro_compat); |
|---|
| 255 | 242 | |
|---|
| 256 | | - out += snprintf(buf + out, len - out, |
|---|
| 243 | + out += scnprintf(buf + out, len - out, |
|---|
| 257 | 244 | "%10s => Opts: 0x%lX AtimeQuanta: %u\n", "Mount", |
|---|
| 258 | 245 | osb->s_mount_opt, osb->s_atime_quantum); |
|---|
| 259 | 246 | |
|---|
| 260 | 247 | if (cconn) { |
|---|
| 261 | | - out += snprintf(buf + out, len - out, |
|---|
| 248 | + out += scnprintf(buf + out, len - out, |
|---|
| 262 | 249 | "%10s => Stack: %s Name: %*s " |
|---|
| 263 | 250 | "Version: %d.%d\n", "Cluster", |
|---|
| 264 | 251 | (*osb->osb_cluster_stack == '\0' ? |
|---|
| .. | .. |
|---|
| 269 | 256 | } |
|---|
| 270 | 257 | |
|---|
| 271 | 258 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
|---|
| 272 | | - out += snprintf(buf + out, len - out, |
|---|
| 259 | + out += scnprintf(buf + out, len - out, |
|---|
| 273 | 260 | "%10s => Pid: %d Count: %lu WakeSeq: %lu " |
|---|
| 274 | 261 | "WorkSeq: %lu\n", "DownCnvt", |
|---|
| 275 | 262 | (osb->dc_task ? task_pid_nr(osb->dc_task) : -1), |
|---|
| .. | .. |
|---|
| 278 | 265 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
|---|
| 279 | 266 | |
|---|
| 280 | 267 | spin_lock(&osb->osb_lock); |
|---|
| 281 | | - out += snprintf(buf + out, len - out, "%10s => Pid: %d Nodes:", |
|---|
| 268 | + out += scnprintf(buf + out, len - out, "%10s => Pid: %d Nodes:", |
|---|
| 282 | 269 | "Recovery", |
|---|
| 283 | 270 | (osb->recovery_thread_task ? |
|---|
| 284 | 271 | task_pid_nr(osb->recovery_thread_task) : -1)); |
|---|
| 285 | 272 | if (rm->rm_used == 0) |
|---|
| 286 | | - out += snprintf(buf + out, len - out, " None\n"); |
|---|
| 273 | + out += scnprintf(buf + out, len - out, " None\n"); |
|---|
| 287 | 274 | else { |
|---|
| 288 | 275 | for (i = 0; i < rm->rm_used; i++) |
|---|
| 289 | | - out += snprintf(buf + out, len - out, " %d", |
|---|
| 276 | + out += scnprintf(buf + out, len - out, " %d", |
|---|
| 290 | 277 | rm->rm_entries[i]); |
|---|
| 291 | | - out += snprintf(buf + out, len - out, "\n"); |
|---|
| 278 | + out += scnprintf(buf + out, len - out, "\n"); |
|---|
| 292 | 279 | } |
|---|
| 293 | 280 | spin_unlock(&osb->osb_lock); |
|---|
| 294 | 281 | |
|---|
| 295 | | - out += snprintf(buf + out, len - out, |
|---|
| 282 | + out += scnprintf(buf + out, len - out, |
|---|
| 296 | 283 | "%10s => Pid: %d Interval: %lu\n", "Commit", |
|---|
| 297 | 284 | (osb->commit_task ? task_pid_nr(osb->commit_task) : -1), |
|---|
| 298 | 285 | osb->osb_commit_interval); |
|---|
| 299 | 286 | |
|---|
| 300 | | - out += snprintf(buf + out, len - out, |
|---|
| 287 | + out += scnprintf(buf + out, len - out, |
|---|
| 301 | 288 | "%10s => State: %d TxnId: %lu NumTxns: %d\n", |
|---|
| 302 | 289 | "Journal", osb->journal->j_state, |
|---|
| 303 | 290 | osb->journal->j_trans_id, |
|---|
| 304 | 291 | atomic_read(&osb->journal->j_num_trans)); |
|---|
| 305 | 292 | |
|---|
| 306 | | - out += snprintf(buf + out, len - out, |
|---|
| 293 | + out += scnprintf(buf + out, len - out, |
|---|
| 307 | 294 | "%10s => GlobalAllocs: %d LocalAllocs: %d " |
|---|
| 308 | 295 | "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n", |
|---|
| 309 | 296 | "Stats", |
|---|
| .. | .. |
|---|
| 313 | 300 | atomic_read(&osb->alloc_stats.moves), |
|---|
| 314 | 301 | atomic_read(&osb->alloc_stats.bg_extends)); |
|---|
| 315 | 302 | |
|---|
| 316 | | - out += snprintf(buf + out, len - out, |
|---|
| 303 | + out += scnprintf(buf + out, len - out, |
|---|
| 317 | 304 | "%10s => State: %u Descriptor: %llu Size: %u bits " |
|---|
| 318 | 305 | "Default: %u bits\n", |
|---|
| 319 | 306 | "LocalAlloc", osb->local_alloc_state, |
|---|
| .. | .. |
|---|
| 321 | 308 | osb->local_alloc_bits, osb->local_alloc_default_bits); |
|---|
| 322 | 309 | |
|---|
| 323 | 310 | spin_lock(&osb->osb_lock); |
|---|
| 324 | | - out += snprintf(buf + out, len - out, |
|---|
| 311 | + out += scnprintf(buf + out, len - out, |
|---|
| 325 | 312 | "%10s => InodeSlot: %d StolenInodes: %d, " |
|---|
| 326 | 313 | "MetaSlot: %d StolenMeta: %d\n", "Steal", |
|---|
| 327 | 314 | osb->s_inode_steal_slot, |
|---|
| .. | .. |
|---|
| 330 | 317 | atomic_read(&osb->s_num_meta_stolen)); |
|---|
| 331 | 318 | spin_unlock(&osb->osb_lock); |
|---|
| 332 | 319 | |
|---|
| 333 | | - out += snprintf(buf + out, len - out, "OrphanScan => "); |
|---|
| 334 | | - out += snprintf(buf + out, len - out, "Local: %u Global: %u ", |
|---|
| 320 | + out += scnprintf(buf + out, len - out, "OrphanScan => "); |
|---|
| 321 | + out += scnprintf(buf + out, len - out, "Local: %u Global: %u ", |
|---|
| 335 | 322 | os->os_count, os->os_seqno); |
|---|
| 336 | | - out += snprintf(buf + out, len - out, " Last Scan: "); |
|---|
| 323 | + out += scnprintf(buf + out, len - out, " Last Scan: "); |
|---|
| 337 | 324 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE) |
|---|
| 338 | | - out += snprintf(buf + out, len - out, "Disabled\n"); |
|---|
| 325 | + out += scnprintf(buf + out, len - out, "Disabled\n"); |
|---|
| 339 | 326 | else |
|---|
| 340 | | - out += snprintf(buf + out, len - out, "%lu seconds ago\n", |
|---|
| 327 | + out += scnprintf(buf + out, len - out, "%lu seconds ago\n", |
|---|
| 341 | 328 | (unsigned long)(ktime_get_seconds() - os->os_scantime)); |
|---|
| 342 | 329 | |
|---|
| 343 | | - out += snprintf(buf + out, len - out, "%10s => %3s %10s\n", |
|---|
| 330 | + out += scnprintf(buf + out, len - out, "%10s => %3s %10s\n", |
|---|
| 344 | 331 | "Slots", "Num", "RecoGen"); |
|---|
| 345 | 332 | for (i = 0; i < osb->max_slots; ++i) { |
|---|
| 346 | | - out += snprintf(buf + out, len - out, |
|---|
| 333 | + out += scnprintf(buf + out, len - out, |
|---|
| 347 | 334 | "%10s %c %3d %10d\n", |
|---|
| 348 | 335 | " ", |
|---|
| 349 | 336 | (i == osb->slot_num ? '*' : ' '), |
|---|
| .. | .. |
|---|
| 575 | 562 | return &oi->vfs_inode; |
|---|
| 576 | 563 | } |
|---|
| 577 | 564 | |
|---|
| 578 | | -static void ocfs2_i_callback(struct rcu_head *head) |
|---|
| 565 | +static void ocfs2_free_inode(struct inode *inode) |
|---|
| 579 | 566 | { |
|---|
| 580 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 581 | 567 | kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode)); |
|---|
| 582 | | -} |
|---|
| 583 | | - |
|---|
| 584 | | -static void ocfs2_destroy_inode(struct inode *inode) |
|---|
| 585 | | -{ |
|---|
| 586 | | - call_rcu(&inode->i_rcu, ocfs2_i_callback); |
|---|
| 587 | 568 | } |
|---|
| 588 | 569 | |
|---|
| 589 | 570 | static unsigned long long ocfs2_max_file_offset(unsigned int bbits, |
|---|
| .. | .. |
|---|
| 600 | 581 | */ |
|---|
| 601 | 582 | |
|---|
| 602 | 583 | #if BITS_PER_LONG == 32 |
|---|
| 603 | | -# if defined(CONFIG_LBDAF) |
|---|
| 604 | 584 | BUILD_BUG_ON(sizeof(sector_t) != 8); |
|---|
| 605 | 585 | /* |
|---|
| 606 | 586 | * We might be limited by page cache size. |
|---|
| .. | .. |
|---|
| 614 | 594 | */ |
|---|
| 615 | 595 | bitshift = 31; |
|---|
| 616 | 596 | } |
|---|
| 617 | | -# else |
|---|
| 618 | | - /* |
|---|
| 619 | | - * We are limited by the size of sector_t. Use block size, as |
|---|
| 620 | | - * that's what we expose to the VFS. |
|---|
| 621 | | - */ |
|---|
| 622 | | - bytes = 1 << bbits; |
|---|
| 623 | | - trim = 1; |
|---|
| 624 | | - bitshift = 31; |
|---|
| 625 | | -# endif |
|---|
| 626 | 597 | #endif |
|---|
| 627 | 598 | |
|---|
| 628 | 599 | /* |
|---|
| .. | .. |
|---|
| 956 | 927 | status = -ENOENT; |
|---|
| 957 | 928 | goto out_quota_off; |
|---|
| 958 | 929 | } |
|---|
| 959 | | - status = dquot_enable(inode[type], type, QFMT_OCFS2, |
|---|
| 960 | | - DQUOT_USAGE_ENABLED); |
|---|
| 930 | + status = dquot_load_quota_inode(inode[type], type, QFMT_OCFS2, |
|---|
| 931 | + DQUOT_USAGE_ENABLED); |
|---|
| 961 | 932 | if (status < 0) |
|---|
| 962 | 933 | goto out_quota_off; |
|---|
| 963 | 934 | } |
|---|
| .. | .. |
|---|
| 985 | 956 | for (type = 0; type < OCFS2_MAXQUOTAS; type++) { |
|---|
| 986 | 957 | if (!sb_has_quota_loaded(sb, type)) |
|---|
| 987 | 958 | continue; |
|---|
| 988 | | - oinfo = sb_dqinfo(sb, type)->dqi_priv; |
|---|
| 989 | | - cancel_delayed_work_sync(&oinfo->dqi_sync_work); |
|---|
| 959 | + if (!sb_has_quota_suspended(sb, type)) { |
|---|
| 960 | + oinfo = sb_dqinfo(sb, type)->dqi_priv; |
|---|
| 961 | + cancel_delayed_work_sync(&oinfo->dqi_sync_work); |
|---|
| 962 | + } |
|---|
| 990 | 963 | inode = igrab(sb->s_dquot.files[type]); |
|---|
| 991 | 964 | /* Turn off quotas. This will remove all dquot structures from |
|---|
| 992 | 965 | * memory and so they will be automatically synced to global |
|---|
| .. | .. |
|---|
| 1014 | 987 | |
|---|
| 1015 | 988 | if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) { |
|---|
| 1016 | 989 | status = -EINVAL; |
|---|
| 1017 | | - goto read_super_error; |
|---|
| 990 | + goto out; |
|---|
| 1018 | 991 | } |
|---|
| 1019 | 992 | |
|---|
| 1020 | 993 | /* probe for superblock */ |
|---|
| 1021 | 994 | status = ocfs2_sb_probe(sb, &bh, §or_size, &stats); |
|---|
| 1022 | 995 | if (status < 0) { |
|---|
| 1023 | 996 | mlog(ML_ERROR, "superblock probe failed!\n"); |
|---|
| 1024 | | - goto read_super_error; |
|---|
| 997 | + goto out; |
|---|
| 1025 | 998 | } |
|---|
| 1026 | 999 | |
|---|
| 1027 | 1000 | status = ocfs2_initialize_super(sb, bh, sector_size, &stats); |
|---|
| 1028 | | - osb = OCFS2_SB(sb); |
|---|
| 1029 | | - if (status < 0) { |
|---|
| 1030 | | - mlog_errno(status); |
|---|
| 1031 | | - goto read_super_error; |
|---|
| 1032 | | - } |
|---|
| 1033 | 1001 | brelse(bh); |
|---|
| 1034 | 1002 | bh = NULL; |
|---|
| 1003 | + if (status < 0) |
|---|
| 1004 | + goto out; |
|---|
| 1005 | + |
|---|
| 1006 | + osb = OCFS2_SB(sb); |
|---|
| 1035 | 1007 | |
|---|
| 1036 | 1008 | if (!ocfs2_check_set_options(sb, &parsed_options)) { |
|---|
| 1037 | 1009 | status = -EINVAL; |
|---|
| 1038 | | - goto read_super_error; |
|---|
| 1010 | + goto out_super; |
|---|
| 1039 | 1011 | } |
|---|
| 1040 | 1012 | osb->s_mount_opt = parsed_options.mount_opt; |
|---|
| 1041 | 1013 | osb->s_atime_quantum = parsed_options.atime_quantum; |
|---|
| .. | .. |
|---|
| 1052 | 1024 | |
|---|
| 1053 | 1025 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); |
|---|
| 1054 | 1026 | if (status) |
|---|
| 1055 | | - goto read_super_error; |
|---|
| 1027 | + goto out_super; |
|---|
| 1056 | 1028 | |
|---|
| 1057 | 1029 | sb->s_magic = OCFS2_SUPER_MAGIC; |
|---|
| 1058 | 1030 | |
|---|
| .. | .. |
|---|
| 1066 | 1038 | status = -EACCES; |
|---|
| 1067 | 1039 | mlog(ML_ERROR, "Readonly device detected but readonly " |
|---|
| 1068 | 1040 | "mount was not specified.\n"); |
|---|
| 1069 | | - goto read_super_error; |
|---|
| 1041 | + goto out_super; |
|---|
| 1070 | 1042 | } |
|---|
| 1071 | 1043 | |
|---|
| 1072 | 1044 | /* You should not be able to start a local heartbeat |
|---|
| .. | .. |
|---|
| 1075 | 1047 | status = -EROFS; |
|---|
| 1076 | 1048 | mlog(ML_ERROR, "Local heartbeat specified on readonly " |
|---|
| 1077 | 1049 | "device.\n"); |
|---|
| 1078 | | - goto read_super_error; |
|---|
| 1050 | + goto out_super; |
|---|
| 1079 | 1051 | } |
|---|
| 1080 | 1052 | |
|---|
| 1081 | 1053 | status = ocfs2_check_journals_nolocks(osb); |
|---|
| .. | .. |
|---|
| 1084 | 1056 | mlog(ML_ERROR, "Recovery required on readonly " |
|---|
| 1085 | 1057 | "file system, but write access is " |
|---|
| 1086 | 1058 | "unavailable.\n"); |
|---|
| 1087 | | - else |
|---|
| 1088 | | - mlog_errno(status); |
|---|
| 1089 | | - goto read_super_error; |
|---|
| 1059 | + goto out_super; |
|---|
| 1090 | 1060 | } |
|---|
| 1091 | 1061 | |
|---|
| 1092 | 1062 | ocfs2_set_ro_flag(osb, 1); |
|---|
| .. | .. |
|---|
| 1102 | 1072 | } |
|---|
| 1103 | 1073 | |
|---|
| 1104 | 1074 | status = ocfs2_verify_heartbeat(osb); |
|---|
| 1105 | | - if (status < 0) { |
|---|
| 1106 | | - mlog_errno(status); |
|---|
| 1107 | | - goto read_super_error; |
|---|
| 1108 | | - } |
|---|
| 1075 | + if (status < 0) |
|---|
| 1076 | + goto out_super; |
|---|
| 1109 | 1077 | |
|---|
| 1110 | 1078 | osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, |
|---|
| 1111 | 1079 | ocfs2_debugfs_root); |
|---|
| 1112 | | - if (!osb->osb_debug_root) { |
|---|
| 1113 | | - status = -EINVAL; |
|---|
| 1114 | | - mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n"); |
|---|
| 1115 | | - goto read_super_error; |
|---|
| 1116 | | - } |
|---|
| 1117 | 1080 | |
|---|
| 1118 | | - osb->osb_ctxt = debugfs_create_file("fs_state", S_IFREG|S_IRUSR, |
|---|
| 1119 | | - osb->osb_debug_root, |
|---|
| 1120 | | - osb, |
|---|
| 1121 | | - &ocfs2_osb_debug_fops); |
|---|
| 1122 | | - if (!osb->osb_ctxt) { |
|---|
| 1123 | | - status = -EINVAL; |
|---|
| 1124 | | - mlog_errno(status); |
|---|
| 1125 | | - goto read_super_error; |
|---|
| 1126 | | - } |
|---|
| 1081 | + debugfs_create_file("fs_state", S_IFREG|S_IRUSR, osb->osb_debug_root, |
|---|
| 1082 | + osb, &ocfs2_osb_debug_fops); |
|---|
| 1127 | 1083 | |
|---|
| 1128 | | - if (ocfs2_meta_ecc(osb)) { |
|---|
| 1129 | | - status = ocfs2_blockcheck_stats_debugfs_install( |
|---|
| 1130 | | - &osb->osb_ecc_stats, |
|---|
| 1131 | | - osb->osb_debug_root); |
|---|
| 1132 | | - if (status) { |
|---|
| 1133 | | - mlog(ML_ERROR, |
|---|
| 1134 | | - "Unable to create blockcheck statistics " |
|---|
| 1135 | | - "files\n"); |
|---|
| 1136 | | - goto read_super_error; |
|---|
| 1137 | | - } |
|---|
| 1138 | | - } |
|---|
| 1084 | + if (ocfs2_meta_ecc(osb)) |
|---|
| 1085 | + ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats, |
|---|
| 1086 | + osb->osb_debug_root); |
|---|
| 1139 | 1087 | |
|---|
| 1140 | 1088 | status = ocfs2_mount_volume(sb); |
|---|
| 1141 | 1089 | if (status < 0) |
|---|
| 1142 | | - goto read_super_error; |
|---|
| 1090 | + goto out_debugfs; |
|---|
| 1143 | 1091 | |
|---|
| 1144 | 1092 | if (osb->root_inode) |
|---|
| 1145 | 1093 | inode = igrab(osb->root_inode); |
|---|
| 1146 | 1094 | |
|---|
| 1147 | 1095 | if (!inode) { |
|---|
| 1148 | 1096 | status = -EIO; |
|---|
| 1149 | | - mlog_errno(status); |
|---|
| 1150 | | - goto read_super_error; |
|---|
| 1097 | + goto out_dismount; |
|---|
| 1151 | 1098 | } |
|---|
| 1152 | | - |
|---|
| 1153 | | - root = d_make_root(inode); |
|---|
| 1154 | | - if (!root) { |
|---|
| 1155 | | - status = -ENOMEM; |
|---|
| 1156 | | - mlog_errno(status); |
|---|
| 1157 | | - goto read_super_error; |
|---|
| 1158 | | - } |
|---|
| 1159 | | - |
|---|
| 1160 | | - sb->s_root = root; |
|---|
| 1161 | | - |
|---|
| 1162 | | - ocfs2_complete_mount_recovery(osb); |
|---|
| 1163 | 1099 | |
|---|
| 1164 | 1100 | osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL, |
|---|
| 1165 | 1101 | &ocfs2_kset->kobj); |
|---|
| 1166 | 1102 | if (!osb->osb_dev_kset) { |
|---|
| 1167 | 1103 | status = -ENOMEM; |
|---|
| 1168 | 1104 | mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id); |
|---|
| 1169 | | - goto read_super_error; |
|---|
| 1105 | + goto out_dismount; |
|---|
| 1170 | 1106 | } |
|---|
| 1171 | 1107 | |
|---|
| 1172 | 1108 | /* Create filecheck sysfs related directories/files at |
|---|
| .. | .. |
|---|
| 1175 | 1111 | status = -ENOMEM; |
|---|
| 1176 | 1112 | mlog(ML_ERROR, "Unable to create filecheck sysfs directory at " |
|---|
| 1177 | 1113 | "/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id); |
|---|
| 1178 | | - goto read_super_error; |
|---|
| 1114 | + goto out_dismount; |
|---|
| 1179 | 1115 | } |
|---|
| 1116 | + |
|---|
| 1117 | + root = d_make_root(inode); |
|---|
| 1118 | + if (!root) { |
|---|
| 1119 | + status = -ENOMEM; |
|---|
| 1120 | + goto out_dismount; |
|---|
| 1121 | + } |
|---|
| 1122 | + |
|---|
| 1123 | + sb->s_root = root; |
|---|
| 1124 | + |
|---|
| 1125 | + ocfs2_complete_mount_recovery(osb); |
|---|
| 1180 | 1126 | |
|---|
| 1181 | 1127 | if (ocfs2_mount_local(osb)) |
|---|
| 1182 | 1128 | snprintf(nodestr, sizeof(nodestr), "local"); |
|---|
| .. | .. |
|---|
| 1218 | 1164 | |
|---|
| 1219 | 1165 | return status; |
|---|
| 1220 | 1166 | |
|---|
| 1221 | | -read_super_error: |
|---|
| 1222 | | - brelse(bh); |
|---|
| 1167 | +out_dismount: |
|---|
| 1168 | + atomic_set(&osb->vol_state, VOLUME_DISABLED); |
|---|
| 1169 | + wake_up(&osb->osb_mount_event); |
|---|
| 1170 | + ocfs2_free_replay_slots(osb); |
|---|
| 1171 | + ocfs2_dismount_volume(sb, 1); |
|---|
| 1172 | + goto out; |
|---|
| 1223 | 1173 | |
|---|
| 1224 | | - if (status) |
|---|
| 1225 | | - mlog_errno(status); |
|---|
| 1226 | | - |
|---|
| 1227 | | - if (osb) { |
|---|
| 1228 | | - atomic_set(&osb->vol_state, VOLUME_DISABLED); |
|---|
| 1229 | | - wake_up(&osb->osb_mount_event); |
|---|
| 1230 | | - ocfs2_dismount_volume(sb, 1); |
|---|
| 1231 | | - } |
|---|
| 1174 | +out_debugfs: |
|---|
| 1175 | + debugfs_remove_recursive(osb->osb_debug_root); |
|---|
| 1176 | +out_super: |
|---|
| 1177 | + ocfs2_release_system_inodes(osb); |
|---|
| 1178 | + kfree(osb->recovery_map); |
|---|
| 1179 | + ocfs2_delete_osb(osb); |
|---|
| 1180 | + kfree(osb); |
|---|
| 1181 | +out: |
|---|
| 1182 | + mlog_errno(status); |
|---|
| 1232 | 1183 | |
|---|
| 1233 | 1184 | return status; |
|---|
| 1234 | 1185 | } |
|---|
| .. | .. |
|---|
| 1622 | 1573 | goto out2; |
|---|
| 1623 | 1574 | |
|---|
| 1624 | 1575 | ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL); |
|---|
| 1625 | | - if (!ocfs2_debugfs_root) { |
|---|
| 1626 | | - status = -ENOMEM; |
|---|
| 1627 | | - mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n"); |
|---|
| 1628 | | - goto out3; |
|---|
| 1629 | | - } |
|---|
| 1630 | 1576 | |
|---|
| 1631 | 1577 | ocfs2_set_locking_protocol(); |
|---|
| 1632 | 1578 | |
|---|
| .. | .. |
|---|
| 1842 | 1788 | static int ocfs2_mount_volume(struct super_block *sb) |
|---|
| 1843 | 1789 | { |
|---|
| 1844 | 1790 | int status = 0; |
|---|
| 1845 | | - int unlock_super = 0; |
|---|
| 1846 | 1791 | struct ocfs2_super *osb = OCFS2_SB(sb); |
|---|
| 1847 | 1792 | |
|---|
| 1848 | 1793 | if (ocfs2_is_hard_readonly(osb)) |
|---|
| 1849 | | - goto leave; |
|---|
| 1794 | + goto out; |
|---|
| 1795 | + |
|---|
| 1796 | + mutex_init(&osb->obs_trim_fs_mutex); |
|---|
| 1850 | 1797 | |
|---|
| 1851 | 1798 | status = ocfs2_dlm_init(osb); |
|---|
| 1852 | 1799 | if (status < 0) { |
|---|
| .. | .. |
|---|
| 1854 | 1801 | if (status == -EBADR && ocfs2_userspace_stack(osb)) |
|---|
| 1855 | 1802 | mlog(ML_ERROR, "couldn't mount because cluster name on" |
|---|
| 1856 | 1803 | " disk does not match the running cluster name.\n"); |
|---|
| 1857 | | - goto leave; |
|---|
| 1804 | + goto out; |
|---|
| 1858 | 1805 | } |
|---|
| 1859 | 1806 | |
|---|
| 1860 | 1807 | status = ocfs2_super_lock(osb, 1); |
|---|
| 1861 | 1808 | if (status < 0) { |
|---|
| 1862 | 1809 | mlog_errno(status); |
|---|
| 1863 | | - goto leave; |
|---|
| 1810 | + goto out_dlm; |
|---|
| 1864 | 1811 | } |
|---|
| 1865 | | - unlock_super = 1; |
|---|
| 1866 | 1812 | |
|---|
| 1867 | 1813 | /* This will load up the node map and add ourselves to it. */ |
|---|
| 1868 | 1814 | status = ocfs2_find_slot(osb); |
|---|
| 1869 | 1815 | if (status < 0) { |
|---|
| 1870 | 1816 | mlog_errno(status); |
|---|
| 1871 | | - goto leave; |
|---|
| 1817 | + goto out_super_lock; |
|---|
| 1872 | 1818 | } |
|---|
| 1873 | 1819 | |
|---|
| 1874 | 1820 | /* load all node-local system inodes */ |
|---|
| 1875 | 1821 | status = ocfs2_init_local_system_inodes(osb); |
|---|
| 1876 | 1822 | if (status < 0) { |
|---|
| 1877 | 1823 | mlog_errno(status); |
|---|
| 1878 | | - goto leave; |
|---|
| 1824 | + goto out_super_lock; |
|---|
| 1879 | 1825 | } |
|---|
| 1880 | 1826 | |
|---|
| 1881 | 1827 | status = ocfs2_check_volume(osb); |
|---|
| 1882 | 1828 | if (status < 0) { |
|---|
| 1883 | 1829 | mlog_errno(status); |
|---|
| 1884 | | - goto leave; |
|---|
| 1830 | + goto out_system_inodes; |
|---|
| 1885 | 1831 | } |
|---|
| 1886 | 1832 | |
|---|
| 1887 | 1833 | status = ocfs2_truncate_log_init(osb); |
|---|
| 1888 | | - if (status < 0) |
|---|
| 1834 | + if (status < 0) { |
|---|
| 1889 | 1835 | mlog_errno(status); |
|---|
| 1836 | + goto out_check_volume; |
|---|
| 1837 | + } |
|---|
| 1890 | 1838 | |
|---|
| 1891 | | -leave: |
|---|
| 1892 | | - if (unlock_super) |
|---|
| 1893 | | - ocfs2_super_unlock(osb, 1); |
|---|
| 1839 | + ocfs2_super_unlock(osb, 1); |
|---|
| 1840 | + return 0; |
|---|
| 1894 | 1841 | |
|---|
| 1842 | +out_check_volume: |
|---|
| 1843 | + ocfs2_free_replay_slots(osb); |
|---|
| 1844 | +out_system_inodes: |
|---|
| 1845 | + if (osb->local_alloc_state == OCFS2_LA_ENABLED) |
|---|
| 1846 | + ocfs2_shutdown_local_alloc(osb); |
|---|
| 1847 | + ocfs2_release_system_inodes(osb); |
|---|
| 1848 | + /* before journal shutdown, we should release slot_info */ |
|---|
| 1849 | + ocfs2_free_slot_info(osb); |
|---|
| 1850 | + ocfs2_journal_shutdown(osb); |
|---|
| 1851 | +out_super_lock: |
|---|
| 1852 | + ocfs2_super_unlock(osb, 1); |
|---|
| 1853 | +out_dlm: |
|---|
| 1854 | + ocfs2_dlm_shutdown(osb, 0); |
|---|
| 1855 | +out: |
|---|
| 1895 | 1856 | return status; |
|---|
| 1896 | 1857 | } |
|---|
| 1897 | 1858 | |
|---|
| .. | .. |
|---|
| 1912 | 1873 | ocfs2_filecheck_remove_sysfs(osb); |
|---|
| 1913 | 1874 | |
|---|
| 1914 | 1875 | kset_unregister(osb->osb_dev_kset); |
|---|
| 1915 | | - |
|---|
| 1916 | | - debugfs_remove(osb->osb_ctxt); |
|---|
| 1917 | 1876 | |
|---|
| 1918 | 1877 | /* Orphan scan should be stopped as early as possible */ |
|---|
| 1919 | 1878 | ocfs2_orphan_scan_stop(osb); |
|---|
| .. | .. |
|---|
| 1966 | 1925 | !ocfs2_is_hard_readonly(osb)) |
|---|
| 1967 | 1926 | hangup_needed = 1; |
|---|
| 1968 | 1927 | |
|---|
| 1969 | | - if (osb->cconn) |
|---|
| 1970 | | - ocfs2_dlm_shutdown(osb, hangup_needed); |
|---|
| 1928 | + ocfs2_dlm_shutdown(osb, hangup_needed); |
|---|
| 1971 | 1929 | |
|---|
| 1972 | 1930 | ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats); |
|---|
| 1973 | | - debugfs_remove(osb->osb_debug_root); |
|---|
| 1931 | + debugfs_remove_recursive(osb->osb_debug_root); |
|---|
| 1974 | 1932 | |
|---|
| 1975 | 1933 | if (hangup_needed) |
|---|
| 1976 | 1934 | ocfs2_cluster_hangup(osb->uuid_str, strlen(osb->uuid_str)); |
|---|