diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 00b8f37cc306..bf71071ab6f6 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -97,15 +97,6 @@ const char *btrfs_decode_error(int errno) | |||
97 | return errstr; | 97 | return errstr; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void save_error_info(struct btrfs_fs_info *fs_info) | ||
101 | { | ||
102 | /* | ||
103 | * today we only save the error info into ram. Long term we'll | ||
104 | * also send it down to the disk | ||
105 | */ | ||
106 | set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state); | ||
107 | } | ||
108 | |||
109 | /* btrfs handle error by forcing the filesystem readonly */ | 100 | /* btrfs handle error by forcing the filesystem readonly */ |
110 | static void btrfs_handle_error(struct btrfs_fs_info *fs_info) | 101 | static void btrfs_handle_error(struct btrfs_fs_info *fs_info) |
111 | { | 102 | { |
@@ -131,11 +122,11 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) | |||
131 | } | 122 | } |
132 | 123 | ||
133 | /* | 124 | /* |
134 | * __btrfs_std_error decodes expected errors from the caller and | 125 | * __btrfs_handle_fs_error decodes expected errors from the caller and |
135 | * invokes the approciate error response. | 126 | * invokes the approciate error response. |
136 | */ | 127 | */ |
137 | __cold | 128 | __cold |
138 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | 129 | void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function, |
139 | unsigned int line, int errno, const char *fmt, ...) | 130 | unsigned int line, int errno, const char *fmt, ...) |
140 | { | 131 | { |
141 | struct super_block *sb = fs_info->sb; | 132 | struct super_block *sb = fs_info->sb; |
@@ -170,8 +161,13 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
170 | } | 161 | } |
171 | #endif | 162 | #endif |
172 | 163 | ||
164 | /* | ||
165 | * Today we only save the error info to memory. Long term we'll | ||
166 | * also send it down to the disk | ||
167 | */ | ||
168 | set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state); | ||
169 | |||
173 | /* Don't go through full error handling during mount */ | 170 | /* Don't go through full error handling during mount */ |
174 | save_error_info(fs_info); | ||
175 | if (sb->s_flags & MS_BORN) | 171 | if (sb->s_flags & MS_BORN) |
176 | btrfs_handle_error(fs_info); | 172 | btrfs_handle_error(fs_info); |
177 | } | 173 | } |
@@ -252,7 +248,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, | |||
252 | /* Wake up anybody who may be waiting on this transaction */ | 248 | /* Wake up anybody who may be waiting on this transaction */ |
253 | wake_up(&root->fs_info->transaction_wait); | 249 | wake_up(&root->fs_info->transaction_wait); |
254 | wake_up(&root->fs_info->transaction_blocked_wait); | 250 | wake_up(&root->fs_info->transaction_blocked_wait); |
255 | __btrfs_std_error(root->fs_info, function, line, errno, NULL); | 251 | __btrfs_handle_fs_error(root->fs_info, function, line, errno, NULL); |
256 | } | 252 | } |
257 | /* | 253 | /* |
258 | * __btrfs_panic decodes unexpected, fatal errors from the caller, | 254 | * __btrfs_panic decodes unexpected, fatal errors from the caller, |
@@ -1160,7 +1156,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
1160 | return 0; | 1156 | return 0; |
1161 | } | 1157 | } |
1162 | 1158 | ||
1163 | btrfs_wait_ordered_roots(fs_info, -1); | 1159 | btrfs_wait_ordered_roots(fs_info, -1, 0, (u64)-1); |
1164 | 1160 | ||
1165 | trans = btrfs_attach_transaction_barrier(root); | 1161 | trans = btrfs_attach_transaction_barrier(root); |
1166 | if (IS_ERR(trans)) { | 1162 | if (IS_ERR(trans)) { |
@@ -1488,10 +1484,10 @@ static int setup_security_options(struct btrfs_fs_info *fs_info, | |||
1488 | memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts)); | 1484 | memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts)); |
1489 | } else { | 1485 | } else { |
1490 | /* | 1486 | /* |
1491 | * Since SELinux(the only one supports security_mnt_opts) does | 1487 | * Since SELinux (the only one supporting security_mnt_opts) |
1492 | * NOT support changing context during remount/mount same sb, | 1488 | * does NOT support changing context during remount/mount of |
1493 | * This must be the same or part of the same security options, | 1489 | * the same sb, this must be the same or part of the same |
1494 | * just free it. | 1490 | * security options, just free it. |
1495 | */ | 1491 | */ |
1496 | security_free_mnt_opts(sec_opts); | 1492 | security_free_mnt_opts(sec_opts); |
1497 | } | 1493 | } |
@@ -1669,8 +1665,8 @@ static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, | |||
1669 | unsigned long old_opts) | 1665 | unsigned long old_opts) |
1670 | { | 1666 | { |
1671 | /* | 1667 | /* |
1672 | * We need cleanup all defragable inodes if the autodefragment is | 1668 | * We need to cleanup all defragable inodes if the autodefragment is |
1673 | * close or the fs is R/O. | 1669 | * close or the filesystem is read only. |
1674 | */ | 1670 | */ |
1675 | if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && | 1671 | if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && |
1676 | (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || | 1672 | (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || |
@@ -2051,9 +2047,10 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2051 | struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; | 2047 | struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; |
2052 | int ret; | 2048 | int ret; |
2053 | u64 thresh = 0; | 2049 | u64 thresh = 0; |
2050 | int mixed = 0; | ||
2054 | 2051 | ||
2055 | /* | 2052 | /* |
2056 | * holding chunk_muext to avoid allocating new chunks, holding | 2053 | * holding chunk_mutex to avoid allocating new chunks, holding |
2057 | * device_list_mutex to avoid the device being removed | 2054 | * device_list_mutex to avoid the device being removed |
2058 | */ | 2055 | */ |
2059 | rcu_read_lock(); | 2056 | rcu_read_lock(); |
@@ -2076,8 +2073,17 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2076 | } | 2073 | } |
2077 | } | 2074 | } |
2078 | } | 2075 | } |
2079 | if (found->flags & BTRFS_BLOCK_GROUP_METADATA) | 2076 | |
2080 | total_free_meta += found->disk_total - found->disk_used; | 2077 | /* |
2078 | * Metadata in mixed block goup profiles are accounted in data | ||
2079 | */ | ||
2080 | if (!mixed && found->flags & BTRFS_BLOCK_GROUP_METADATA) { | ||
2081 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) | ||
2082 | mixed = 1; | ||
2083 | else | ||
2084 | total_free_meta += found->disk_total - | ||
2085 | found->disk_used; | ||
2086 | } | ||
2081 | 2087 | ||
2082 | total_used += found->disk_used; | 2088 | total_used += found->disk_used; |
2083 | } | 2089 | } |
@@ -2090,7 +2096,11 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2090 | 2096 | ||
2091 | /* Account global block reserve as used, it's in logical size already */ | 2097 | /* Account global block reserve as used, it's in logical size already */ |
2092 | spin_lock(&block_rsv->lock); | 2098 | spin_lock(&block_rsv->lock); |
2093 | buf->f_bfree -= block_rsv->size >> bits; | 2099 | /* Mixed block groups accounting is not byte-accurate, avoid overflow */ |
2100 | if (buf->f_bfree >= block_rsv->size >> bits) | ||
2101 | buf->f_bfree -= block_rsv->size >> bits; | ||
2102 | else | ||
2103 | buf->f_bfree = 0; | ||
2094 | spin_unlock(&block_rsv->lock); | 2104 | spin_unlock(&block_rsv->lock); |
2095 | 2105 | ||
2096 | buf->f_bavail = div_u64(total_free_data, factor); | 2106 | buf->f_bavail = div_u64(total_free_data, factor); |
@@ -2115,7 +2125,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2115 | */ | 2125 | */ |
2116 | thresh = 4 * 1024 * 1024; | 2126 | thresh = 4 * 1024 * 1024; |
2117 | 2127 | ||
2118 | if (total_free_meta - thresh < block_rsv->size) | 2128 | if (!mixed && total_free_meta - thresh < block_rsv->size) |
2119 | buf->f_bavail = 0; | 2129 | buf->f_bavail = 0; |
2120 | 2130 | ||
2121 | buf->f_type = BTRFS_SUPER_MAGIC; | 2131 | buf->f_type = BTRFS_SUPER_MAGIC; |