Commit d7ca9266 authored by Anton Altaparmakov's avatar Anton Altaparmakov Committed by Richard Russon

NTFS: Big cleanup of mft record writing code.

- Clear the page uptodate flag in fs/ntfs/aops.c::ntfs_write_mst_block()
  to ensure noone can see the page whilst the mst fixups are applied.
- Add the helper fs/ntfs/mft.c::ntfs_may_write_mft_record() which
  checks if an mft record may be written out safely obtaining any
  necessary locks in the process.  This is used by
  fs/ntfs/aops.c::ntfs_write_mst_block().
- Modify fs/ntfs/aops.c::ntfs_write_mst_block() to also work for
  writing mft records and improve its error handling in the process.
  Now if any of the records in the page fail to be written out, all
  other records will be written out instead of aborting completely.
- Remove ntfs_mft_aops and update all users to use ntfs_mst_aops.
- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to set the
  ntfs_mst_aops for all inodes which are NInoMstProtected() and
  ntfs_aops for all other inodes.
- Rename fs/ntfs/mft.c::sync_mft_mirror{,_umount}() to
  ntfs_sync_mft_mirror{,_umount}() and change their parameters so they
  no longer require an ntfs inode to be present.  Update all callers.
- Cleanup the error handling in fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- Clear the page uptodate flag in fs/ntfs/mft.c::ntfs_sync_mft_mirror()
  to ensure noone can see the page whilst the mst fixups are applied.
- Remove the no longer needed fs/ntfs/mft.c::ntfs_mft_writepage() and
  fs/ntfs/mft.c::try_map_mft_record().
- Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it
  with the ntfs inode which contains the page rather than the ntfs
  inode the mft record of which is in the page.

Ooops.  Yes, I know, I should have split this up into smaller changes...
Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent f9682e71
......@@ -85,6 +85,31 @@ ToDo/Notes:
- Provide exclusion between opening an inode / mapping an mft record
and accessing the mft record in fs/ntfs/mft.c::ntfs_mft_writepage()
by setting the page not uptodate throughout ntfs_mft_writepage().
- Clear the page uptodate flag in fs/ntfs/aops.c::ntfs_write_mst_block()
to ensure noone can see the page whilst the mst fixups are applied.
- Add the helper fs/ntfs/mft.c::ntfs_may_write_mft_record() which
checks if an mft record may be written out safely obtaining any
necessary locks in the process. This is used by
fs/ntfs/aops.c::ntfs_write_mst_block().
- Modify fs/ntfs/aops.c::ntfs_write_mst_block() to also work for
writing mft records and improve its error handling in the process.
Now if any of the records in the page fail to be written out, all
other records will be written out instead of aborting completely.
- Remove ntfs_mft_aops and update all users to use ntfs_mst_aops.
- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to set the
ntfs_mst_aops for all inodes which are NInoMstProtected() and
ntfs_aops for all other inodes.
- Rename fs/ntfs/mft.c::sync_mft_mirror{,_umount}() to
ntfs_sync_mft_mirror{,_umount}() and change their parameters so they
no longer require an ntfs inode to be present. Update all callers.
- Cleanup the error handling in fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- Clear the page uptodate flag in fs/ntfs/mft.c::ntfs_sync_mft_mirror()
to ensure noone can see the page whilst the mst fixups are applied.
- Remove the no longer needed fs/ntfs/mft.c::ntfs_mft_writepage() and
fs/ntfs/mft.c::try_map_mft_record().
- Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it
with the ntfs inode which contains the page rather than the ntfs
inode the mft record of which is in the page.
2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
......
This diff is collapsed.
......@@ -968,7 +968,6 @@ static int ntfs_read_locked_inode(struct inode *vi)
/* Setup the operations for this inode. */
vi->i_op = &ntfs_dir_inode_ops;
vi->i_fop = &ntfs_dir_ops;
vi->i_mapping->a_ops = &ntfs_mst_aops;
} else {
/* It is a file. */
ntfs_attr_reinit_search_ctx(ctx);
......@@ -1112,8 +1111,11 @@ static int ntfs_read_locked_inode(struct inode *vi)
/* Setup the operations for this inode. */
vi->i_op = &ntfs_file_inode_ops;
vi->i_fop = &ntfs_file_ops;
vi->i_mapping->a_ops = &ntfs_aops;
}
if (NInoMstProtected(ni))
vi->i_mapping->a_ops = &ntfs_mst_aops;
else
vi->i_mapping->a_ops = &ntfs_aops;
/*
* The number of 512-byte blocks used on disk (for stat). This is in so
* far inaccurate as it doesn't account for any named streams or other
......@@ -1766,7 +1768,7 @@ int ntfs_read_inode_mount(struct inode *vi)
vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number);
/* Provides readpage() and sync_page() for map_mft_record(). */
vi->i_mapping->a_ops = &ntfs_mft_aops;
vi->i_mapping->a_ops = &ntfs_mst_aops;
ctx = ntfs_attr_get_search_ctx(ni, m);
if (!ctx) {
......@@ -2028,8 +2030,6 @@ int ntfs_read_inode_mount(struct inode *vi)
/* No VFS initiated operations allowed for $MFT. */
vi->i_op = &ntfs_empty_inode_ops;
vi->i_fop = &ntfs_empty_file_ops;
/* Put back our special address space operations. */
vi->i_mapping->a_ops = &ntfs_mft_aops;
}
/* Get the lowest vcn for the next extent. */
......@@ -2514,8 +2514,8 @@ int ntfs_write_inode(struct inode *vi, int sync)
* this function returns.
*/
if (modified && !NInoTestSetDirty(ctx->ntfs_ino))
mark_ntfs_record_dirty(ctx->ntfs_ino, ctx->ntfs_ino->page,
ctx->ntfs_ino->page_ofs);
mark_ntfs_record_dirty(NTFS_I(ni->vol->mft_ino),
ctx->ntfs_ino->page, ctx->ntfs_ino->page_ofs);
ntfs_attr_put_search_ctx(ctx);
/* Now the access times are updated, write the base mft record. */
if (NInoDirty(ni))
......
This diff is collapsed.
......@@ -29,7 +29,6 @@
#include "inode.h"
extern MFT_RECORD *try_map_mft_record(ntfs_inode *ni);
extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
extern void unmap_mft_record(ntfs_inode *ni);
......@@ -77,6 +76,9 @@ static inline void mark_mft_record_dirty(ntfs_inode *ni)
__mark_mft_record_dirty(ni);
}
extern int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
MFT_RECORD *m, int sync);
extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
/**
......@@ -112,6 +114,10 @@ static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
return err;
}
extern BOOL ntfs_may_write_mft_record(ntfs_volume *vol,
const unsigned long mft_no, const MFT_RECORD *m,
ntfs_inode **locked_ni);
extern int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m);
#endif /* NTFS_RW */
......
......@@ -56,7 +56,6 @@ extern kmem_cache_t *ntfs_index_ctx_cache;
extern struct super_operations ntfs_sops;
extern struct address_space_operations ntfs_aops;
extern struct address_space_operations ntfs_mst_aops;
extern struct address_space_operations ntfs_mft_aops;
extern struct file_operations ntfs_file_ops;
extern struct inode_operations ntfs_file_inode_ops;
......
......@@ -946,8 +946,8 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
/* No VFS initiated operations allowed for $MFTMirr. */
tmp_ino->i_op = &ntfs_empty_inode_ops;
tmp_ino->i_fop = &ntfs_empty_file_ops;
/* Put back our special address space operations. */
tmp_ino->i_mapping->a_ops = &ntfs_mft_aops;
/* Put in our special address space operations. */
tmp_ino->i_mapping->a_ops = &ntfs_mst_aops;
tmp_ni = NTFS_I(tmp_ino);
/* The $MFTMirr, like the $MFT is multi sector transfer protected. */
NInoSetMstProtected(tmp_ni);
......
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