summaryrefslogtreecommitdiff
path: root/fs/ntfs3/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs3/bitmap.c')
-rw-r--r--fs/ntfs3/bitmap.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
index 04107b950717..60b362f388d9 100644
--- a/fs/ntfs3/bitmap.c
+++ b/fs/ntfs3/bitmap.c
@@ -508,6 +508,8 @@ static int wnd_rescan(struct wnd_bitmap *wnd)
size_t wpos, wbit, iw, vbo;
struct buffer_head *bh = NULL;
CLST lcn, clen;
+ struct file_ra_state *ra;
+ struct address_space *mapping = sb->s_bdev->bd_mapping;
wnd->uptodated = 0;
wnd->extent_max = 0;
@@ -516,6 +518,13 @@ static int wnd_rescan(struct wnd_bitmap *wnd)
vbo = 0;
+ /* Allocate in memory instead of stack. Not critical if failed. */
+ ra = kzalloc_obj(*ra, GFP_NOFS);
+ if (ra) {
+ file_ra_state_init(ra, mapping);
+ ra->ra_pages = (wnd->nbits / 8 + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ }
+
for (iw = 0; iw < wnd->nwnd; iw++) {
if (iw + 1 == wnd->nwnd)
wbits = wnd->bits_last;
@@ -552,6 +561,13 @@ static int wnd_rescan(struct wnd_bitmap *wnd)
len = ((u64)clen << cluster_bits) - off;
}
+ if (ra) {
+ pgoff_t idx = lbo >> PAGE_SHIFT;
+ if (!ra_has_index(ra, idx))
+ page_cache_sync_readahead(mapping, ra, NULL,
+ idx, 1);
+ }
+
bh = ntfs_bread(sb, lbo >> sb->s_blocksize_bits);
if (!bh) {
err = -EIO;
@@ -638,6 +654,7 @@ next_wnd:
}
out:
+ kfree(ra);
return err;
}
@@ -1371,6 +1388,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits)
mark_buffer_dirty(bh);
unlock_buffer(bh);
/* err = sync_dirty_buffer(bh); */
+ put_bh(bh);
b0 = 0;
bits -= op;