aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c60
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
100static 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 */
110static void btrfs_handle_error(struct btrfs_fs_info *fs_info) 101static 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
138void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, 129void __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;