| .. | .. |
|---|
| 956 | 956 | for (type = 0; type < OCFS2_MAXQUOTAS; type++) { |
|---|
| 957 | 957 | if (!sb_has_quota_loaded(sb, type)) |
|---|
| 958 | 958 | continue; |
|---|
| 959 | | - oinfo = sb_dqinfo(sb, type)->dqi_priv; |
|---|
| 960 | | - 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 | + } |
|---|
| 961 | 963 | inode = igrab(sb->s_dquot.files[type]); |
|---|
| 962 | 964 | /* Turn off quotas. This will remove all dquot structures from |
|---|
| 963 | 965 | * memory and so they will be automatically synced to global |
|---|
| .. | .. |
|---|
| 985 | 987 | |
|---|
| 986 | 988 | if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) { |
|---|
| 987 | 989 | status = -EINVAL; |
|---|
| 988 | | - goto read_super_error; |
|---|
| 990 | + goto out; |
|---|
| 989 | 991 | } |
|---|
| 990 | 992 | |
|---|
| 991 | 993 | /* probe for superblock */ |
|---|
| 992 | 994 | status = ocfs2_sb_probe(sb, &bh, §or_size, &stats); |
|---|
| 993 | 995 | if (status < 0) { |
|---|
| 994 | 996 | mlog(ML_ERROR, "superblock probe failed!\n"); |
|---|
| 995 | | - goto read_super_error; |
|---|
| 997 | + goto out; |
|---|
| 996 | 998 | } |
|---|
| 997 | 999 | |
|---|
| 998 | 1000 | status = ocfs2_initialize_super(sb, bh, sector_size, &stats); |
|---|
| 999 | | - osb = OCFS2_SB(sb); |
|---|
| 1000 | | - if (status < 0) { |
|---|
| 1001 | | - mlog_errno(status); |
|---|
| 1002 | | - goto read_super_error; |
|---|
| 1003 | | - } |
|---|
| 1004 | 1001 | brelse(bh); |
|---|
| 1005 | 1002 | bh = NULL; |
|---|
| 1003 | + if (status < 0) |
|---|
| 1004 | + goto out; |
|---|
| 1005 | + |
|---|
| 1006 | + osb = OCFS2_SB(sb); |
|---|
| 1006 | 1007 | |
|---|
| 1007 | 1008 | if (!ocfs2_check_set_options(sb, &parsed_options)) { |
|---|
| 1008 | 1009 | status = -EINVAL; |
|---|
| 1009 | | - goto read_super_error; |
|---|
| 1010 | + goto out_super; |
|---|
| 1010 | 1011 | } |
|---|
| 1011 | 1012 | osb->s_mount_opt = parsed_options.mount_opt; |
|---|
| 1012 | 1013 | osb->s_atime_quantum = parsed_options.atime_quantum; |
|---|
| .. | .. |
|---|
| 1023 | 1024 | |
|---|
| 1024 | 1025 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); |
|---|
| 1025 | 1026 | if (status) |
|---|
| 1026 | | - goto read_super_error; |
|---|
| 1027 | + goto out_super; |
|---|
| 1027 | 1028 | |
|---|
| 1028 | 1029 | sb->s_magic = OCFS2_SUPER_MAGIC; |
|---|
| 1029 | 1030 | |
|---|
| .. | .. |
|---|
| 1037 | 1038 | status = -EACCES; |
|---|
| 1038 | 1039 | mlog(ML_ERROR, "Readonly device detected but readonly " |
|---|
| 1039 | 1040 | "mount was not specified.\n"); |
|---|
| 1040 | | - goto read_super_error; |
|---|
| 1041 | + goto out_super; |
|---|
| 1041 | 1042 | } |
|---|
| 1042 | 1043 | |
|---|
| 1043 | 1044 | /* You should not be able to start a local heartbeat |
|---|
| .. | .. |
|---|
| 1046 | 1047 | status = -EROFS; |
|---|
| 1047 | 1048 | mlog(ML_ERROR, "Local heartbeat specified on readonly " |
|---|
| 1048 | 1049 | "device.\n"); |
|---|
| 1049 | | - goto read_super_error; |
|---|
| 1050 | + goto out_super; |
|---|
| 1050 | 1051 | } |
|---|
| 1051 | 1052 | |
|---|
| 1052 | 1053 | status = ocfs2_check_journals_nolocks(osb); |
|---|
| .. | .. |
|---|
| 1055 | 1056 | mlog(ML_ERROR, "Recovery required on readonly " |
|---|
| 1056 | 1057 | "file system, but write access is " |
|---|
| 1057 | 1058 | "unavailable.\n"); |
|---|
| 1058 | | - else |
|---|
| 1059 | | - mlog_errno(status); |
|---|
| 1060 | | - goto read_super_error; |
|---|
| 1059 | + goto out_super; |
|---|
| 1061 | 1060 | } |
|---|
| 1062 | 1061 | |
|---|
| 1063 | 1062 | ocfs2_set_ro_flag(osb, 1); |
|---|
| .. | .. |
|---|
| 1073 | 1072 | } |
|---|
| 1074 | 1073 | |
|---|
| 1075 | 1074 | status = ocfs2_verify_heartbeat(osb); |
|---|
| 1076 | | - if (status < 0) { |
|---|
| 1077 | | - mlog_errno(status); |
|---|
| 1078 | | - goto read_super_error; |
|---|
| 1079 | | - } |
|---|
| 1075 | + if (status < 0) |
|---|
| 1076 | + goto out_super; |
|---|
| 1080 | 1077 | |
|---|
| 1081 | 1078 | osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, |
|---|
| 1082 | 1079 | ocfs2_debugfs_root); |
|---|
| .. | .. |
|---|
| 1090 | 1087 | |
|---|
| 1091 | 1088 | status = ocfs2_mount_volume(sb); |
|---|
| 1092 | 1089 | if (status < 0) |
|---|
| 1093 | | - goto read_super_error; |
|---|
| 1090 | + goto out_debugfs; |
|---|
| 1094 | 1091 | |
|---|
| 1095 | 1092 | if (osb->root_inode) |
|---|
| 1096 | 1093 | inode = igrab(osb->root_inode); |
|---|
| 1097 | 1094 | |
|---|
| 1098 | 1095 | if (!inode) { |
|---|
| 1099 | 1096 | status = -EIO; |
|---|
| 1100 | | - mlog_errno(status); |
|---|
| 1101 | | - goto read_super_error; |
|---|
| 1097 | + goto out_dismount; |
|---|
| 1102 | 1098 | } |
|---|
| 1103 | 1099 | |
|---|
| 1104 | 1100 | osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL, |
|---|
| .. | .. |
|---|
| 1106 | 1102 | if (!osb->osb_dev_kset) { |
|---|
| 1107 | 1103 | status = -ENOMEM; |
|---|
| 1108 | 1104 | mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id); |
|---|
| 1109 | | - goto read_super_error; |
|---|
| 1105 | + goto out_dismount; |
|---|
| 1110 | 1106 | } |
|---|
| 1111 | 1107 | |
|---|
| 1112 | 1108 | /* Create filecheck sysfs related directories/files at |
|---|
| .. | .. |
|---|
| 1115 | 1111 | status = -ENOMEM; |
|---|
| 1116 | 1112 | mlog(ML_ERROR, "Unable to create filecheck sysfs directory at " |
|---|
| 1117 | 1113 | "/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id); |
|---|
| 1118 | | - goto read_super_error; |
|---|
| 1114 | + goto out_dismount; |
|---|
| 1119 | 1115 | } |
|---|
| 1120 | 1116 | |
|---|
| 1121 | 1117 | root = d_make_root(inode); |
|---|
| 1122 | 1118 | if (!root) { |
|---|
| 1123 | 1119 | status = -ENOMEM; |
|---|
| 1124 | | - mlog_errno(status); |
|---|
| 1125 | | - goto read_super_error; |
|---|
| 1120 | + goto out_dismount; |
|---|
| 1126 | 1121 | } |
|---|
| 1127 | 1122 | |
|---|
| 1128 | 1123 | sb->s_root = root; |
|---|
| .. | .. |
|---|
| 1169 | 1164 | |
|---|
| 1170 | 1165 | return status; |
|---|
| 1171 | 1166 | |
|---|
| 1172 | | -read_super_error: |
|---|
| 1173 | | - 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; |
|---|
| 1174 | 1173 | |
|---|
| 1175 | | - if (status) |
|---|
| 1176 | | - mlog_errno(status); |
|---|
| 1177 | | - |
|---|
| 1178 | | - if (osb) { |
|---|
| 1179 | | - atomic_set(&osb->vol_state, VOLUME_DISABLED); |
|---|
| 1180 | | - wake_up(&osb->osb_mount_event); |
|---|
| 1181 | | - ocfs2_dismount_volume(sb, 1); |
|---|
| 1182 | | - } |
|---|
| 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); |
|---|
| 1183 | 1183 | |
|---|
| 1184 | 1184 | return status; |
|---|
| 1185 | 1185 | } |
|---|
| .. | .. |
|---|
| 1788 | 1788 | static int ocfs2_mount_volume(struct super_block *sb) |
|---|
| 1789 | 1789 | { |
|---|
| 1790 | 1790 | int status = 0; |
|---|
| 1791 | | - int unlock_super = 0; |
|---|
| 1792 | 1791 | struct ocfs2_super *osb = OCFS2_SB(sb); |
|---|
| 1793 | 1792 | |
|---|
| 1794 | 1793 | if (ocfs2_is_hard_readonly(osb)) |
|---|
| 1795 | | - goto leave; |
|---|
| 1794 | + goto out; |
|---|
| 1796 | 1795 | |
|---|
| 1797 | 1796 | mutex_init(&osb->obs_trim_fs_mutex); |
|---|
| 1798 | 1797 | |
|---|
| .. | .. |
|---|
| 1802 | 1801 | if (status == -EBADR && ocfs2_userspace_stack(osb)) |
|---|
| 1803 | 1802 | mlog(ML_ERROR, "couldn't mount because cluster name on" |
|---|
| 1804 | 1803 | " disk does not match the running cluster name.\n"); |
|---|
| 1805 | | - goto leave; |
|---|
| 1804 | + goto out; |
|---|
| 1806 | 1805 | } |
|---|
| 1807 | 1806 | |
|---|
| 1808 | 1807 | status = ocfs2_super_lock(osb, 1); |
|---|
| 1809 | 1808 | if (status < 0) { |
|---|
| 1810 | 1809 | mlog_errno(status); |
|---|
| 1811 | | - goto leave; |
|---|
| 1810 | + goto out_dlm; |
|---|
| 1812 | 1811 | } |
|---|
| 1813 | | - unlock_super = 1; |
|---|
| 1814 | 1812 | |
|---|
| 1815 | 1813 | /* This will load up the node map and add ourselves to it. */ |
|---|
| 1816 | 1814 | status = ocfs2_find_slot(osb); |
|---|
| 1817 | 1815 | if (status < 0) { |
|---|
| 1818 | 1816 | mlog_errno(status); |
|---|
| 1819 | | - goto leave; |
|---|
| 1817 | + goto out_super_lock; |
|---|
| 1820 | 1818 | } |
|---|
| 1821 | 1819 | |
|---|
| 1822 | 1820 | /* load all node-local system inodes */ |
|---|
| 1823 | 1821 | status = ocfs2_init_local_system_inodes(osb); |
|---|
| 1824 | 1822 | if (status < 0) { |
|---|
| 1825 | 1823 | mlog_errno(status); |
|---|
| 1826 | | - goto leave; |
|---|
| 1824 | + goto out_super_lock; |
|---|
| 1827 | 1825 | } |
|---|
| 1828 | 1826 | |
|---|
| 1829 | 1827 | status = ocfs2_check_volume(osb); |
|---|
| 1830 | 1828 | if (status < 0) { |
|---|
| 1831 | 1829 | mlog_errno(status); |
|---|
| 1832 | | - goto leave; |
|---|
| 1830 | + goto out_system_inodes; |
|---|
| 1833 | 1831 | } |
|---|
| 1834 | 1832 | |
|---|
| 1835 | 1833 | status = ocfs2_truncate_log_init(osb); |
|---|
| 1836 | | - if (status < 0) |
|---|
| 1834 | + if (status < 0) { |
|---|
| 1837 | 1835 | mlog_errno(status); |
|---|
| 1836 | + goto out_check_volume; |
|---|
| 1837 | + } |
|---|
| 1838 | 1838 | |
|---|
| 1839 | | -leave: |
|---|
| 1840 | | - if (unlock_super) |
|---|
| 1841 | | - ocfs2_super_unlock(osb, 1); |
|---|
| 1839 | + ocfs2_super_unlock(osb, 1); |
|---|
| 1840 | + return 0; |
|---|
| 1842 | 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: |
|---|
| 1843 | 1856 | return status; |
|---|
| 1844 | 1857 | } |
|---|
| 1845 | 1858 | |
|---|
| .. | .. |
|---|
| 1912 | 1925 | !ocfs2_is_hard_readonly(osb)) |
|---|
| 1913 | 1926 | hangup_needed = 1; |
|---|
| 1914 | 1927 | |
|---|
| 1915 | | - if (osb->cconn) |
|---|
| 1916 | | - ocfs2_dlm_shutdown(osb, hangup_needed); |
|---|
| 1928 | + ocfs2_dlm_shutdown(osb, hangup_needed); |
|---|
| 1917 | 1929 | |
|---|
| 1918 | 1930 | ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats); |
|---|
| 1919 | 1931 | debugfs_remove_recursive(osb->osb_debug_root); |
|---|