diff options
Diffstat (limited to 'fs/fs-writeback.c')
| -rw-r--r-- | fs/fs-writeback.c | 19 | 
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 195dc23e0d83..ae4e51e91ee3 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -829,7 +829,7 @@ void wbc_detach_inode(struct writeback_control *wbc)  		 * is okay.  The main goal is avoiding keeping an inode on  		 * the wrong wb for an extended period of time.  		 */ -		if (hweight32(history) > WB_FRN_HIST_THR_SLOTS) +		if (hweight16(history) > WB_FRN_HIST_THR_SLOTS)  			inode_switch_wbs(inode, max_id);  	} @@ -978,6 +978,16 @@ restart:  			continue;  		} +		/* +		 * If wb_tryget fails, the wb has been shutdown, skip it. +		 * +		 * Pin @wb so that it stays on @bdi->wb_list.  This allows +		 * continuing iteration from @wb after dropping and +		 * regrabbing rcu read lock. +		 */ +		if (!wb_tryget(wb)) +			continue; +  		/* alloc failed, execute synchronously using on-stack fallback */  		work = &fallback_work;  		*work = *base_work; @@ -986,13 +996,6 @@ restart:  		work->done = &fallback_work_done;  		wb_queue_work(wb, work); - -		/* -		 * Pin @wb so that it stays on @bdi->wb_list.  This allows -		 * continuing iteration from @wb after dropping and -		 * regrabbing rcu read lock. -		 */ -		wb_get(wb);  		last_wb = wb;  		rcu_read_unlock();  |