Commit e9042fae authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: Initial implementation of write(2) based overwriting of existing

files on ntfs. (Note: Resident files are not supported yet, so avoid
writing to files smaller than 1kiB.)
parent 1a683e2e
...@@ -247,6 +247,11 @@ ChangeLog ...@@ -247,6 +247,11 @@ 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.1.0:
- Add configuration option for developmental write support.
- Initial implementation of file overwriting. (Writes to resident files
are not written out to disk yet, so avoid writing to files smaller
than about 1kiB.)
2.0.25: 2.0.25:
- Minor bugfixes in error code paths and small cleanups. - Minor bugfixes in error code paths and small cleanups.
2.0.24: 2.0.24:
......
ToDo: ToDo:
- Find and fix bugs. - Find and fix bugs.
- Enable NFS exporting of NTFS. - Enable NFS exporting of NTFS.
- Implement aops->set_page_dirty() in order to take control of buffer
dirtying. Not having it means if page_has_buffers(), all buffers
will be dirtied with the page. And if not they won't be. That is
fine for the moment but will break once we enable metadata updates.
- Implement sops->dirty_inode() to implement {a,m,c} time updates and
such things.
- Implement sops->write_inode().
- In between ntfs_prepare/commit_write, need exclusion between
simultaneous file extensions. Need perhaps an NInoResizeUnderway()
flag which we can set in ntfs_prepare_write() and clear again in
ntfs_commit_write(). Just have to be careful in readpage/writepage,
as well as in truncate, that we play nice... We might need to have
a data_size field in the ntfs_inode to store the real attribute
length. Also need to be careful with initialized_size extention in
ntfs_prepare_write. Basically, just be _very_ careful in this code...
OTOH, perhaps i_sem, which is held accross generic_file_write is
sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us.
2.1.0 - First steps towards write support: implement file overwrite.
- Add configuration option for developmental write support with an
appropriately scary configuration help text.
- Initial implementation of fs/ntfs/aops.c::ntfs_writepage() and its
helper fs/ntfs/aops.c::ntfs_write_block(). This enables mmap(2) based
overwriting of existing files on ntfs. Note: Resident files are
only written into memory, and not written out to disk at present, so
avoid writing to files smaller than about 1kiB.
- Initial implementation of fs/ntfs/aops.c::ntfs_prepare_write(), its
helper fs/ntfs/aops.c::ntfs_prepare_nonresident_write() and their
counterparts, fs/ntfs/aops.c::ntfs_commit_write(), and
fs/ntfs/aops.c::ntfs_commit_nonresident_write(), respectively. Also,
add generic_file_write() to the ntfs file operations (fs/ntfs/file.c).
This enables write(2) based overwriting of existing files on ntfs.
Note: As with mmap(2) based overwriting, resident files are only
written into memory, and not written out to disk at present, so avoid
writing to files smaller than about 1kiB.
2.0.25 - Small bug fixes and cleanups. 2.0.25 - Small bug fixes and cleanups.
......
This diff is collapsed.
...@@ -1182,8 +1182,9 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len, ...@@ -1182,8 +1182,9 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len,
else { else {
register int rc; register int rc;
rc = memcmp(val, (u8*)a +le16_to_cpu(a->_ARA(value_offset)), rc = memcmp(val, (u8*)a + le16_to_cpu(
min(val_len, le32_to_cpu(a->_ARA(value_length)))); a->_ARA(value_offset)), min(val_len,
le32_to_cpu(a->_ARA(value_length))));
/* /*
* If @val collates before the current attribute's * If @val collates before the current attribute's
* value, there is no matching attribute. * value, there is no matching attribute.
......
...@@ -51,6 +51,9 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) ...@@ -51,6 +51,9 @@ static int ntfs_file_open(struct inode *vi, struct file *filp)
struct file_operations ntfs_file_ops = { struct file_operations ntfs_file_ops = {
.llseek = generic_file_llseek, /* Seek inside file. */ .llseek = generic_file_llseek, /* Seek inside file. */
.read = generic_file_read, /* Read from file. */ .read = generic_file_read, /* Read from file. */
#ifdef NTFS_RW
.write = generic_file_write, /* Write to a file. */
#endif
.mmap = generic_file_mmap, /* Mmap file. */ .mmap = generic_file_mmap, /* Mmap file. */
.sendfile = generic_file_sendfile,/* Zero-copy data send with the .sendfile = generic_file_sendfile,/* Zero-copy data send with the
data source being on the data source being on the
......
...@@ -98,7 +98,7 @@ int format_mft_record(ntfs_inode *ni, MFT_RECORD *mft_rec) ...@@ -98,7 +98,7 @@ int format_mft_record(ntfs_inode *ni, MFT_RECORD *mft_rec)
} }
/** /**
* From fs/ntfs/aops.c * ntfs_readpage - external declaration, function is in fs/ntfs/aops.c
*/ */
extern int ntfs_readpage(struct file *, struct page *); extern int ntfs_readpage(struct file *, struct page *);
...@@ -109,12 +109,9 @@ extern int ntfs_readpage(struct file *, struct page *); ...@@ -109,12 +109,9 @@ extern int ntfs_readpage(struct file *, struct page *);
* ntfs_map_page() in map_mft_record_page(). * ntfs_map_page() in map_mft_record_page().
*/ */
struct address_space_operations ntfs_mft_aops = { struct address_space_operations ntfs_mft_aops = {
.writepage = NULL, /* Write dirty page to disk. */
.readpage = ntfs_readpage, /* Fill page with data. */ .readpage = ntfs_readpage, /* Fill page with data. */
.sync_page = block_sync_page, /* Currently, just unplugs the .sync_page = block_sync_page, /* Currently, just unplugs the
disk request queue. */ disk request queue. */
.prepare_write = NULL, /* . */
.commit_write = NULL, /* . */
}; };
/** /**
......
...@@ -43,5 +43,19 @@ static inline void unmap_extent_mft_record(ntfs_inode *ni) ...@@ -43,5 +43,19 @@ static inline void unmap_extent_mft_record(ntfs_inode *ni)
return; return;
} }
/*
* flush_dcache_mft_record_page - flush_dcache_page() for mft records
* @ni: ntfs inode structure of mft record
*
* Call flush_dcache_page() for the page in which an mft record resides.
*
* This must be called every time an mft record is modified, just after the
* modification.
*/
static inline void flush_dcache_mft_record_page(ntfs_inode *ni)
{
flush_dcache_page(ni->page);
}
#endif /* _LINUX_NTFS_MFT_H */ #endif /* _LINUX_NTFS_MFT_H */
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