Loading fs/buffer.c +45 −2 Original line number Diff line number Diff line Loading @@ -1392,12 +1392,48 @@ static bool has_bh_in_lru(int cpu, void *dummy) return 0; } static void __evict_bh_lru(void *arg) { struct bh_lru *b = &get_cpu_var(bh_lrus); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) { brelse(b->bhs[i]); b->bhs[i] = NULL; goto out; } } out: put_cpu_var(bh_lrus); } static bool bh_exists_in_lru(int cpu, void *arg) { struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) return true; } return false; } void invalidate_bh_lrus(void) { on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL); } EXPORT_SYMBOL_GPL(invalidate_bh_lrus); static void evict_bh_lrus(struct buffer_head *bh) { on_each_cpu_cond(bh_exists_in_lru, __evict_bh_lru, bh, 1, GFP_ATOMIC); } void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset) { Loading Loading @@ -3238,8 +3274,15 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free) bh = head; do { if (buffer_busy(bh)) { /* * Check if the busy failure was due to an * outstanding LRU reference */ evict_bh_lrus(bh); if (buffer_busy(bh)) goto failed; } bh = bh->b_this_page; } while (bh != head); Loading Loading
fs/buffer.c +45 −2 Original line number Diff line number Diff line Loading @@ -1392,12 +1392,48 @@ static bool has_bh_in_lru(int cpu, void *dummy) return 0; } static void __evict_bh_lru(void *arg) { struct bh_lru *b = &get_cpu_var(bh_lrus); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) { brelse(b->bhs[i]); b->bhs[i] = NULL; goto out; } } out: put_cpu_var(bh_lrus); } static bool bh_exists_in_lru(int cpu, void *arg) { struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) return true; } return false; } void invalidate_bh_lrus(void) { on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL); } EXPORT_SYMBOL_GPL(invalidate_bh_lrus); static void evict_bh_lrus(struct buffer_head *bh) { on_each_cpu_cond(bh_exists_in_lru, __evict_bh_lru, bh, 1, GFP_ATOMIC); } void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset) { Loading Loading @@ -3238,8 +3274,15 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free) bh = head; do { if (buffer_busy(bh)) { /* * Check if the busy failure was due to an * outstanding LRU reference */ evict_bh_lrus(bh); if (buffer_busy(bh)) goto failed; } bh = bh->b_this_page; } while (bh != head); Loading