Commit 759cec37 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: 2.0.17 - Cleanups and optimizations - shrinking the ToDo list.

- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to return an error
  code and update callers, i.e. ntfs_iget(), to pass that error code
  up instead of just using -EIO.
- Modifications to super.c to ensure that both mount and remount
  cannot set any write related options when the driver is compiled
  read-only.
- Optimize block resolution in fs/ntfs/aops.c::ntfs_read_block() to
  cache the current run list element. This should improve performance
  when reading very large and/or very fragmented data.
parent 4492b1b5
...@@ -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.17:
- Cleanups and optimizations.
2.0.16: 2.0.16:
- Fix stupid bug introduced in 2.0.15 in new attribute inode API. - Fix stupid bug introduced in 2.0.15 in new attribute inode API.
- Big internal cleanup replacing the mftbmp access hacks by using the - Big internal cleanup replacing the mftbmp access hacks by using the
......
...@@ -9,21 +9,23 @@ ToDo: ...@@ -9,21 +9,23 @@ ToDo:
read() will fail when s_maxbytes is reached? -> Investigate this. read() will fail when s_maxbytes is reached? -> Investigate this.
- Implement/allow non-resident index bitmaps in dir.c::ntfs_readdir() - Implement/allow non-resident index bitmaps in dir.c::ntfs_readdir()
and then also consider initialized_size w.r.t. the bitmaps, etc. and then also consider initialized_size w.r.t. the bitmaps, etc.
- vcn_to_lcn() should somehow return the correct pointer within the
->run_list so we can get at the lcns for the following vcns, this is
strictly a speed optimization. Obviously need to keep the ->run_list
locked or RACE. load_attribute_list() already performs such an
optimization so use the same optimization where desired.
- Consider if ntfs_file_read_compressed_block() shouldn't be coping - Consider if ntfs_file_read_compressed_block() shouldn't be coping
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.
- CLEANUP: Modularising code in aops.c a bit, e.g. a-la get_block(),
will be cleaner and make code reuse easier.
- Modify ntfs_read_locked_inode() to return an error code and update
callers, i.e. ntfs_iget(), to pass that error code up instead of just
using -EIO.
- Enable NFS exporting of NTFS. - Enable NFS exporting of NTFS.
2.0.17 - Cleanups and optimizations - shrinking the ToDo list.
- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to return an error
code and update callers, i.e. ntfs_iget(), to pass that error code
up instead of just using -EIO.
- Modifications to super.c to ensure that both mount and remount
cannot set any write related options when the driver is compiled
read-only.
- Optimize block resolution in fs/ntfs/aops.c::ntfs_read_block() to
cache the current run list element. This should improve performance
when reading very large and/or very fragmented data.
2.0.16 - Convert access to $MFT/$BITMAP to attribute inode API. 2.0.16 - Convert access to $MFT/$BITMAP to attribute inode API.
- Fix a stupid bug introduced in 2.0.15 where we were unmapping the - Fix a stupid bug introduced in 2.0.15 where we were unmapping the
......
...@@ -5,11 +5,15 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ...@@ -5,11 +5,15 @@ 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.16\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.17\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
endif endif
#ifeq ($(CONFIG_NTFS_RW),y)
#EXTRA_CFLAGS += -DNTFS_RW
#endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -162,6 +162,7 @@ static int ntfs_read_block(struct page *page) ...@@ -162,6 +162,7 @@ static int ntfs_read_block(struct page *page)
LCN lcn; LCN lcn;
ntfs_inode *ni; ntfs_inode *ni;
ntfs_volume *vol; ntfs_volume *vol;
run_list_element *rl;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
sector_t iblock, lblock, zblock; sector_t iblock, lblock, zblock;
unsigned int blocksize, blocks, vcn_ofs; unsigned int blocksize, blocks, vcn_ofs;
...@@ -192,6 +193,7 @@ static int ntfs_read_block(struct page *page) ...@@ -192,6 +193,7 @@ static int ntfs_read_block(struct page *page)
#endif #endif
/* Loop through all the buffers in the page. */ /* Loop through all the buffers in the page. */
rl = NULL;
nr = i = 0; nr = i = 0;
do { do {
if (unlikely(buffer_uptodate(bh))) if (unlikely(buffer_uptodate(bh)))
...@@ -210,11 +212,18 @@ static int ntfs_read_block(struct page *page) ...@@ -210,11 +212,18 @@ static int ntfs_read_block(struct page *page)
vol->cluster_size_bits; vol->cluster_size_bits;
vcn_ofs = ((VCN)iblock << blocksize_bits) & vcn_ofs = ((VCN)iblock << blocksize_bits) &
vol->cluster_size_mask; vol->cluster_size_mask;
retry_remap: if (!rl) {
/* Convert the vcn to the corresponding lcn. */ lock_retry_remap:
down_read(&ni->run_list.lock); down_read(&ni->run_list.lock);
lcn = vcn_to_lcn(ni->run_list.rl, vcn); rl = ni->run_list.rl;
up_read(&ni->run_list.lock); }
if (likely(rl != NULL)) {
/* Seek to element containing target vcn. */
while (rl->length && rl[1].vcn <= vcn)
rl++;
lcn = vcn_to_lcn(rl, vcn);
} else
lcn = (LCN)LCN_RL_NOT_MAPPED;
/* Successful remap. */ /* Successful remap. */
if (lcn >= 0) { if (lcn >= 0) {
/* Setup buffer head to correct block. */ /* Setup buffer head to correct block. */
...@@ -235,8 +244,14 @@ static int ntfs_read_block(struct page *page) ...@@ -235,8 +244,14 @@ static int ntfs_read_block(struct page *page)
/* If first try and run list unmapped, map and retry. */ /* If first try and run list unmapped, map and retry. */
if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
is_retry = TRUE; is_retry = TRUE;
/*
* Attempt to map run list, dropping lock for
* the duration.
*/
up_read(&ni->run_list.lock);
if (!map_run_list(ni, vcn)) if (!map_run_list(ni, vcn))
goto retry_remap; goto lock_retry_remap;
rl = NULL;
} }
/* Hard error, zero out region. */ /* Hard error, zero out region. */
SetPageError(page); SetPageError(page);
...@@ -261,6 +276,10 @@ static int ntfs_read_block(struct page *page) ...@@ -261,6 +276,10 @@ static int ntfs_read_block(struct page *page)
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
} while (i++, iblock++, (bh = bh->b_this_page) != head); } while (i++, iblock++, (bh = bh->b_this_page) != head);
/* Release the lock if we took it. */
if (rl)
up_read(&ni->run_list.lock);
/* Check we have at least one buffer ready for i/o. */ /* Check we have at least one buffer ready for i/o. */
if (nr) { if (nr) {
/* Lock the buffers. */ /* Lock the buffers. */
......
...@@ -964,7 +964,7 @@ int map_run_list(ntfs_inode *ni, VCN vcn) ...@@ -964,7 +964,7 @@ int map_run_list(ntfs_inode *ni, VCN vcn)
} }
down_write(&ni->run_list.lock); down_write(&ni->run_list.lock);
/* Make sure someone else didn't do the work while we were spinning. */ /* Make sure someone else didn't do the work while we were sleeping. */
if (likely(vcn_to_lcn(ni->run_list.rl, vcn) <= LCN_RL_NOT_MAPPED)) { if (likely(vcn_to_lcn(ni->run_list.rl, vcn) <= LCN_RL_NOT_MAPPED)) {
run_list_element *rl; run_list_element *rl;
......
This diff is collapsed.
...@@ -323,6 +323,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ...@@ -323,6 +323,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
if (!parse_options(vol, opt)) if (!parse_options(vol, opt))
return -EINVAL; return -EINVAL;
#ifndef NTFS_RW
*flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
#endif
return 0; return 0;
} }
...@@ -789,9 +794,6 @@ static BOOL load_system_files(ntfs_volume *vol) ...@@ -789,9 +794,6 @@ static BOOL load_system_files(ntfs_volume *vol)
ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute."); ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute.");
return FALSE; return FALSE;
} }
// FIXME: If mounting read-only, it would be ok to ignore errors when
// loading the mftbmp but we then need to make sure nobody remounts the
// volume read-write...
/* Get mft mirror inode. */ /* Get mft mirror inode. */
vol->mftmirr_ino = ntfs_iget(sb, FILE_MFTMirr); vol->mftmirr_ino = ntfs_iget(sb, FILE_MFTMirr);
...@@ -858,8 +860,8 @@ static BOOL load_system_files(ntfs_volume *vol) ...@@ -858,8 +860,8 @@ static BOOL load_system_files(ntfs_volume *vol)
le16_to_cpu(ctx->attr->_ARA(value_offset))); le16_to_cpu(ctx->attr->_ARA(value_offset)));
/* Some bounds checks. */ /* Some bounds checks. */
if ((u8*)vi < (u8*)ctx->attr || (u8*)vi + if ((u8*)vi < (u8*)ctx->attr || (u8*)vi +
le32_to_cpu(ctx->attr->_ARA(value_length)) > (u8*)ctx->attr + le32_to_cpu(ctx->attr->_ARA(value_length)) >
le32_to_cpu(ctx->attr->length)) (u8*)ctx->attr + le32_to_cpu(ctx->attr->length))
goto err_put_vol; goto err_put_vol;
/* Setup volume flags and version. */ /* Setup volume flags and version. */
vol->vol_flags = vi->flags; vol->vol_flags = vi->flags;
...@@ -1306,6 +1308,9 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1306,6 +1308,9 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
int result; int result;
ntfs_debug("Entering."); ntfs_debug("Entering.");
#ifndef NTFS_RW
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
#endif
/* Allocate a new ntfs_volume and place it in sb->u.generic_sbp. */ /* Allocate a new ntfs_volume and place it in sb->u.generic_sbp. */
sb->u.generic_sbp = kmalloc(sizeof(ntfs_volume), GFP_NOFS); sb->u.generic_sbp = kmalloc(sizeof(ntfs_volume), GFP_NOFS);
vol = NTFS_SB(sb); vol = NTFS_SB(sb);
...@@ -1346,9 +1351,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1346,9 +1351,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
if (!parse_options(vol, (char*)opt)) if (!parse_options(vol, (char*)opt))
goto err_out_now; goto err_out_now;
/* We are just a read-only fs at the moment. */
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
/* /*
* TODO: Fail safety check. In the future we should really be able to * TODO: Fail safety check. In the future we should really be able to
* cope with this being the case, but for now just bail out. * cope with this being the case, but for now just bail out.
...@@ -1623,7 +1625,7 @@ static int __init init_ntfs_fs(void) ...@@ -1623,7 +1625,7 @@ static int __init init_ntfs_fs(void)
/* This may be ugly but it results in pretty output so who cares. (-8 */ /* This may be ugly but it results in pretty output so who cares. (-8 */
printk(KERN_INFO "NTFS driver " NTFS_VERSION " [Flags: R/" printk(KERN_INFO "NTFS driver " NTFS_VERSION " [Flags: R/"
#ifdef CONFIG_NTFS_RW #ifdef NTFS_RW
"W" "W"
#else #else
"O" "O"
......
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