Commit 3968bf66 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: 2.0.18 - Fix race condition in reading of compressed files.

- There was a narrow window between checking a buffer head for being
uptodate and locking it in ntfs_file_read_compressed_block(). We now
lock the buffer and then check whether it is uptodate or not.
parent 759cec37
...@@ -247,6 +247,8 @@ ChangeLog ...@@ -247,6 +247,8 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.0.18:
- Fix race condition in reading of compressed files.
2.0.17: 2.0.17:
- Cleanups and optimizations. - Cleanups and optimizations.
2.0.16: 2.0.16:
......
...@@ -13,6 +13,14 @@ ToDo: ...@@ -13,6 +13,14 @@ ToDo:
with initialized_size < data_size. I don't think it can happen but with initialized_size < data_size. I don't think it can happen but
it requires more careful consideration. it requires more careful consideration.
- Enable NFS exporting of NTFS. - Enable NFS exporting of NTFS.
- Apply block resolution optimization from aops.c::ntfs_read_block() to
compress.c::ntfs_file_read_compressed_block() as well.
2.0.18 - Fix race condition in reading of compressed files.
- There was a narrow window between checking a buffer head for being
uptodate and locking it in ntfs_file_read_compressed_block(). We now
lock the buffer and then check whether it is uptodate or not.
2.0.17 - Cleanups and optimizations - shrinking the ToDo list. 2.0.17 - Cleanups and optimizations - shrinking the ToDo list.
......
...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.17\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.18\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
...@@ -157,7 +157,7 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index, ...@@ -157,7 +157,7 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
/* Default error code. */ /* Default error code. */
int err = -EOVERFLOW; int err = -EOVERFLOW;
ntfs_debug("Entering, cb_size = 0x%x.", cb_size); ntfs_debug("Entering, cb_size = 0x%x.", cb_size);
do_next_sb: do_next_sb:
ntfs_debug("Beginning sub-block at offset = 0x%x in the cb.", ntfs_debug("Beginning sub-block at offset = 0x%x in the cb.",
...@@ -193,7 +193,7 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index, ...@@ -193,7 +193,7 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
/* Setup offsets for the current sub-block destination. */ /* Setup offsets for the current sub-block destination. */
do_sb_start = *dest_ofs; do_sb_start = *dest_ofs;
do_sb_end = do_sb_start + NTFS_SB_SIZE; do_sb_end = do_sb_start + NTFS_SB_SIZE;
/* Check that we are still within allowed boundaries. */ /* Check that we are still within allowed boundaries. */
if (*dest_index == dest_max_index && do_sb_end > dest_max_ofs) if (*dest_index == dest_max_index && do_sb_end > dest_max_ofs)
goto return_overflow; goto return_overflow;
...@@ -572,11 +572,13 @@ int ntfs_file_read_compressed_block(struct page *page) ...@@ -572,11 +572,13 @@ int ntfs_file_read_compressed_block(struct page *page)
for (i = 0; i < nr_bhs; i++) { for (i = 0; i < nr_bhs; i++) {
struct buffer_head *tbh = bhs[i]; struct buffer_head *tbh = bhs[i];
if (buffer_uptodate(tbh)) if (unlikely(test_set_buffer_locked(tbh)))
continue; continue;
if (unlikely(buffer_uptodate(tbh))) {
lock_buffer(tbh); unlock_buffer(tbh);
get_bh(tbh); continue;
}
atomic_inc(&tbh->b_count);
tbh->b_end_io = end_buffer_io_sync; tbh->b_end_io = end_buffer_io_sync;
submit_bh(READ, tbh); submit_bh(READ, tbh);
} }
...@@ -587,9 +589,8 @@ int ntfs_file_read_compressed_block(struct page *page) ...@@ -587,9 +589,8 @@ int ntfs_file_read_compressed_block(struct page *page)
if (buffer_uptodate(tbh)) if (buffer_uptodate(tbh))
continue; continue;
wait_on_buffer(tbh); wait_on_buffer(tbh);
if (!buffer_uptodate(tbh)) if (unlikely(!buffer_uptodate(tbh)))
goto read_err; goto read_err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment