@@ -119,6 +119,8 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
119119 if (fs_info -> fs_state & BTRFS_SUPER_FLAG_ERROR ) {
120120 sb -> s_flags |= MS_RDONLY ;
121121 printk (KERN_INFO "btrfs is forced readonly\n" );
122+ __btrfs_scrub_cancel (fs_info );
123+ // WARN_ON(1);
122124 }
123125}
124126
@@ -197,6 +199,34 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...)
197199 printk ("%sBTRFS %s (device %s): %pV" , lvl , type , sb -> s_id , & vaf );
198200}
199201
202+ /*
203+ * We only mark the transaction aborted and then set the file system read-only.
204+ * This will prevent new transactions from starting or trying to join this
205+ * one.
206+ *
207+ * This means that error recovery at the call site is limited to freeing
208+ * any local memory allocations and passing the error code up without
209+ * further cleanup. The transaction should complete as it normally would
210+ * in the call path but will return -EIO.
211+ *
212+ * We'll complete the cleanup in btrfs_end_transaction and
213+ * btrfs_commit_transaction.
214+ */
215+ void __btrfs_abort_transaction (struct btrfs_trans_handle * trans ,
216+ struct btrfs_root * root , const char * function ,
217+ unsigned int line , int errno )
218+ {
219+ WARN_ON_ONCE (1 );
220+ trans -> aborted = errno ;
221+ /* Nothing used. The other threads that have joined this
222+ * transaction may be able to continue. */
223+ if (!trans -> blocks_used ) {
224+ btrfs_printk (root -> fs_info , "Aborting unused transaction.\n" );
225+ return ;
226+ }
227+ trans -> transaction -> aborted = errno ;
228+ __btrfs_std_error (root -> fs_info , function , line , errno , NULL );
229+ }
200230/*
201231 * __btrfs_panic decodes unexpected, fatal errors from the caller,
202232 * issues an alert, and either panics or BUGs, depending on mount options.
@@ -295,6 +325,7 @@ static match_table_t tokens = {
295325/*
296326 * Regular mount options parser. Everything that is needed only when
297327 * reading in a new superblock is parsed here.
328+ * XXX JDM: This needs to be cleaned up for remount.
298329 */
299330int btrfs_parse_options (struct btrfs_root * root , char * options )
300331{
@@ -1096,38 +1127,65 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
10961127{
10971128 struct btrfs_fs_info * fs_info = btrfs_sb (sb );
10981129 struct btrfs_root * root = fs_info -> tree_root ;
1130+ unsigned old_flags = sb -> s_flags ;
1131+ unsigned long old_opts = fs_info -> mount_opt ;
1132+ unsigned long old_compress_type = fs_info -> compress_type ;
1133+ u64 old_max_inline = fs_info -> max_inline ;
1134+ u64 old_alloc_start = fs_info -> alloc_start ;
1135+ int old_thread_pool_size = fs_info -> thread_pool_size ;
1136+ unsigned int old_metadata_ratio = fs_info -> metadata_ratio ;
10991137 int ret ;
11001138
11011139 ret = btrfs_parse_options (root , data );
1102- if (ret )
1103- return - EINVAL ;
1140+ if (ret ) {
1141+ ret = - EINVAL ;
1142+ goto restore ;
1143+ }
11041144
11051145 if ((* flags & MS_RDONLY ) == (sb -> s_flags & MS_RDONLY ))
11061146 return 0 ;
11071147
11081148 if (* flags & MS_RDONLY ) {
11091149 sb -> s_flags |= MS_RDONLY ;
11101150
1111- ret = btrfs_commit_super (root );
1112- WARN_ON (ret );
1151+ ret = btrfs_commit_super (root );
1152+ if (ret )
1153+ goto restore ;
11131154 } else {
11141155 if (fs_info -> fs_devices -> rw_devices == 0 )
1115- return - EACCES ;
1156+ ret = - EACCES ;
1157+ goto restore ;
11161158
11171159 if (btrfs_super_log_root (fs_info -> super_copy ) != 0 )
1118- return - EINVAL ;
1160+ ret = - EINVAL ;
1161+ goto restore ;
11191162
11201163 ret = btrfs_cleanup_fs_roots (fs_info );
1121- WARN_ON (ret );
1164+ if (ret )
1165+ goto restore ;
11221166
11231167 /* recover relocation */
11241168 ret = btrfs_recover_relocation (root );
1125- WARN_ON (ret );
1169+ if (ret )
1170+ goto restore ;
11261171
11271172 sb -> s_flags &= ~MS_RDONLY ;
11281173 }
11291174
11301175 return 0 ;
1176+
1177+ restore :
1178+ /* We've hit an error - don't reset MS_RDONLY */
1179+ if (sb -> s_flags & MS_RDONLY )
1180+ old_flags |= MS_RDONLY ;
1181+ sb -> s_flags = old_flags ;
1182+ fs_info -> mount_opt = old_opts ;
1183+ fs_info -> compress_type = old_compress_type ;
1184+ fs_info -> max_inline = old_max_inline ;
1185+ fs_info -> alloc_start = old_alloc_start ;
1186+ fs_info -> thread_pool_size = old_thread_pool_size ;
1187+ fs_info -> metadata_ratio = old_metadata_ratio ;
1188+ return ret ;
11311189}
11321190
11331191/* Used to sort the devices by max_avail(descending sort) */
0 commit comments