]> git.ipfire.org Git - people/arne_f/kernel.git/blobdiff - fs/drop_caches.c
scsi: pm8001: Fix memleak in pm8001_exec_internal_task_abort
[people/arne_f/kernel.git] / fs / drop_caches.c
index d72d52b904333767328235a2de720107503cdcf2..dc1a1d5d825b48de17f3192f8d0c50829dd07885 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Implement the manual drop-all-pagecache function
  */
@@ -20,8 +21,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
        spin_lock(&sb->s_inode_list_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
                spin_lock(&inode->i_lock);
+               /*
+                * We must skip inodes in unusual state. We may also skip
+                * inodes without pages but we deliberately won't in case
+                * we need to reschedule to avoid softlockups.
+                */
                if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
-                   (inode->i_mapping->nrpages == 0)) {
+                   (inode->i_mapping->nrpages == 0 && !need_resched())) {
                        spin_unlock(&inode->i_lock);
                        continue;
                }
@@ -33,6 +39,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
                iput(toput_inode);
                toput_inode = inode;
 
+               cond_resched();
                spin_lock(&sb->s_inode_list_lock);
        }
        spin_unlock(&sb->s_inode_list_lock);