Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NTFS: Improve scalability by changing the driver global spin lock in fs/ntfs/aops.c::ntfs_end_buffer_async_read() to a bit spin lock in the first buffer head of a page.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

+12 -6
+3
fs/ntfs/ChangeLog
··· 86 86 - Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case 87 87 where a concurrent truncate has truncated the runlist under our feet. 88 88 - Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c. 89 + - In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock 90 + in the first buffer head instead of a driver global spin lock to 91 + improve scalability. 89 92 90 93 2.1.23 - Implement extension of resident files and make writing safe as well as 91 94 many bug fixes, cleanups, and enhancements...
+9 -6
fs/ntfs/aops.c
··· 55 55 */ 56 56 static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) 57 57 { 58 - static DEFINE_SPINLOCK(page_uptodate_lock); 59 58 unsigned long flags; 60 - struct buffer_head *tmp; 59 + struct buffer_head *first, *tmp; 61 60 struct page *page; 62 61 ntfs_inode *ni; 63 62 int page_uptodate = 1; ··· 88 89 } 89 90 } else { 90 91 clear_buffer_uptodate(bh); 92 + SetPageError(page); 91 93 ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.", 92 94 (unsigned long long)bh->b_blocknr); 93 - SetPageError(page); 94 95 } 95 - spin_lock_irqsave(&page_uptodate_lock, flags); 96 + first = page_buffers(page); 97 + local_irq_save(flags); 98 + bit_spin_lock(BH_Uptodate_Lock, &first->b_state); 96 99 clear_buffer_async_read(bh); 97 100 unlock_buffer(bh); 98 101 tmp = bh; ··· 109 108 } 110 109 tmp = tmp->b_this_page; 111 110 } while (tmp != bh); 112 - spin_unlock_irqrestore(&page_uptodate_lock, flags); 111 + bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); 112 + local_irq_restore(flags); 113 113 /* 114 114 * If none of the buffers had errors then we can set the page uptodate, 115 115 * but we first have to perform the post read mst fixups, if the ··· 143 141 unlock_page(page); 144 142 return; 145 143 still_busy: 146 - spin_unlock_irqrestore(&page_uptodate_lock, flags); 144 + bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); 145 + local_irq_restore(flags); 147 146 return; 148 147 } 149 148