--- /dev/null
+From ffe61171f91ea4f029c9fd3f556555e6e7e309a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2019 10:25:01 +0800
+Subject: ext4: choose hardlimit when softlimit is larger than hardlimit in
+ ext4_statfs_project()
+
+From: Chengguang Xu <cgxu519@mykernel.net>
+
+[ Upstream commit 57c32ea42f8e802bda47010418e25043e0c9337f ]
+
+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 mnt_ext4]# repquota -P -a
+*** Report for project quotas on device /dev/loop0
+Block grace time: 7days; Inode grace time: 7days
+ Block limits File limits
+Project used soft hard grace used soft hard grace
+----------------------------------------------------------------------
+ 0 -- 13 0 0 2 0 0
+ 123 -- 10237 20480 10240 5 200 100
+
+The result of df command as below:
+
+[root@hades mnt_ext4]# df -h test_dir
+Filesystem Size Used Avail Use% Mounted on
+/dev/loop0 20M 10M 10M 50% /home/cgxu/test/mnt_ext4
+
+Even though it looks like there is another 10M free space to use,
+if we write new data to diretory test_dir(inherit project id),
+the write will fail with errno(-EDQUOT).
+
+After this patch, the df result looks like below.
+
+[root@hades mnt_ext4]# df -h test_dir
+Filesystem Size Used Avail Use% Mounted on
+/dev/loop0 10M 10M 3.0K 100% /home/cgxu/test/mnt_ext4
+
+Signed-off-by: Chengguang Xu <cgxu519@mykernel.net>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20191016022501.760-1-cgxu519@mykernel.net
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 937d8bc1dda74..c51d7ef2e4675 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5536,9 +5536,15 @@ static int ext4_statfs_project(struct super_block *sb,
+ 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 < limit))
++ 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 >>= sb->s_blocksize_bits;
++
+ if (limit && buf->f_blocks > limit) {
+ curblock = (dquot->dq_dqb.dqb_curspace +
+ dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits;
+@@ -5548,9 +5554,14 @@ static int ext4_statfs_project(struct super_block *sb,
+ (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 < limit))
++ 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 =
+--
+2.20.1
+
--- /dev/null
+From 1730e33238477e6a78b22705f1d916078bf19435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2020 12:11:48 +0100
+Subject: ext4: simplify checking quota limits in ext4_statfs()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 46d36880d1c6f9b9a0cbaf90235355ea1f4cab96 ]
+
+Coverity reports that conditions checking quota limits in ext4_statfs()
+contain dead code. Indeed it is right and current conditions can be
+simplified.
+
+Link: https://lore.kernel.org/r/20200130111148.10766-1-jack@suse.cz
+Reported-by: Coverity <scan-admin@coverity.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index c51d7ef2e4675..ae77d11d1a34b 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5536,10 +5536,7 @@ static int ext4_statfs_project(struct super_block *sb,
+ return PTR_ERR(dquot);
+ spin_lock(&dquot->dq_dqb_lock);
+
+- limit = 0;
+- if (dquot->dq_dqb.dqb_bsoftlimit &&
+- (!limit || dquot->dq_dqb.dqb_bsoftlimit < limit))
+- limit = 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;
+@@ -5554,10 +5551,7 @@ static int ext4_statfs_project(struct super_block *sb,
+ (buf->f_blocks - curblock) : 0;
+ }
+
+- limit = 0;
+- if (dquot->dq_dqb.dqb_isoftlimit &&
+- (!limit || dquot->dq_dqb.dqb_isoftlimit < limit))
+- limit = 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;
+--
+2.20.1
+
--- /dev/null
+From ddff44d17dfc7f81c27412e0de75af604a2c5614 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Dec 2019 03:40:55 +0100
+Subject: gpio: add gpiod_toggle_active_low()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit d3a5bcb4a17f1ad072484bb92c42519ff3aba6e1 ]
+
+Add possibility to toggle active-low flag of a gpio descriptor. This is
+useful for compatibility code, where defaults are inverted vs DT gpio
+flags or the active-low flag is taken from elsewhere.
+
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/7ce0338e01ad17fa5a227176813941b41a7c35c1.1576031637.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib.c | 11 +++++++++++
+ include/linux/gpio/consumer.h | 7 +++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 78a16e42f222e..bcfbfded9ba3f 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -3371,6 +3371,17 @@ int gpiod_is_active_low(const struct gpio_desc *desc)
+ }
+ EXPORT_SYMBOL_GPL(gpiod_is_active_low);
+
++/**
++ * gpiod_toggle_active_low - toggle whether a GPIO is active-low or not
++ * @desc: the gpio descriptor to change
++ */
++void gpiod_toggle_active_low(struct gpio_desc *desc)
++{
++ VALIDATE_DESC_VOID(desc);
++ change_bit(FLAG_ACTIVE_LOW, &desc->flags);
++}
++EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);
++
+ /* I/O calls are only valid after configuration completed; the relevant
+ * "is this a valid GPIO" error checks should already have been done.
+ *
+diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
+index 5215fdba6b9a6..bf2d017dd7b71 100644
+--- a/include/linux/gpio/consumer.h
++++ b/include/linux/gpio/consumer.h
+@@ -158,6 +158,7 @@ int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
+
+ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
+ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
++void gpiod_toggle_active_low(struct gpio_desc *desc);
+
+ int gpiod_is_active_low(const struct gpio_desc *desc);
+ int gpiod_cansleep(const struct gpio_desc *desc);
+@@ -483,6 +484,12 @@ static inline int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
+ return -ENOSYS;
+ }
+
++static inline void gpiod_toggle_active_low(struct gpio_desc *desc)
++{
++ /* GPIO can never have been requested */
++ WARN_ON(desc);
++}
++
+ static inline int gpiod_is_active_low(const struct gpio_desc *desc)
+ {
+ /* GPIO can never have been requested */
+--
+2.20.1
+
--- /dev/null
+From 5d6fdf1b2d5274f11ef7d1e2e54356656319bfff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2020 21:42:51 -0700
+Subject: io-wq: add support for inheriting ->fs
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 9392a27d88b9707145d713654eb26f0c29789e50 ]
+
+Some work items need this for relative path lookup, make it available
+like the other inherited credentials/mm/etc.
+
+Cc: stable@vger.kernel.org # 5.3+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/io-wq.c | 8 ++++++++
+ fs/io-wq.h | 4 +++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/io-wq.c b/fs/io-wq.c
+index 5147d2213b019..0dc4bb6de6566 100644
+--- a/fs/io-wq.c
++++ b/fs/io-wq.c
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/kthread.h>
+ #include <linux/rculist_nulls.h>
++#include <linux/fs_struct.h>
+
+ #include "io-wq.h"
+
+@@ -58,6 +59,7 @@ struct io_worker {
+ struct mm_struct *mm;
+ const struct cred *creds;
+ struct files_struct *restore_files;
++ struct fs_struct *restore_fs;
+ };
+
+ #if BITS_PER_LONG == 64
+@@ -150,6 +152,9 @@ static bool __io_worker_unuse(struct io_wqe *wqe, struct io_worker *worker)
+ task_unlock(current);
+ }
+
++ if (current->fs != worker->restore_fs)
++ current->fs = worker->restore_fs;
++
+ /*
+ * If we have an active mm, we need to drop the wq lock before unusing
+ * it. If we do, return true and let the caller retry the idle loop.
+@@ -310,6 +315,7 @@ static void io_worker_start(struct io_wqe *wqe, struct io_worker *worker)
+
+ worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
+ worker->restore_files = current->files;
++ worker->restore_fs = current->fs;
+ io_wqe_inc_running(wqe, worker);
+ }
+
+@@ -456,6 +462,8 @@ static void io_worker_handle_work(struct io_worker *worker)
+ }
+ if (!worker->creds)
+ worker->creds = override_creds(wq->creds);
++ if (work->fs && current->fs != work->fs)
++ current->fs = work->fs;
+ if (test_bit(IO_WQ_BIT_CANCEL, &wq->state))
+ work->flags |= IO_WQ_WORK_CANCEL;
+ if (worker->mm)
+diff --git a/fs/io-wq.h b/fs/io-wq.h
+index 3f5e356de9805..bbab98d1d328b 100644
+--- a/fs/io-wq.h
++++ b/fs/io-wq.h
+@@ -72,6 +72,7 @@ struct io_wq_work {
+ };
+ void (*func)(struct io_wq_work **);
+ struct files_struct *files;
++ struct fs_struct *fs;
+ unsigned flags;
+ };
+
+@@ -79,8 +80,9 @@ struct io_wq_work {
+ do { \
+ (work)->list.next = NULL; \
+ (work)->func = _func; \
+- (work)->flags = 0; \
+ (work)->files = NULL; \
++ (work)->fs = NULL; \
++ (work)->flags = 0; \
+ } while (0) \
+
+ typedef void (get_work_fn)(struct io_wq_work *);
+--
+2.20.1
+
--- /dev/null
+From c585d4fb871d21870c87ea91b85bb319bab7bad3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Dec 2019 03:40:55 +0100
+Subject: mmc: core: Rework wp-gpio handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 9073d10b098973519044f5fcdc25586810b435da ]
+
+Use MMC_CAP2_RO_ACTIVE_HIGH flag as indicator if GPIO line is to be
+inverted compared to DT/platform-specified polarity. The flag is not used
+after init in GPIO mode anyway. No functional changes intended.
+
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/a60f563f11bbff821da2fa2949ca82922b144860.1576031637.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-of.c | 4 ----
+ drivers/mmc/core/host.c | 11 ++++-------
+ drivers/mmc/core/slot-gpio.c | 3 +++
+ drivers/mmc/host/pxamci.c | 8 ++++----
+ drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
+ 5 files changed, 13 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index b696e4598a240..b0e79bed59520 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -147,10 +147,6 @@ static void of_gpio_flags_quirks(struct device_node *np,
+ if (of_property_read_bool(np, "cd-inverted"))
+ *flags ^= OF_GPIO_ACTIVE_LOW;
+ }
+- if (!strcmp(propname, "wp-gpios")) {
+- if (of_property_read_bool(np, "wp-inverted"))
+- *flags ^= OF_GPIO_ACTIVE_LOW;
+- }
+ }
+ /*
+ * Some GPIO fixed regulator quirks.
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index 105b7a7c02513..b3484def0a8b0 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -176,7 +176,6 @@ int mmc_of_parse(struct mmc_host *host)
+ u32 bus_width, drv_type, cd_debounce_delay_ms;
+ int ret;
+ bool cd_cap_invert, cd_gpio_invert = false;
+- bool ro_cap_invert, ro_gpio_invert = false;
+
+ if (!dev || !dev_fwnode(dev))
+ return 0;
+@@ -255,9 +254,11 @@ int mmc_of_parse(struct mmc_host *host)
+ }
+
+ /* Parse Write Protection */
+- ro_cap_invert = device_property_read_bool(dev, "wp-inverted");
+
+- ret = mmc_gpiod_request_ro(host, "wp", 0, 0, &ro_gpio_invert);
++ if (device_property_read_bool(dev, "wp-inverted"))
++ host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
++
++ ret = mmc_gpiod_request_ro(host, "wp", 0, 0, NULL);
+ if (!ret)
+ dev_info(host->parent, "Got WP GPIO\n");
+ else if (ret != -ENOENT && ret != -ENOSYS)
+@@ -266,10 +267,6 @@ int mmc_of_parse(struct mmc_host *host)
+ if (device_property_read_bool(dev, "disable-wp"))
+ host->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
+
+- /* See the comment on CD inversion above */
+- if (ro_cap_invert ^ ro_gpio_invert)
+- host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+-
+ if (device_property_read_bool(dev, "cap-sd-highspeed"))
+ host->caps |= MMC_CAP_SD_HIGHSPEED;
+ if (device_property_read_bool(dev, "cap-mmc-highspeed"))
+diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
+index da2596c5fa28d..582ec3d720f64 100644
+--- a/drivers/mmc/core/slot-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -241,6 +241,9 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
+ return ret;
+ }
+
++ if (host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH)
++ gpiod_toggle_active_low(desc);
++
+ if (gpio_invert)
+ *gpio_invert = !gpiod_is_active_low(desc);
+
+diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
+index 024acc1b0a2ea..b2bbcb09a49e6 100644
+--- a/drivers/mmc/host/pxamci.c
++++ b/drivers/mmc/host/pxamci.c
+@@ -740,16 +740,16 @@ static int pxamci_probe(struct platform_device *pdev)
+ goto out;
+ }
+
++ if (!host->pdata->gpio_card_ro_invert)
++ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
++
+ ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
+ if (ret && ret != -ENOENT) {
+ dev_err(dev, "Failed requesting gpio_ro\n");
+ goto out;
+ }
+- if (!ret) {
++ if (!ret)
+ host->use_ro_gpio = true;
+- mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
+- 0 : MMC_CAP2_RO_ACTIVE_HIGH;
+- }
+
+ if (host->pdata->init)
+ host->pdata->init(dev, pxamci_detect_irq, mmc);
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 1c988d6a24330..dccb4df465126 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1381,13 +1381,14 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
+ host->mmc->parent->platform_data);
+ /* write_protect */
+ if (boarddata->wp_type == ESDHC_WP_GPIO) {
++ host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
++
+ err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
+ if (err) {
+ dev_err(mmc_dev(host->mmc),
+ "failed to request write-protect gpio!\n");
+ return err;
+ }
+- host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+ }
+
+ /* card_detect */
+--
+2.20.1
+
--- /dev/null
+From 2724276851c78de61380511e5e229dc672da6bcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2020 09:58:18 -0500
+Subject: NFSv4: Add accounting for the number of active delegations held
+
+From: Trond Myklebust <trondmy@gmail.com>
+
+[ Upstream commit d2269ea14ebd2a73f291d6b3a7a7d320ec00270c ]
+
+In order to better manage our delegation caching, add a counter
+to track the number of active delegations.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 5f02d922f2173..8e322bacde699 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -25,13 +25,29 @@
+ #include "internal.h"
+ #include "nfs4trace.h"
+
+-static void nfs_free_delegation(struct nfs_delegation *delegation)
++static atomic_long_t nfs_active_delegations;
++
++static void __nfs_free_delegation(struct nfs_delegation *delegation)
+ {
+ put_cred(delegation->cred);
+ delegation->cred = NULL;
+ kfree_rcu(delegation, rcu);
+ }
+
++static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation)
++{
++ if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
++ delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
++ atomic_long_dec(&nfs_active_delegations);
++ }
++}
++
++static void nfs_free_delegation(struct nfs_delegation *delegation)
++{
++ nfs_mark_delegation_revoked(delegation);
++ __nfs_free_delegation(delegation);
++}
++
+ /**
+ * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
+ * @delegation: delegation to process
+@@ -348,7 +364,8 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation,
+ delegation->stateid.seqid = update->stateid.seqid;
+ smp_wmb();
+ delegation->type = update->type;
+- clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
++ if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
++ atomic_long_inc(&nfs_active_delegations);
+ }
+ }
+
+@@ -428,6 +445,8 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
+ rcu_assign_pointer(nfsi->delegation, delegation);
+ delegation = NULL;
+
++ atomic_long_inc(&nfs_active_delegations);
++
+ trace_nfs4_set_delegation(inode, type);
+
+ spin_lock(&inode->i_lock);
+@@ -437,7 +456,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
+ out:
+ spin_unlock(&clp->cl_lock);
+ if (delegation != NULL)
+- nfs_free_delegation(delegation);
++ __nfs_free_delegation(delegation);
+ if (freeme != NULL) {
+ nfs_do_return_delegation(inode, freeme, 0);
+ nfs_free_delegation(freeme);
+@@ -765,13 +784,6 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
+ rcu_read_unlock();
+ }
+
+-static void nfs_mark_delegation_revoked(struct nfs_server *server,
+- struct nfs_delegation *delegation)
+-{
+- set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
+- delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
+-}
+-
+ static void nfs_revoke_delegation(struct inode *inode,
+ const nfs4_stateid *stateid)
+ {
+@@ -799,7 +811,7 @@ static void nfs_revoke_delegation(struct inode *inode,
+ }
+ spin_unlock(&delegation->lock);
+ }
+- nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
++ nfs_mark_delegation_revoked(delegation);
+ ret = true;
+ out:
+ rcu_read_unlock();
+@@ -838,7 +850,7 @@ void nfs_delegation_mark_returned(struct inode *inode,
+ delegation->stateid.seqid = stateid->seqid;
+ }
+
+- nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
++ nfs_mark_delegation_revoked(delegation);
+
+ out_clear_returning:
+ clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+--
+2.20.1
+
nfsv4-ensure-the-delegation-cred-is-pinned-when-we-call-delegreturn.patch
revert-drm-sun4i-drv-allow-framebuffer-modifiers-in-mode-config.patch
drm-i915-pmu-correct-the-rc6-offset-upon-enabling.patch
+ext4-choose-hardlimit-when-softlimit-is-larger-than-.patch
+ext4-simplify-checking-quota-limits-in-ext4_statfs.patch
+io-wq-add-support-for-inheriting-fs.patch
+nfsv4-add-accounting-for-the-number-of-active-delega.patch
+gpio-add-gpiod_toggle_active_low.patch
+mmc-core-rework-wp-gpio-handling.patch