From 475d3c09bb66ca7430ce7eccf998d45e04351a61 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Feb 2020 11:28:29 +0100 Subject: [PATCH] 4.19-stable patches added patches: f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch f2fs-code-cleanup-for-f2fs_statfs_project.patch f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch --- ...han-hardlimit-in-f2fs_statfs_project.patch | 58 +++++++++ ...code-cleanup-for-f2fs_statfs_project.patch | 53 ++++++++ ...d-block-limit-in-f2fs_statfs_project.patch | 33 +++++ ...rong-warn_on-in-ovl_cache_update_ino.patch | 43 ++++++ ...es-deleted-during-system-wide-resume.patch | 123 ++++++++++++++++++ queue-4.19/series | 5 + 6 files changed, 315 insertions(+) create mode 100644 queue-4.19/f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch create mode 100644 queue-4.19/f2fs-code-cleanup-for-f2fs_statfs_project.patch create mode 100644 queue-4.19/f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch create mode 100644 queue-4.19/ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch create mode 100644 queue-4.19/pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch diff --git a/queue-4.19/f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch b/queue-4.19/f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch new file mode 100644 index 00000000000..fed221f1ab7 --- /dev/null +++ b/queue-4.19/f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch @@ -0,0 +1,58 @@ +From 909110c060f22e65756659ec6fa957ae75777e00 Mon Sep 17 00:00:00 2001 +From: Chengguang Xu +Date: Mon, 25 Nov 2019 11:20:36 +0800 +Subject: f2fs: choose hardlimit when softlimit is larger than hardlimit in f2fs_statfs_project() + +From: Chengguang Xu + +commit 909110c060f22e65756659ec6fa957ae75777e00 upstream. + +Setting softlimit larger than hardlimit seems meaningless +for disk quota but currently it is allowed. In this case, +there may be a bit of comfusion for users when they run +df comamnd to directory which has project quota. + +For example, we set 20M softlimit and 10M hardlimit of +block usage limit for project quota of test_dir(project id 123). + +[root@hades f2fs]# repquota -P -a +--- + fs/f2fs/super.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1148,9 +1148,13 @@ static int f2fs_statfs_project(struct su + return PTR_ERR(dquot); + spin_lock(&dquot->dq_dqb_lock); + +- limit = (dquot->dq_dqb.dqb_bsoftlimit ? +- dquot->dq_dqb.dqb_bsoftlimit : +- dquot->dq_dqb.dqb_bhardlimit) >> sb->s_blocksize_bits; ++ limit = 0; ++ if (dquot->dq_dqb.dqb_bsoftlimit) ++ limit = dquot->dq_dqb.dqb_bsoftlimit; ++ if (dquot->dq_dqb.dqb_bhardlimit && ++ (!limit || dquot->dq_dqb.dqb_bhardlimit < limit)) ++ limit = dquot->dq_dqb.dqb_bhardlimit; ++ + if (limit && buf->f_blocks > limit) { + curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits; + buf->f_blocks = limit; +@@ -1159,9 +1163,13 @@ static int f2fs_statfs_project(struct su + (buf->f_blocks - curblock) : 0; + } + +- limit = dquot->dq_dqb.dqb_isoftlimit ? +- dquot->dq_dqb.dqb_isoftlimit : +- dquot->dq_dqb.dqb_ihardlimit; ++ limit = 0; ++ if (dquot->dq_dqb.dqb_isoftlimit) ++ limit = dquot->dq_dqb.dqb_isoftlimit; ++ if (dquot->dq_dqb.dqb_ihardlimit && ++ (!limit || dquot->dq_dqb.dqb_ihardlimit < limit)) ++ limit = dquot->dq_dqb.dqb_ihardlimit; ++ + if (limit && buf->f_files > limit) { + buf->f_files = limit; + buf->f_ffree = diff --git a/queue-4.19/f2fs-code-cleanup-for-f2fs_statfs_project.patch b/queue-4.19/f2fs-code-cleanup-for-f2fs_statfs_project.patch new file mode 100644 index 00000000000..7e78e6c64ba --- /dev/null +++ b/queue-4.19/f2fs-code-cleanup-for-f2fs_statfs_project.patch @@ -0,0 +1,53 @@ +From bf2cbd3c57159c2b639ee8797b52ab5af180bf83 Mon Sep 17 00:00:00 2001 +From: Chengguang Xu +Date: Sat, 4 Jan 2020 22:20:04 +0800 +Subject: f2fs: code cleanup for f2fs_statfs_project() + +From: Chengguang Xu + +commit bf2cbd3c57159c2b639ee8797b52ab5af180bf83 upstream. + +Calling min_not_zero() to simplify complicated prjquota +limit comparison in f2fs_statfs_project(). + +Signed-off-by: Chengguang Xu +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/super.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1148,12 +1148,8 @@ static int f2fs_statfs_project(struct su + return PTR_ERR(dquot); + spin_lock(&dquot->dq_dqb_lock); + +- limit = 0; +- if (dquot->dq_dqb.dqb_bsoftlimit) +- limit = dquot->dq_dqb.dqb_bsoftlimit; +- if (dquot->dq_dqb.dqb_bhardlimit && +- (!limit || dquot->dq_dqb.dqb_bhardlimit < limit)) +- limit = dquot->dq_dqb.dqb_bhardlimit; ++ limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit, ++ dquot->dq_dqb.dqb_bhardlimit); + if (limit) + limit >>= sb->s_blocksize_bits; + +@@ -1165,12 +1161,8 @@ static int f2fs_statfs_project(struct su + (buf->f_blocks - curblock) : 0; + } + +- limit = 0; +- if (dquot->dq_dqb.dqb_isoftlimit) +- limit = dquot->dq_dqb.dqb_isoftlimit; +- if (dquot->dq_dqb.dqb_ihardlimit && +- (!limit || dquot->dq_dqb.dqb_ihardlimit < limit)) +- limit = dquot->dq_dqb.dqb_ihardlimit; ++ limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit, ++ dquot->dq_dqb.dqb_ihardlimit); + + if (limit && buf->f_files > limit) { + buf->f_files = limit; diff --git a/queue-4.19/f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch b/queue-4.19/f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch new file mode 100644 index 00000000000..7aab6015d19 --- /dev/null +++ b/queue-4.19/f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch @@ -0,0 +1,33 @@ +From acdf2172172a511f97fa21ed0ee7609a6d3b3a07 Mon Sep 17 00:00:00 2001 +From: Chengguang Xu +Date: Sat, 4 Jan 2020 22:20:03 +0800 +Subject: f2fs: fix miscounted block limit in f2fs_statfs_project() + +From: Chengguang Xu + +commit acdf2172172a511f97fa21ed0ee7609a6d3b3a07 upstream. + +statfs calculates Total/Used/Avail disk space in block unit, +so we should translate soft/hard prjquota limit to block unit +as well. + +Below testing result shows the block/inode numbers of +Total/Used/Avail from df command are all correct afer +applying this patch. + +[root@localhost quota-tools]\# ./repquota -P /dev/sdb1 +--- + fs/f2fs/super.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1154,6 +1154,8 @@ static int f2fs_statfs_project(struct su + if (dquot->dq_dqb.dqb_bhardlimit && + (!limit || dquot->dq_dqb.dqb_bhardlimit < limit)) + limit = dquot->dq_dqb.dqb_bhardlimit; ++ if (limit) ++ limit >>= sb->s_blocksize_bits; + + if (limit && buf->f_blocks > limit) { + curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits; diff --git a/queue-4.19/ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch b/queue-4.19/ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch new file mode 100644 index 00000000000..661db570f8f --- /dev/null +++ b/queue-4.19/ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch @@ -0,0 +1,43 @@ +From 4c37e71b713ecffe81f8e6273c6835e54306d412 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Sun, 22 Dec 2019 22:47:54 +0200 +Subject: ovl: fix wrong WARN_ON() in ovl_cache_update_ino() + +From: Amir Goldstein + +commit 4c37e71b713ecffe81f8e6273c6835e54306d412 upstream. + +The WARN_ON() that child entry is always on overlay st_dev became wrong +when we allowed this function to update d_ino in non-samefs setup with xino +enabled. + +It is not true in case of xino bits overflow on a non-dir inode. Leave the +WARN_ON() only for directories, where assertion is still true. + +Fixes: adbf4f7ea834 ("ovl: consistent d_ino for non-samefs with xino") +Cc: # v4.17+ +Signed-off-by: Amir Goldstein +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/readdir.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/fs/overlayfs/readdir.c ++++ b/fs/overlayfs/readdir.c +@@ -507,7 +507,13 @@ get: + if (err) + goto fail; + +- WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev); ++ /* ++ * Directory inode is always on overlay st_dev. ++ * Non-dir with ovl_same_dev() could be on pseudo st_dev in case ++ * of xino bits overflow. ++ */ ++ WARN_ON_ONCE(S_ISDIR(stat.mode) && ++ dir->d_sb->s_dev != stat.dev); + ino = stat.ino; + } else if (xinobits && !OVL_TYPE_UPPER(type)) { + ino = ovl_remap_lower_ino(ino, xinobits, diff --git a/queue-4.19/pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch b/queue-4.19/pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch new file mode 100644 index 00000000000..4bc971a5d7d --- /dev/null +++ b/queue-4.19/pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch @@ -0,0 +1,123 @@ +From 0552e05fdfea191a2cf3a0abd33574b5ef9ca818 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 23 Jan 2020 00:11:24 +0100 +Subject: PM: core: Fix handling of devices deleted during system-wide resume + +From: Rafael J. Wysocki + +commit 0552e05fdfea191a2cf3a0abd33574b5ef9ca818 upstream. + +If a device is deleted by one of its system-wide resume callbacks +(for example, because it does not appear to be present or accessible +any more) along with its children, the resume of the children may +continue leading to use-after-free errors and other issues +(potentially). + +Namely, if the device's children are resumed asynchronously, their +resume may have been scheduled already before the device's callback +runs and so the device may be deleted while dpm_wait_for_superior() +is being executed for them. The memory taken up by the parent device +object may be freed then while dpm_wait() is waiting for the parent's +resume callback to complete, which leads to a use-after-free. +Moreover, the resume of the children is really not expected to +continue after they have been unregistered, so it must be terminated +right away in that case. + +To address this problem, modify dpm_wait_for_superior() to check +if the target device is still there in the system-wide PM list of +devices and if so, to increment its parent's reference counter, both +under dpm_list_mtx which prevents device_del() running for the child +from dropping the parent's reference counter prematurely. + +If the device is not present in the system-wide PM list of devices +any more, the resume of it cannot continue, so check that again after +dpm_wait() returns, which means that the parent's callback has been +completed, and pass the result of that check to the caller of +dpm_wait_for_superior() to allow it to abort the device's resume +if it is not there any more. + +Link: https://lore.kernel.org/linux-pm/1579568452-27253-1-git-send-email-chanho.min@lge.com +Reported-by: Chanho Min +Cc: All applicable +Signed-off-by: Rafael J. Wysocki +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/main.c | 42 +++++++++++++++++++++++++++++++++++++----- + 1 file changed, 37 insertions(+), 5 deletions(-) + +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -265,10 +265,38 @@ static void dpm_wait_for_suppliers(struc + device_links_read_unlock(idx); + } + +-static void dpm_wait_for_superior(struct device *dev, bool async) ++static bool dpm_wait_for_superior(struct device *dev, bool async) + { +- dpm_wait(dev->parent, async); ++ struct device *parent; ++ ++ /* ++ * If the device is resumed asynchronously and the parent's callback ++ * deletes both the device and the parent itself, the parent object may ++ * be freed while this function is running, so avoid that by reference ++ * counting the parent once more unless the device has been deleted ++ * already (in which case return right away). ++ */ ++ mutex_lock(&dpm_list_mtx); ++ ++ if (!device_pm_initialized(dev)) { ++ mutex_unlock(&dpm_list_mtx); ++ return false; ++ } ++ ++ parent = get_device(dev->parent); ++ ++ mutex_unlock(&dpm_list_mtx); ++ ++ dpm_wait(parent, async); ++ put_device(parent); ++ + dpm_wait_for_suppliers(dev, async); ++ ++ /* ++ * If the parent's callback has deleted the device, attempting to resume ++ * it would be invalid, so avoid doing that then. ++ */ ++ return device_pm_initialized(dev); + } + + static void dpm_wait_for_consumers(struct device *dev, bool async) +@@ -628,7 +656,8 @@ static int device_resume_noirq(struct de + if (!dev->power.is_noirq_suspended) + goto Out; + +- dpm_wait_for_superior(dev, async); ++ if (!dpm_wait_for_superior(dev, async)) ++ goto Out; + + skip_resume = dev_pm_may_skip_resume(dev); + +@@ -829,7 +858,8 @@ static int device_resume_early(struct de + if (!dev->power.is_late_suspended) + goto Out; + +- dpm_wait_for_superior(dev, async); ++ if (!dpm_wait_for_superior(dev, async)) ++ goto Out; + + callback = dpm_subsys_resume_early_cb(dev, state, &info); + +@@ -949,7 +979,9 @@ static int device_resume(struct device * + goto Complete; + } + +- dpm_wait_for_superior(dev, async); ++ if (!dpm_wait_for_superior(dev, async)) ++ goto Complete; ++ + dpm_watchdog_set(&wd, dev); + device_lock(dev); + diff --git a/queue-4.19/series b/queue-4.19/series index 6dd905996ec..5d3d1f335d5 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -77,3 +77,8 @@ crypto-ccree-fix-pm-race-condition.patch scripts-find-unused-docs-fix-massive-false-positives.patch scsi-qla2xxx-fix-mtcp-dump-collection-failure.patch power-supply-ltc2941-battery-gauge-fix-use-after-free.patch +ovl-fix-wrong-warn_on-in-ovl_cache_update_ino.patch +f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_project.patch +f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch +f2fs-code-cleanup-for-f2fs_statfs_project.patch +pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch -- 2.47.3