diff mbox

quota: fix potential infinite loop

Message ID 20171101104045.31753-1-yi.zhang@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zhang Yi Nov. 1, 2017, 10:40 a.m. UTC
In dquot_writeback_dquots(), we write back dquot from dirty dquots
list. There is a potential infinite loop if ->write_dquot() failure
and forget remove dquot from the list. This patch clear dirty bit
anyway to avoid it.

Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
 fs/quota/dquot.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Jan Kara Nov. 1, 2017, 1:43 p.m. UTC | #1
On Wed 01-11-17 18:40:45, zhangyi (F) wrote:
> In dquot_writeback_dquots(), we write back dquot from dirty dquots
> list. There is a potential infinite loop if ->write_dquot() failure
> and forget remove dquot from the list. This patch clear dirty bit
> anyway to avoid it.
> 
> Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>

Thanks. Added to my tree.

								Honza

> ---
>  fs/quota/dquot.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index 52ad151..7ff0080 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -644,8 +644,15 @@ int dquot_writeback_dquots(struct super_block *sb, int type)
>  			spin_unlock(&dq_list_lock);
>  			dqstats_inc(DQST_LOOKUPS);
>  			err = sb->dq_op->write_dquot(dquot);
> -			if (!ret && err)
> -				ret = err;
> +			if (err) {
> +				/*
> +				 * Clear dirty bit anyway to avoid infinite
> +				 * loop here.
> +				 */
> +				clear_dquot_dirty(dquot);
> +				if (!ret)
> +					ret = err;
> +			}
>  			dqput(dquot);
>  			spin_lock(&dq_list_lock);
>  		}
> -- 
> 2.9.5
>
diff mbox

Patch

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 52ad151..7ff0080 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -644,8 +644,15 @@  int dquot_writeback_dquots(struct super_block *sb, int type)
 			spin_unlock(&dq_list_lock);
 			dqstats_inc(DQST_LOOKUPS);
 			err = sb->dq_op->write_dquot(dquot);
-			if (!ret && err)
-				ret = err;
+			if (err) {
+				/*
+				 * Clear dirty bit anyway to avoid infinite
+				 * loop here.
+				 */
+				clear_dquot_dirty(dquot);
+				if (!ret)
+					ret = err;
+			}
 			dqput(dquot);
 			spin_lock(&dq_list_lock);
 		}