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
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:
- Cleanups and optimizations.
2.0.16:
......
......@@ -13,6 +13,14 @@ ToDo:
with initialized_size < data_size. I don't think it can happen but
it requires more careful consideration.
- 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.
......
......@@ -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 \
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)
EXTRA_CFLAGS += -DDEBUG
......
......@@ -157,7 +157,7 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
/* Default error code. */
int err = -EOVERFLOW;
ntfs_debug("Entering, cb_size = 0x%x.", cb_size);
do_next_sb:
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,
/* Setup offsets for the current sub-block destination. */
do_sb_start = *dest_ofs;
do_sb_end = do_sb_start + NTFS_SB_SIZE;
/* Check that we are still within allowed boundaries. */
if (*dest_index == dest_max_index && do_sb_end > dest_max_ofs)
goto return_overflow;
......@@ -572,11 +572,13 @@ int ntfs_file_read_compressed_block(struct page *page)
for (i = 0; i < nr_bhs; i++) {
struct buffer_head *tbh = bhs[i];
if (buffer_uptodate(tbh))
if (unlikely(test_set_buffer_locked(tbh)))
continue;
lock_buffer(tbh);
get_bh(tbh);
if (unlikely(buffer_uptodate(tbh))) {
unlock_buffer(tbh);
continue;
}
atomic_inc(&tbh->b_count);
tbh->b_end_io = end_buffer_io_sync;
submit_bh(READ, tbh);
}
......@@ -587,9 +589,8 @@ int ntfs_file_read_compressed_block(struct page *page)
if (buffer_uptodate(tbh))
continue;
wait_on_buffer(tbh);
if (!buffer_uptodate(tbh))
if (unlikely(!buffer_uptodate(tbh)))
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