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;
