On Wed, Sep 24, 2014 at 12:16 PM, Miao Xie <mi...@cn.fujitsu.com> wrote:
> On Wed, 24 Sep 2014 11:28:26 +0100, Filipe Manana wrote:
> [SNIP]
>>  int btrfs_wait_marked_extents(struct btrfs_root *root,
>> +                           struct btrfs_trans_handle *trans,
>>                             struct extent_io_tree *dirty_pages, int mark)
>>  {
>>       int err = 0;
>> @@ -852,6 +855,7 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
>>       struct extent_state *cached_state = NULL;
>>       u64 start = 0;
>>       u64 end;
>> +     int errors;
>>
>>       while (!find_first_extent_bit(dirty_pages, start, &start, &end,
>>                                     EXTENT_NEED_WAIT, &cached_state)) {
>> @@ -865,6 +869,16 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
>>       }
>>       if (err)
>>               werr = err;
>> +
>> +     if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID)
>> +             errors = atomic_xchg(
>> +                 &trans->transaction->log_eb_write_errors, 0);
>> +     else
>> +             errors = atomic_xchg(&trans->transaction->eb_write_errors, 0);
>
> There is a bug in log tree commit case.
> As we know, each fs/file tree has two log sub-transaction, when we are 
> committing
> a log sub-transaction, the other one may be started by the other file sync 
> tasks.
> It is very likely that there is no any error happens in the former, but some 
> write
> errors happen in the latter. The above code might clear the number of that 
> errors.
>
> So I think the variant for log write error should be created for each log 
> sub-transaction.

Right.
I'm fixing that and another issue I missed before.

thanks

>
> Thanks
> Miao
>
>> +
>> +     if (errors && !werr)
>> +             werr = -EIO;
>> +
>>       return werr;
>>  }
>>
>> @@ -874,6 +888,7 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
>>   * those extents are on disk for transaction or log commit
>>   */
>>  static int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
>> +                             struct btrfs_trans_handle *trans,
>>                               struct extent_io_tree *dirty_pages, int mark)
>>  {
>>       int ret;
>> @@ -883,7 +898,7 @@ static int btrfs_write_and_wait_marked_extents(struct 
>> btrfs_root *root,
>>       blk_start_plug(&plug);
>>       ret = btrfs_write_marked_extents(root, dirty_pages, mark);
>>       blk_finish_plug(&plug);
>> -     ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
>> +     ret2 = btrfs_wait_marked_extents(root, trans, dirty_pages, mark);
>>
>>       if (ret)
>>               return ret;
>> @@ -892,7 +907,7 @@ static int btrfs_write_and_wait_marked_extents(struct 
>> btrfs_root *root,
>>       return 0;
>>  }
>>
>> -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
>> +static int btrfs_write_and_wait_transaction(struct btrfs_trans_handle 
>> *trans,
>>                                    struct btrfs_root *root)
>>  {
>>       if (!trans || !trans->transaction) {
>> @@ -900,7 +915,7 @@ int btrfs_write_and_wait_transaction(struct 
>> btrfs_trans_handle *trans,
>>               btree_inode = root->fs_info->btree_inode;
>>               return filemap_write_and_wait(btree_inode->i_mapping);
>>       }
>> -     return btrfs_write_and_wait_marked_extents(root,
>> +     return btrfs_write_and_wait_marked_extents(root, trans,
>>                                          &trans->transaction->dirty_pages,
>>                                          EXTENT_DIRTY);
>>  }
>> diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
>> index 7dd558e..311f3e3 100644
>> --- a/fs/btrfs/transaction.h
>> +++ b/fs/btrfs/transaction.h
>> @@ -46,6 +46,8 @@ struct btrfs_transaction {
>>        */
>>       atomic_t num_writers;
>>       atomic_t use_count;
>> +     atomic_t eb_write_errors;
>> +     atomic_t log_eb_write_errors;
>>
>>       /* Be protected by fs_info->trans_lock when we want to change it. */
>>       enum btrfs_trans_state state;
>> @@ -146,8 +148,6 @@ struct btrfs_trans_handle 
>> *btrfs_attach_transaction_barrier(
>>                                       struct btrfs_root *root);
>>  struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root 
>> *root);
>>  int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
>> -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
>> -                                  struct btrfs_root *root);
>>
>>  void btrfs_add_dead_root(struct btrfs_root *root);
>>  int btrfs_defrag_root(struct btrfs_root *root);
>> @@ -167,6 +167,7 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle 
>> *trans,
>>  int btrfs_write_marked_extents(struct btrfs_root *root,
>>                               struct extent_io_tree *dirty_pages, int mark);
>>  int btrfs_wait_marked_extents(struct btrfs_root *root,
>> +                           struct btrfs_trans_handle *trans,
>>                               struct extent_io_tree *dirty_pages, int mark);
>>  int btrfs_transaction_blocked(struct btrfs_fs_info *info);
>>  int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
>> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
>> index 2d0fa43..22ffd32 100644
>> --- a/fs/btrfs/tree-log.c
>> +++ b/fs/btrfs/tree-log.c
>> @@ -2583,7 +2583,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
>>                       mutex_unlock(&log_root_tree->log_mutex);
>>                       goto out;
>>               }
>> -             btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
>> +             btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
>> +                                       mark);
>>               btrfs_free_logged_extents(log, log_transid);
>>               mutex_unlock(&log_root_tree->log_mutex);
>>               ret = -EAGAIN;
>> @@ -2599,7 +2600,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
>>       index2 = root_log_ctx.log_transid % 2;
>>       if (atomic_read(&log_root_tree->log_commit[index2])) {
>>               blk_finish_plug(&plug);
>> -             btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
>> +             btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
>> +                                       mark);
>>               wait_log_commit(trans, log_root_tree,
>>                               root_log_ctx.log_transid);
>>               btrfs_free_logged_extents(log, log_transid);
>> @@ -2623,7 +2625,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
>>        */
>>       if (btrfs_need_log_full_commit(root->fs_info, trans)) {
>>               blk_finish_plug(&plug);
>> -             btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
>> +             btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
>> +                                       mark);
>>               btrfs_free_logged_extents(log, log_transid);
>>               mutex_unlock(&log_root_tree->log_mutex);
>>               ret = -EAGAIN;
>> @@ -2641,8 +2644,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
>>               mutex_unlock(&log_root_tree->log_mutex);
>>               goto out_wake_log_root;
>>       }
>> -     btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
>> -     btrfs_wait_marked_extents(log_root_tree,
>> +     btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages, mark);
>> +     btrfs_wait_marked_extents(log_root_tree, trans,
>>                                 &log_root_tree->dirty_log_pages,
>>                                 EXTENT_NEW | EXTENT_DIRTY);
>>       btrfs_wait_logged_extents(log, log_transid);
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Filipe David Manana,

"Reasonable men adapt themselves to the world.
 Unreasonable men adapt the world to themselves.
 That's why all progress depends on unreasonable men."
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to