btrfs: factor btrfs_check_rw_degradable() to check given device
diff mbox

Message ID 20171218090859.8141-1-anand.jain@oracle.com
State New
Headers show

Commit Message

Anand Jain Dec. 18, 2017, 9:08 a.m. UTC
Update btrfs_check_rw_degradable() to check against the given
device if its lost.

We can use this function to know if the volume is going to be
in degraded mode OR failed state, when the given device fails.
Which is needed when we are handling the device failed state.

A preparatory patch does not affect the flow as such.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/disk-io.c | 4 ++--
 fs/btrfs/super.c   | 2 +-
 fs/btrfs/volumes.c | 8 ++++++--
 fs/btrfs/volumes.h | 4 ++--
 4 files changed, 11 insertions(+), 7 deletions(-)

Comments

Qu Wenruo Dec. 18, 2017, 9:46 a.m. UTC | #1
On 2017年12月18日 17:08, Anand Jain wrote:
> Update btrfs_check_rw_degradable() to check against the given
> device if its lost.
> 
> We can use this function to know if the volume is going to be
> in degraded mode OR failed state, when the given device fails.
> Which is needed when we are handling the device failed state.
> 
> A preparatory patch does not affect the flow as such.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>

Looks good.

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu

> ---
>  fs/btrfs/disk-io.c | 4 ++--
>  fs/btrfs/super.c   | 2 +-
>  fs/btrfs/volumes.c | 8 ++++++--
>  fs/btrfs/volumes.h | 4 ++--
>  4 files changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 55bc6c846671..5604f5e1873e 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -2904,7 +2904,7 @@ int open_ctree(struct super_block *sb,
>  		goto fail_sysfs;
>  	}
>  
> -	if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info)) {
> +	if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info, NULL)) {
>  		btrfs_warn(fs_info,
>  		"writeable mount is not allowed due to too many missing devices");
>  		goto fail_sysfs;
> @@ -3423,7 +3423,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device)
>  
>  static int check_barrier_error(struct btrfs_fs_info *fs_info)
>  {
> -	if (!btrfs_check_rw_degradable(fs_info))
> +	if (!btrfs_check_rw_degradable(fs_info, NULL))
>  		return -EIO;
>  	return 0;
>  }
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index f8129ebad963..cb6d62cf83ec 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -1855,7 +1855,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
>  			goto restore;
>  		}
>  
> -		if (!btrfs_check_rw_degradable(fs_info)) {
> +		if (!btrfs_check_rw_degradable(fs_info, NULL)) {
>  			btrfs_warn(fs_info,
>  				"too many missing devices, writeable remount is not allowed");
>  			ret = -EACCES;
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index b881fc2b2225..9c4868d6fd9a 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -6923,7 +6923,8 @@ int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
>   * Return true if all chunks meet the minimal RW mount requirements.
>   * Return false if any chunk doesn't meet the minimal RW mount requirements.
>   */
> -bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info)
> +bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
> +					struct btrfs_device *failing_dev)
>  {
>  	struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
>  	struct extent_map *em;
> @@ -6955,9 +6956,12 @@ bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info)
>  			    test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) ||
>  			    dev->last_flush_error)
>  				missing++;
> +			else if (failing_dev && failing_dev == dev)
> +				missing++;
>  		}
>  		if (missing > max_tolerated) {
> -			btrfs_warn(fs_info,
> +			if (!failing_dev)
> +				btrfs_warn(fs_info,
>  	"chunk %llu missing %d devices, max tolerance is %d for writeable mount",
>  				   em->start, missing, max_tolerated);
>  			free_extent_map(em);
> diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
> index c7484da44ca4..e707fb39b2d4 100644
> --- a/fs/btrfs/volumes.h
> +++ b/fs/btrfs/volumes.h
> @@ -555,7 +555,7 @@ void btrfs_update_commit_device_bytes_used(struct btrfs_fs_info *fs_info,
>  struct list_head *btrfs_get_fs_uuids(void);
>  void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);
>  void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info);
> -
> -bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info);
> +bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
> +					struct btrfs_device *failing_dev);
>  
>  #endif
>
David Sterba Jan. 2, 2018, 6:01 p.m. UTC | #2
On Mon, Dec 18, 2017 at 05:46:59PM +0800, Qu Wenruo wrote:
> 
> 
> On 2017年12月18日 17:08, Anand Jain wrote:
> > Update btrfs_check_rw_degradable() to check against the given
> > device if its lost.
> > 
> > We can use this function to know if the volume is going to be
> > in degraded mode OR failed state, when the given device fails.
> > Which is needed when we are handling the device failed state.
> > 
> > A preparatory patch does not affect the flow as such.
> > 
> > Signed-off-by: Anand Jain <anand.jain@oracle.com>
> 
> Looks good.
> 
> Reviewed-by: Qu Wenruo <wqu@suse.com>

Added to 4.16 queue, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 55bc6c846671..5604f5e1873e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2904,7 +2904,7 @@  int open_ctree(struct super_block *sb,
 		goto fail_sysfs;
 	}
 
-	if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info)) {
+	if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info, NULL)) {
 		btrfs_warn(fs_info,
 		"writeable mount is not allowed due to too many missing devices");
 		goto fail_sysfs;
@@ -3423,7 +3423,7 @@  static blk_status_t wait_dev_flush(struct btrfs_device *device)
 
 static int check_barrier_error(struct btrfs_fs_info *fs_info)
 {
-	if (!btrfs_check_rw_degradable(fs_info))
+	if (!btrfs_check_rw_degradable(fs_info, NULL))
 		return -EIO;
 	return 0;
 }
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f8129ebad963..cb6d62cf83ec 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1855,7 +1855,7 @@  static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 			goto restore;
 		}
 
-		if (!btrfs_check_rw_degradable(fs_info)) {
+		if (!btrfs_check_rw_degradable(fs_info, NULL)) {
 			btrfs_warn(fs_info,
 				"too many missing devices, writeable remount is not allowed");
 			ret = -EACCES;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b881fc2b2225..9c4868d6fd9a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6923,7 +6923,8 @@  int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
  * Return true if all chunks meet the minimal RW mount requirements.
  * Return false if any chunk doesn't meet the minimal RW mount requirements.
  */
-bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info)
+bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
+					struct btrfs_device *failing_dev)
 {
 	struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
 	struct extent_map *em;
@@ -6955,9 +6956,12 @@  bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info)
 			    test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) ||
 			    dev->last_flush_error)
 				missing++;
+			else if (failing_dev && failing_dev == dev)
+				missing++;
 		}
 		if (missing > max_tolerated) {
-			btrfs_warn(fs_info,
+			if (!failing_dev)
+				btrfs_warn(fs_info,
 	"chunk %llu missing %d devices, max tolerance is %d for writeable mount",
 				   em->start, missing, max_tolerated);
 			free_extent_map(em);
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index c7484da44ca4..e707fb39b2d4 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -555,7 +555,7 @@  void btrfs_update_commit_device_bytes_used(struct btrfs_fs_info *fs_info,
 struct list_head *btrfs_get_fs_uuids(void);
 void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);
 void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info);
-
-bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info);
+bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
+					struct btrfs_device *failing_dev);
 
 #endif