http://linux-ntfs.bkbits.net/ntfs-2.6 aia21@cantab.net|ChangeSet|20040525153128|15453 aia21 # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/05/25 16:31:28+01:00 aia21@cantab.net # NTFS: Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also # includes an adapted ntfs_commit_inode() and an implementation of # ntfs_write_inode() which for now just cleans dirty inodes without # writing them (it does emit a warning that this is happening). # # fs/ntfs/inode.h # 2004/05/25 16:31:22+01:00 aia21@cantab.net +9 -0 # Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also # includes an adapted ntfs_commit_inode() and an implementation of # ntfs_write_inode() which for now just cleans dirty inodes without # writing them (it does emit a warning that this is happening). # # fs/ntfs/inode.c # 2004/05/25 16:31:22+01:00 aia21@cantab.net +84 -41 # Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also # includes an adapted ntfs_commit_inode() and an implementation of # ntfs_write_inode() which for now just cleans dirty inodes without # writing them (it does emit a warning that this is happening). # # fs/ntfs/dir.c # 2004/05/25 16:31:22+01:00 aia21@cantab.net +1 -1 # Change a rogue a debug message to print inode number in hex, not decimal. # # fs/ntfs/ChangeLog # 2004/05/25 16:31:21+01:00 aia21@cantab.net +4 -0 # Update. # # fs/ntfs/super.c # 2004/05/20 14:52:43+01:00 aia21@cantab.net +1 -1 # Improve comment. # # fs/ntfs/inode.c # 2004/05/20 14:52:43+01:00 aia21@cantab.net +1 -1 # Improve comment. # # ChangeSet # 2004/05/17 22:45:04+01:00 aia21@cantab.net # NTFS: Add a new address space operations struct, ntfs_mst_aops, for mst # protected attributes. This is because the default ntfs_aops do not # make sense with mst protected data and were they to write anything to # such an attribute they would cause data corruption so we provide # ntfs_mst_aops which does not have any write related operations set. # # fs/ntfs/ntfs.h # 2004/05/17 22:42:28+01:00 aia21@cantab.net +1 -0 # Add a new address space operations struct, ntfs_mst_aops, for mst # protected attributes. # # fs/ntfs/inode.c # 2004/05/17 22:42:15+01:00 aia21@cantab.net +5 -2 # Add a new address space operations struct, ntfs_mst_aops, for mst # protected attributes. # # fs/ntfs/aops.c # 2004/05/17 22:41:44+01:00 aia21@cantab.net +9 -0 # Add a new address space operations struct, ntfs_mst_aops, for mst # protected attributes. # # fs/ntfs/Makefile # 2004/05/17 22:41:38+01:00 aia21@cantab.net +1 -1 # Update # # fs/ntfs/ChangeLog # 2004/05/17 22:41:31+01:00 aia21@cantab.net +8 -0 # Update # diff -Nru a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog --- a/fs/ntfs/ChangeLog 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/ChangeLog 2004-05-25 21:31:52 -07:00 @@ -25,6 +25,18 @@ sufficient for synchronisation here. We then just need to make sure ntfs_readpage/writepage/truncate interoperate properly with us. +2.1.12 - WIP. + + - Add a new address space operations struct, ntfs_mst_aops, for mst + protected attributes. This is because the default ntfs_aops do not + make sense with mst protected data and were they to write anything to + such an attribute they would cause data corruption so we provide + ntfs_mst_aops which does not have any write related operations set. + - Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also + includes an adapted ntfs_commit_inode() and an implementation of + ntfs_write_inode() which for now just cleans dirty inodes without + writing them (it does emit a warning that this is happening). + 2.1.11 - Driver internal cleanups. - Only build logfile.o if building the driver with read-write support. diff -Nru a/fs/ntfs/Makefile b/fs/ntfs/Makefile --- a/fs/ntfs/Makefile 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/Makefile 2004-05-25 21:31:52 -07:00 @@ -5,7 +5,7 @@ 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 unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.11\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.12-WIP\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c --- a/fs/ntfs/aops.c 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/aops.c 2004-05-25 21:31:52 -07:00 @@ -1788,3 +1788,12 @@ #endif }; +/** + * ntfs_mst_aops - general address space operations for mst protecteed inodes + * and attributes + */ +struct address_space_operations ntfs_mst_aops = { + .readpage = ntfs_readpage, /* Fill page with data. */ + .sync_page = block_sync_page, /* Currently, just unplugs the + disk request queue. */ +}; diff -Nru a/fs/ntfs/dir.c b/fs/ntfs/dir.c --- a/fs/ntfs/dir.c 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/dir.c 2004-05-25 21:31:52 -07:00 @@ -1196,7 +1196,7 @@ ia_mapping = vdir->i_mapping; bmp_vi = ndir->itype.index.bmp_ino; if (unlikely(!bmp_vi)) { - ntfs_debug("Inode %lu, regetting index bitmap.", vdir->i_ino); + ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); if (unlikely(IS_ERR(bmp_vi))) { ntfs_error(sb, "Failed to get bitmap attribute."); diff -Nru a/fs/ntfs/inode.c b/fs/ntfs/inode.c --- a/fs/ntfs/inode.c 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/inode.c 2004-05-25 21:31:52 -07:00 @@ -872,7 +872,7 @@ /* 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_aops; + vi->i_mapping->a_ops = &ntfs_mst_aops; } else { /* It is a file. */ reinit_attr_search_ctx(ctx); @@ -1249,7 +1249,10 @@ /* Setup the operations for this attribute inode. */ vi->i_op = NULL; vi->i_fop = NULL; - 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; if (!NInoCompressed(ni)) vi->i_blocks = ni->allocated_size >> 9; @@ -1339,7 +1342,7 @@ ni->name_len = 0; /* - * This sets up our little cheat allowing us to reuse the async io + * This sets up our little cheat allowing us to reuse the async read io * completion handler for directories. */ ni->itype.index.block_size = vol->mft_record_size; @@ -1703,18 +1706,6 @@ } /** - * ntfs_commit_inode - write out a dirty inode - * @ni: inode to write out - * - */ -int ntfs_commit_inode(ntfs_inode *ni) -{ - ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); - NInoClearDirty(ni); - return 0; -} - -/** * ntfs_put_inode - handler for when the inode reference count is decremented * @vi: vfs inode * @@ -1742,34 +1733,6 @@ void __ntfs_clear_inode(ntfs_inode *ni) { - int err; - - ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); - if (NInoDirty(ni)) { - err = ntfs_commit_inode(ni); - if (err) { - ntfs_error(ni->vol->sb, "Failed to commit dirty " - "inode synchronously."); - // FIXME: Do something!!! - } - } - /* Synchronize with ntfs_commit_inode(). */ - down(&ni->mrec_lock); - up(&ni->mrec_lock); - if (NInoDirty(ni)) { - ntfs_error(ni->vol->sb, "Failed to commit dirty inode " - "asynchronously."); - // FIXME: Do something!!! - } - /* No need to lock at this stage as no one else has a reference. */ - if (ni->nr_extents > 0) { - int i; - - // FIXME: Handle dirty case for each extent inode! - for (i = 0; i < ni->nr_extents; i++) - ntfs_clear_extent_inode(ni->ext.extent_ntfs_inos[i]); - kfree(ni->ext.extent_ntfs_inos); - } /* Free all alocated memory. */ down_write(&ni->run_list.lock); if (ni->run_list.rl) { @@ -1799,6 +1762,20 @@ void ntfs_clear_extent_inode(ntfs_inode *ni) { + ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); + + BUG_ON(NInoAttr(ni)); + BUG_ON(ni->nr_extents != -1); + +#ifdef NTFS_RW + if (NInoDirty(ni)) { + if (!is_bad_inode(VFS_I(ni->ext.base_ntfs_ino))) + ntfs_error(ni->vol->sb, "Clearing dirty extent inode! " + "Losing data! This is a BUG!!!"); + // FIXME: Do something!!! + } +#endif /* NTFS_RW */ + __ntfs_clear_inode(ni); /* Bye, bye... */ @@ -1819,6 +1796,30 @@ { ntfs_inode *ni = NTFS_I(vi); +#ifdef NTFS_RW + if (NInoDirty(ni)) { + BOOL was_bad = (is_bad_inode(vi)); + + /* Committing the inode also commits all extent inodes. */ + ntfs_commit_inode(vi); + + if (!was_bad && (is_bad_inode(vi) || NInoDirty(ni))) { + ntfs_error(vi->i_sb, "Failed to commit dirty inode " + "0x%lx. Losing data!", vi->i_ino); + // FIXME: Do something!!! + } + } +#endif /* NTFS_RW */ + + /* No need to lock at this stage as no one else has a reference. */ + if (ni->nr_extents > 0) { + int i; + + for (i = 0; i < ni->nr_extents; i++) + ntfs_clear_extent_inode(ni->ext.extent_ntfs_inos[i]); + kfree(ni->ext.extent_ntfs_inos); + } + __ntfs_clear_inode(ni); if (NInoAttr(ni)) { @@ -1959,4 +1960,49 @@ return err; } -#endif +void ntfs_write_inode(struct inode *vi, int sync) +{ + ntfs_inode *ni = NTFS_I(vi); + + ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", + vi->i_ino); + + /* + * Dirty attribute inodes are written via their real inodes so just + * clean them here. + */ + if (NInoAttr(ni)) { + NInoClearDirty(ni); + return; + } + + /* Write this base mft record. */ + if (NInoDirty(ni)) { + ntfs_warning(vi->i_sb, "Cleaning dirty inode 0x%lx without " + "writing to disk as this is not yet " + "implemented.", vi->i_ino); + NInoClearDirty(ni); + } + + /* Write all attached extent mft records. */ + down(&ni->extent_lock); + if (ni->nr_extents > 0) { + int i; + ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos; + + for (i = 0; i < ni->nr_extents; i++) { + ntfs_inode *tni = extent_nis[i]; + + if (NInoDirty(tni)) { + ntfs_warning(vi->i_sb, "Cleaning dirty extent " + "inode 0x%lx without writing " + "to disk as this is not yet " + "implemented.", tni->mft_no); + NInoClearDirty(tni); + } + } + } + up(&ni->extent_lock); +} + +#endif /* NTFS_RW */ diff -Nru a/fs/ntfs/inode.h b/fs/ntfs/inode.h --- a/fs/ntfs/inode.h 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/inode.h 2004-05-25 21:31:52 -07:00 @@ -281,6 +281,15 @@ extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr); +extern void ntfs_write_inode(struct inode *vi, int sync); + +static inline void ntfs_commit_inode(struct inode *vi) +{ + if (!is_bad_inode(vi)) + ntfs_write_inode(vi, 1); + return; +} + #endif /* NTFS_RW */ #endif /* _LINUX_NTFS_INODE_H */ diff -Nru a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h --- a/fs/ntfs/ntfs.h 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/ntfs.h 2004-05-25 21:31:52 -07:00 @@ -62,6 +62,7 @@ /* The various operations structs defined throughout the driver files. */ 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; diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c --- a/fs/ntfs/super.c 2004-05-25 21:31:52 -07:00 +++ b/fs/ntfs/super.c 2004-05-25 21:31:52 -07:00 @@ -763,7 +763,7 @@ /* The $MFTMirr, like the $MFT is multi sector transfer protected. */ NInoSetMstProtected(tmp_ni); /* - * Set up our little cheat allowing us to reuse the async io + * Set up our little cheat allowing us to reuse the async read io * completion handler for directories. */ tmp_ni->itype.index.block_size = vol->mft_record_size;