All of lore.kernel.org
 help / color / mirror / Atom feed
* [2.6-GIT] NTFS: Release 2.1.24.
@ 2005-09-09  9:18 Anton Altaparmakov
  2005-09-09  9:19 ` [PATCH 1/25] NTFS: Support more clean journal ($LogFile) states Anton Altaparmakov
                   ` (26 more replies)
  0 siblings, 27 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:18 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

Hi Linus, please pull from

rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD

This is the next NTFS update containing a ton of bug fixes several of 
which fix bugs people actually hit in the big bad world...

Please apply.  Thanks!

I am sending the changesets as actual patches generated using git 
format-patch for non-git users in follow up emails (in reply to this one).

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 1/25] NTFS: Support more clean journal ($LogFile) states.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
@ 2005-09-09  9:19 ` Anton Altaparmakov
  2005-09-09  9:19 ` [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version Anton Altaparmakov
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:19 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: Support more clean journal ($LogFile) states.

      - Support journals ($LogFile) which have been modified by chkdsk.  This
        means users can boot into Windows after we marked the volume dirty.
        The Windows boot will run chkdsk and then reboot.  The user can then
        immediately boot into Linux rather than having to do a full Windows
        boot first before rebooting into Linux and we will recognize such a
        journal and empty it as it is clean by definition.
      - Support journals ($LogFile) with only one restart page as well as
        journals with two different restart pages.  We sanity check both and
        either use the only sane one or the more recent one of the two in the
        case that both are valid.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |   13 +++
 fs/ntfs/Makefile  |    2 
 fs/ntfs/logfile.c |  255 +++++++++++++++++++++++++++++------------------------
 fs/ntfs/logfile.h |    8 +-
 fs/ntfs/super.c   |   16 ++-
 5 files changed, 169 insertions(+), 125 deletions(-)

e7a1033b946f4f2622f2b338ab107f559aad542c
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,6 +22,19 @@ ToDo/Notes:
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
+2.1.24-WIP
+
+	- Support journals ($LogFile) which have been modified by chkdsk.  This
+	  means users can boot into Windows after we marked the volume dirty.
+	  The Windows boot will run chkdsk and then reboot.  The user can then
+	  immediately boot into Linux rather than having to do a full Windows
+	  boot first before rebooting into Linux and we will recognize such a
+	  journal and empty it as it is clean by definition.
+	- Support journals ($LogFile) with only one restart page as well as
+	  journals with two different restart pages.  We sanity check both and
+	  either use the only sane one or the more recent one of the two in the
+	  case that both are valid.
+
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
 
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
 	     index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
 	     unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24-WIP\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -121,7 +121,7 @@ static BOOL ntfs_check_restart_page_head
 	 */
 	if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
 		ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
-				"chkdsk but a chkdsk LSN is specified.");
+				"by chkdsk but a chkdsk LSN is specified.");
 		return FALSE;
 	}
 	ntfs_debug("Done.");
@@ -312,10 +312,12 @@ err_out:
  * @vi:		$LogFile inode to which the restart page belongs
  * @rp:		restart page to check
  * @pos:	position in @vi at which the restart page resides
- * @wrp:	copy of the multi sector transfer deprotected restart page
+ * @wrp:	[OUT] copy of the multi sector transfer deprotected restart page
+ * @lsn:	[OUT] set to the current logfile lsn on success
  *
- * Check the restart page @rp for consistency and return TRUE if it is
- * consistent and FALSE otherwise.
+ * Check the restart page @rp for consistency and return 0 if it is consistent
+ * and -errno otherwise.  The restart page may have been modified by chkdsk in
+ * which case its magic is CHKD instead of RSTR.
  *
  * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
  * require the full restart page.
@@ -323,25 +325,33 @@ err_out:
  * If @wrp is not NULL, on success, *@wrp will point to a buffer containing a
  * copy of the complete multi sector transfer deprotected page.  On failure,
  * *@wrp is undefined.
+ *
+ * Simillarly, if @lsn is not NULL, on succes *@lsn will be set to the current
+ * logfile lsn according to this restart page.  On failure, *@lsn is undefined.
+ *
+ * The following error codes are defined:
+ *	-EINVAL	- The restart page is inconsistent.
+ *	-ENOMEM	- Not enough memory to load the restart page.
+ *	-EIO	- Failed to reading from $LogFile.
  */
-static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
-		RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp)
+static int ntfs_check_and_load_restart_page(struct inode *vi,
+		RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp,
+		LSN *lsn)
 {
 	RESTART_AREA *ra;
 	RESTART_PAGE_HEADER *trp;
-	int size;
-	BOOL ret;
+	int size, err;
 
 	ntfs_debug("Entering.");
 	/* Check the restart page header for consistency. */
 	if (!ntfs_check_restart_page_header(vi, rp, pos)) {
 		/* Error output already done inside the function. */
-		return FALSE;
+		return -EINVAL;
 	}
 	/* Check the restart area for consistency. */
 	if (!ntfs_check_restart_area(vi, rp)) {
 		/* Error output already done inside the function. */
-		return FALSE;
+		return -EINVAL;
 	}
 	ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
 	/*
@@ -352,7 +362,7 @@ static BOOL ntfs_check_and_load_restart_
 	if (!trp) {
 		ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
 				"restart page buffer.");
-		return FALSE;
+		return -ENOMEM;
 	}
 	/*
 	 * Read the whole of the restart page into the buffer.  If it fits
@@ -379,6 +389,9 @@ static BOOL ntfs_check_and_load_restart_
 			if (IS_ERR(page)) {
 				ntfs_error(vi->i_sb, "Error mapping $LogFile "
 						"page (index %lu).", idx);
+				err = PTR_ERR(page);
+				if (err != -EIO && err != -ENOMEM)
+					err = -EIO;
 				goto err_out;
 			}
 			size = min_t(int, to_read, PAGE_CACHE_SIZE);
@@ -392,29 +405,57 @@ static BOOL ntfs_check_and_load_restart_
 	/* Perform the multi sector transfer deprotection on the buffer. */
 	if (post_read_mst_fixup((NTFS_RECORD*)trp,
 			le32_to_cpu(rp->system_page_size))) {
-		ntfs_error(vi->i_sb, "Multi sector transfer error detected in "
-				"$LogFile restart page.");
-		goto err_out;
-	}
-	/* Check the log client records for consistency. */
-	ret = ntfs_check_log_client_array(vi, trp);
-	if (ret && wrp)
-		*wrp = trp;
-	else
-		ntfs_free(trp);
+		/*
+		 * A multi sector tranfer error was detected.  We only need to
+		 * abort if the restart page contents exceed the multi sector
+		 * transfer fixup of the first sector.
+		 */
+		if (le16_to_cpu(rp->restart_area_offset) +
+				le16_to_cpu(ra->restart_area_length) >
+				NTFS_BLOCK_SIZE - sizeof(u16)) {
+			ntfs_error(vi->i_sb, "Multi sector transfer error "
+					"detected in $LogFile restart page.");
+			err = -EINVAL;
+			goto err_out;
+		}
+	}
+	/*
+	 * If the restart page is modified by chkdsk or there are no active
+	 * logfile clients, the logfile is consistent.  Otherwise, need to
+	 * check the log client records for consistency, too.
+	 */
+	err = 0;
+	if (ntfs_is_rstr_record(rp->magic) &&
+			ra->client_in_use_list != LOGFILE_NO_CLIENT) {
+		if (!ntfs_check_log_client_array(vi, trp)) {
+			err = -EINVAL;
+			goto err_out;
+		}
+	}
+	if (lsn) {
+		if (ntfs_is_rstr_record(rp->magic))
+			*lsn = sle64_to_cpu(ra->current_lsn);
+		else /* if (ntfs_is_chkd_record(rp->magic)) */
+			*lsn = sle64_to_cpu(rp->chkdsk_lsn);
+	}
 	ntfs_debug("Done.");
-	return ret;
+	if (wrp)
+		*wrp = trp;
+	else {
 err_out:
-	ntfs_free(trp);
-	return FALSE;
+		ntfs_free(trp);
+	}
+	return err;
 }
 
 /**
  * ntfs_check_logfile - check the journal for consistency
  * @log_vi:	struct inode of loaded journal $LogFile to check
+ * @rp:		[OUT] on success this is a copy of the current restart page
  *
  * Check the $LogFile journal for consistency and return TRUE if it is
- * consistent and FALSE if not.
+ * consistent and FALSE if not.  On success, the current restart page is
+ * returned in *@rp.  Caller must call ntfs_free(*@rp) when finished with it.
  *
  * At present we only check the two restart pages and ignore the log record
  * pages.
@@ -424,19 +465,18 @@ err_out:
  * if the $LogFile was created on a system with a different page size to ours
  * yet and mst deprotection would fail if our page size is smaller.
  */
-BOOL ntfs_check_logfile(struct inode *log_vi)
+BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
 {
-	s64 size, pos, rstr1_pos, rstr2_pos;
+	s64 size, pos;
+	LSN rstr1_lsn, rstr2_lsn;
 	ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
 	struct address_space *mapping = log_vi->i_mapping;
 	struct page *page = NULL;
 	u8 *kaddr = NULL;
 	RESTART_PAGE_HEADER *rstr1_ph = NULL;
 	RESTART_PAGE_HEADER *rstr2_ph = NULL;
-	int log_page_size, log_page_mask, ofs;
+	int log_page_size, log_page_mask, err;
 	BOOL logfile_is_empty = TRUE;
-	BOOL rstr1_found = FALSE;
-	BOOL rstr2_found = FALSE;
 	u8 log_page_bits;
 
 	ntfs_debug("Entering.");
@@ -491,7 +531,7 @@ BOOL ntfs_check_logfile(struct inode *lo
 			if (IS_ERR(page)) {
 				ntfs_error(vol->sb, "Error mapping $LogFile "
 						"page (index %lu).", idx);
-				return FALSE;
+				goto err_out;
 			}
 		}
 		kaddr = (u8*)page_address(page) + (pos & ~PAGE_CACHE_MASK);
@@ -510,99 +550,95 @@ BOOL ntfs_check_logfile(struct inode *lo
 		 */
 		if (ntfs_is_rcrd_recordp((le32*)kaddr))
 			break;
-		/*
-		 * A modified by chkdsk restart page means we cannot handle
-		 * this log file.
-		 */
-		if (ntfs_is_chkd_recordp((le32*)kaddr)) {
-			ntfs_error(vol->sb, "$LogFile has been modified by "
-					"chkdsk.  Mount this volume in "
-					"Windows.");
-			goto err_out;
-		}
-		/* If not a restart page, continue. */
-		if (!ntfs_is_rstr_recordp((le32*)kaddr)) {
-			/* Skip to the minimum page size for the next one. */
+		/* If not a (modified by chkdsk) restart page, continue. */
+		if (!ntfs_is_rstr_recordp((le32*)kaddr) &&
+				!ntfs_is_chkd_recordp((le32*)kaddr)) {
 			if (!pos)
 				pos = NTFS_BLOCK_SIZE >> 1;
 			continue;
 		}
-		/* We now know we have a restart page. */
-		if (!pos) {
-			rstr1_found = TRUE;
-			rstr1_pos = pos;
-		} else {
-			if (rstr2_found) {
-				ntfs_error(vol->sb, "Found more than two "
-						"restart pages in $LogFile.");
-				goto err_out;
-			}
-			rstr2_found = TRUE;
-			rstr2_pos = pos;
-		}
 		/*
-		 * Check the restart page for consistency and get a copy of the
-		 * complete multi sector transfer deprotected restart page.
+		 * Check the (modified by chkdsk) restart page for consistency
+		 * and get a copy of the complete multi sector transfer
+		 * deprotected restart page.
 		 */
-		if (!ntfs_check_and_load_restart_page(log_vi,
+		err = ntfs_check_and_load_restart_page(log_vi,
 				(RESTART_PAGE_HEADER*)kaddr, pos,
-				!pos ? &rstr1_ph : &rstr2_ph)) {
-			/* Error output already done inside the function. */
-			goto err_out;
+				!rstr1_ph ? &rstr1_ph : &rstr2_ph,
+				!rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
+		if (!err) {
+			/*
+			 * If we have now found the first (modified by chkdsk)
+			 * restart page, continue looking for the second one.
+			 */
+			if (!pos) {
+				pos = NTFS_BLOCK_SIZE >> 1;
+				continue;
+			}
+			/*
+			 * We have now found the second (modified by chkdsk)
+			 * restart page, so we can stop looking.
+			 */
+			break;
 		}
 		/*
-		 * We have a valid restart page.  The next one must be after
-		 * a whole system page size as specified by the valid restart
-		 * page.
+		 * Error output already done inside the function.  Note, we do
+		 * not abort if the restart page was invalid as we might still
+		 * find a valid one further in the file.
 		 */
+		if (err != -EINVAL) {
+			ntfs_unmap_page(page);
+			goto err_out;
+		}
+		/* Continue looking. */
 		if (!pos)
-			pos = le32_to_cpu(rstr1_ph->system_page_size) >> 1;
+			pos = NTFS_BLOCK_SIZE >> 1;
 	}
-	if (page) {
+	if (page)
 		ntfs_unmap_page(page);
-		page = NULL;
-	}
 	if (logfile_is_empty) {
 		NVolSetLogFileEmpty(vol);
 is_empty:
 		ntfs_debug("Done.  ($LogFile is empty.)");
 		return TRUE;
 	}
-	if (!rstr1_found || !rstr2_found) {
-		ntfs_error(vol->sb, "Did not find two restart pages in "
-				"$LogFile.");
-		goto err_out;
-	}
-	/*
-	 * The two restart areas must be identical except for the update
-	 * sequence number.
-	 */
-	ofs = le16_to_cpu(rstr1_ph->usa_ofs);
-	if (memcmp(rstr1_ph, rstr2_ph, ofs) || (ofs += sizeof(u16),
-			memcmp((u8*)rstr1_ph + ofs, (u8*)rstr2_ph + ofs,
-			le32_to_cpu(rstr1_ph->system_page_size) - ofs))) {
-		ntfs_error(vol->sb, "The two restart pages in $LogFile do not "
-				"match.");
-		goto err_out;
+	if (!rstr1_ph) {
+		BUG_ON(rstr2_ph);
+		ntfs_error(vol->sb, "Did not find any restart pages in "
+				"$LogFile and it was not empty.");
+		return FALSE;
+	}
+	/* If both restart pages were found, use the more recent one. */
+	if (rstr2_ph) {
+		/*
+		 * If the second restart area is more recent, switch to it.
+		 * Otherwise just throw it away.
+		 */
+		if (rstr2_lsn > rstr1_lsn) {
+			ntfs_free(rstr1_ph);
+			rstr1_ph = rstr2_ph;
+			/* rstr1_lsn = rstr2_lsn; */
+		} else
+			ntfs_free(rstr2_ph);
+		rstr2_ph = NULL;
 	}
-	ntfs_free(rstr1_ph);
-	ntfs_free(rstr2_ph);
 	/* All consistency checks passed. */
+	if (rp)
+		*rp = rstr1_ph;
+	else
+		ntfs_free(rstr1_ph);
 	ntfs_debug("Done.");
 	return TRUE;
 err_out:
-	if (page)
-		ntfs_unmap_page(page);
 	if (rstr1_ph)
 		ntfs_free(rstr1_ph);
-	if (rstr2_ph)
-		ntfs_free(rstr2_ph);
 	return FALSE;
 }
 
 /**
  * ntfs_is_logfile_clean - check in the journal if the volume is clean
  * @log_vi:	struct inode of loaded journal $LogFile to check
+ * @rp:		copy of the current restart page
  *
  * Analyze the $LogFile journal and return TRUE if it indicates the volume was
  * shutdown cleanly and FALSE if not.
@@ -619,11 +655,9 @@ err_out:
  * is empty this function requires that NVolLogFileEmpty() is true otherwise an
  * empty volume will be reported as dirty.
  */
-BOOL ntfs_is_logfile_clean(struct inode *log_vi)
+BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
 {
 	ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
-	struct page *page;
-	RESTART_PAGE_HEADER *rp;
 	RESTART_AREA *ra;
 
 	ntfs_debug("Entering.");
@@ -632,23 +666,14 @@ BOOL ntfs_is_logfile_clean(struct inode 
 		ntfs_debug("Done.  ($LogFile is empty.)");
 		return TRUE;
 	}
-	/*
-	 * Read the first restart page.  It will be possibly incomplete and
-	 * will not be multi sector transfer deprotected but we only need the
-	 * first NTFS_BLOCK_SIZE bytes so it does not matter.
-	 */
-	page = ntfs_map_page(log_vi->i_mapping, 0);
-	if (IS_ERR(page)) {
-		ntfs_error(vol->sb, "Error mapping $LogFile page (index 0).");
-		return FALSE;
-	}
-	rp = (RESTART_PAGE_HEADER*)page_address(page);
-	if (!ntfs_is_rstr_record(rp->magic)) {
-		ntfs_error(vol->sb, "No restart page found at offset zero in "
-				"$LogFile.  This is probably a bug in that "
-				"the $LogFile should have been consistency "
-				"checked before calling this function.");
-		goto err_out;
+	BUG_ON(!rp);
+	if (!ntfs_is_rstr_record(rp->magic) &&
+			!ntfs_is_chkd_record(rp->magic)) {
+		ntfs_error(vol->sb, "Restart page buffer is invalid.  This is "
+				"probably a bug in that the $LogFile should "
+				"have been consistency checked before calling "
+				"this function.");
+		return FALSE;
 	}
 	ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
 	/*
@@ -659,15 +684,11 @@ BOOL ntfs_is_logfile_clean(struct inode 
 	if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
 			!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
 		ntfs_debug("Done.  $LogFile indicates a dirty shutdown.");
-		goto err_out;
+		return FALSE;
 	}
-	ntfs_unmap_page(page);
 	/* $LogFile indicates a clean shutdown. */
 	ntfs_debug("Done.  $LogFile indicates a clean shutdown.");
 	return TRUE;
-err_out:
-	ntfs_unmap_page(page);
-	return FALSE;
 }
 
 /**
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -2,7 +2,7 @@
  * logfile.h - Defines for NTFS kernel journal ($LogFile) handling.  Part of
  *	       the Linux-NTFS project.
  *
- * Copyright (c) 2000-2004 Anton Altaparmakov
+ * Copyright (c) 2000-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -296,9 +296,11 @@ typedef struct {
 /* sizeof() = 160 (0xa0) bytes */
 } __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
 
-extern BOOL ntfs_check_logfile(struct inode *log_vi);
+extern BOOL ntfs_check_logfile(struct inode *log_vi,
+		RESTART_PAGE_HEADER **rp);
 
-extern BOOL ntfs_is_logfile_clean(struct inode *log_vi);
+extern BOOL ntfs_is_logfile_clean(struct inode *log_vi,
+		const RESTART_PAGE_HEADER *rp);
 
 extern BOOL ntfs_empty_logfile(struct inode *log_vi);
 
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1133,7 +1133,8 @@ mft_unmap_out:
  *
  * Return TRUE on success or FALSE on error.
  */
-static BOOL load_and_check_logfile(ntfs_volume *vol)
+static BOOL load_and_check_logfile(ntfs_volume *vol,
+		RESTART_PAGE_HEADER **rp)
 {
 	struct inode *tmp_ino;
 
@@ -1145,7 +1146,7 @@ static BOOL load_and_check_logfile(ntfs_
 		/* Caller will display error message. */
 		return FALSE;
 	}
-	if (!ntfs_check_logfile(tmp_ino)) {
+	if (!ntfs_check_logfile(tmp_ino, rp)) {
 		iput(tmp_ino);
 		/* ntfs_check_logfile() will have displayed error output. */
 		return FALSE;
@@ -1687,6 +1688,7 @@ static BOOL load_system_files(ntfs_volum
 	struct super_block *sb = vol->sb;
 	MFT_RECORD *m;
 	VOLUME_INFORMATION *vi;
+	RESTART_PAGE_HEADER *rp;
 	ntfs_attr_search_ctx *ctx;
 #ifdef NTFS_RW
 	int err;
@@ -1841,8 +1843,9 @@ get_ctx_vol_failed:
 	 * Get the inode for the logfile, check it and determine if the volume
 	 * was shutdown cleanly.
 	 */
-	if (!load_and_check_logfile(vol) ||
-			!ntfs_is_logfile_clean(vol->logfile_ino)) {
+	rp = NULL;
+	if (!load_and_check_logfile(vol, &rp) ||
+			!ntfs_is_logfile_clean(vol->logfile_ino, rp)) {
 		static const char *es1a = "Failed to load $LogFile";
 		static const char *es1b = "$LogFile is not clean";
 		static const char *es2 = ".  Mount in Windows.";
@@ -1857,6 +1860,10 @@ get_ctx_vol_failed:
 						"continue nor on_errors="
 						"remount-ro was specified%s",
 						es1, es2);
+				if (vol->logfile_ino) {
+					BUG_ON(!rp);
+					ntfs_free(rp);
+				}
 				goto iput_logfile_err_out;
 			}
 			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
@@ -1867,6 +1874,7 @@ get_ctx_vol_failed:
 		/* This will prevent a read-write remount. */
 		NVolSetErrors(vol);
 	}
+	ntfs_free(rp);
 #endif /* NTFS_RW */
 	/* Get the root directory inode so we can do path lookups. */
 	vol->root_ino = ntfs_iget(sb, FILE_root);



^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
  2005-09-09  9:19 ` [PATCH 1/25] NTFS: Support more clean journal ($LogFile) states Anton Altaparmakov
@ 2005-09-09  9:19 ` Anton Altaparmakov
  2005-09-09 10:36   ` Pekka Enberg
  2005-09-09 14:51   ` Roland Dreier
  2005-09-09  9:21 ` [PATCH 3/25] NTFS: Use ntfs_malloc_nofs_nofail() in ntfs_runlists_merge() Anton Altaparmakov
                   ` (24 subsequent siblings)
  26 siblings, 2 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:19 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.

- Modify fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc() based
  allocations with __GFP_HIGHMEM, analogous to how the vmalloc() based
  allocations are done.
- Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
  ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
  hence cannot fail.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    6 ++++++
 fs/ntfs/malloc.h  |   48 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 48 insertions(+), 6 deletions(-)

06d0e3cf3d527f927681773c6ffbe697ccc5db7f
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -34,6 +34,12 @@ ToDo/Notes:
 	  journals with two different restart pages.  We sanity check both and
 	  either use the only sane one or the more recent one of the two in the
 	  case that both are valid.
+	- Modify fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc() based
+	  allocations with __GFP_HIGHMEM, analogous to how the vmalloc() based
+	  allocations are done.
+	- Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
+	  ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
+	  hence cannot fail.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -27,27 +27,63 @@
 #include <linux/highmem.h>
 
 /**
- * ntfs_malloc_nofs - allocate memory in multiples of pages
- * @size	number of bytes to allocate
+ * __ntfs_malloc - allocate memory in multiples of pages
+ * @size:	number of bytes to allocate
+ * @gfp_mask:	extra flags for the allocator
+ *
+ * Internal function.  You probably want ntfs_malloc_nofs()...
  *
  * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
  * returns a pointer to the allocated memory.
  *
  * If there was insufficient memory to complete the request, return NULL.
+ * Depending on @gfp_mask the allocation may be guaranteed to succeed.
  */
-static inline void *ntfs_malloc_nofs(unsigned long size)
+static inline void *__ntfs_malloc(unsigned long size,
+		unsigned int __nocast gfp_mask)
 {
 	if (likely(size <= PAGE_SIZE)) {
 		BUG_ON(!size);
 		/* kmalloc() has per-CPU caches so is faster for now. */
-		return kmalloc(PAGE_SIZE, GFP_NOFS);
-		/* return (void *)__get_free_page(GFP_NOFS | __GFP_HIGHMEM); */
+		return kmalloc(PAGE_SIZE, gfp_mask);
+		/* return (void *)__get_free_page(gfp_mask); */
 	}
 	if (likely(size >> PAGE_SHIFT < num_physpages))
-		return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL);
+		return __vmalloc(size, gfp_mask, PAGE_KERNEL);
 	return NULL;
 }
 
+/**
+ * ntfs_malloc_nofs - allocate memory in multiples of pages
+ * @size:	number of bytes to allocate
+ *
+ * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
+ * returns a pointer to the allocated memory.
+ *
+ * If there was insufficient memory to complete the request, return NULL.
+ */
+static inline void *ntfs_malloc_nofs(unsigned long size)
+{
+	return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM);
+}
+
+/**
+ * ntfs_malloc_nofs_nofail - allocate memory in multiples of pages
+ * @size:	number of bytes to allocate
+ *
+ * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
+ * returns a pointer to the allocated memory.
+ *
+ * This function guarantees that the allocation will succeed.  It will sleep
+ * for as long as it takes to complete the allocation.
+ *
+ * If there was insufficient memory to complete the request, return NULL.
+ */
+static inline void *ntfs_malloc_nofs_nofail(unsigned long size)
+{
+	return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM | __GFP_NOFAIL);
+}
+
 static inline void ntfs_free(void *addr)
 {
 	if (likely(((unsigned long)addr < VMALLOC_START) ||

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 3/25] NTFS: Use ntfs_malloc_nofs_nofail() in ntfs_runlists_merge().
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
  2005-09-09  9:19 ` [PATCH 1/25] NTFS: Support more clean journal ($LogFile) states Anton Altaparmakov
  2005-09-09  9:19 ` [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version Anton Altaparmakov
@ 2005-09-09  9:21 ` Anton Altaparmakov
  2005-09-09  9:22 ` [PATCH 4/25] NTFS: Fix two nasty runlist merging bugs that had gone unnoticed so far Anton Altaparmakov
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 3/25] NTFS: Use ntfs_malloc_nofs_nofail() in ntfs_runlists_merge()
      in the two critical regions.  This means we no longer need to
      panic() when the allocation fails as it now cannot fail.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    3 ++
 fs/ntfs/runlist.c |   68 +++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 53 insertions(+), 18 deletions(-)

9529d461d0992959026264b8fc002ac01d226708
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -40,6 +40,9 @@ ToDo/Notes:
 	- Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
 	  ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
 	  hence cannot fail.
+	- Use ntfs_malloc_nofs_nofail() in the two critical regions in
+	  fs/ntfs/runlist.c::ntfs_runlists_merge().  This means we no longer
+	  need to panic() if the allocation fails as it now cannot fail.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -35,7 +35,7 @@ static inline void ntfs_rl_mm(runlist_el
 		int size)
 {
 	if (likely((dst != src) && (size > 0)))
-		memmove(base + dst, base + src, size * sizeof (*base));
+		memmove(base + dst, base + src, size * sizeof(*base));
 }
 
 /**
@@ -95,6 +95,51 @@ static inline runlist_element *ntfs_rl_r
 }
 
 /**
+ * ntfs_rl_realloc_nofail - Reallocate memory for runlists
+ * @rl:		original runlist
+ * @old_size:	number of runlist elements in the original runlist @rl
+ * @new_size:	number of runlist elements we need space for
+ *
+ * As the runlists grow, more memory will be required.  To prevent the
+ * kernel having to allocate and reallocate large numbers of small bits of
+ * memory, this function returns an entire page of memory.
+ *
+ * This function guarantees that the allocation will succeed.  It will sleep
+ * for as long as it takes to complete the allocation.
+ *
+ * It is up to the caller to serialize access to the runlist @rl.
+ *
+ * N.B.  If the new allocation doesn't require a different number of pages in
+ *       memory, the function will return the original pointer.
+ *
+ * On success, return a pointer to the newly allocated, or recycled, memory.
+ * On error, return -errno. The following error codes are defined:
+ *	-ENOMEM	- Not enough memory to allocate runlist array.
+ *	-EINVAL	- Invalid parameters were passed in.
+ */
+static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl,
+		int old_size, int new_size)
+{
+	runlist_element *new_rl;
+
+	old_size = PAGE_ALIGN(old_size * sizeof(*rl));
+	new_size = PAGE_ALIGN(new_size * sizeof(*rl));
+	if (old_size == new_size)
+		return rl;
+
+	new_rl = ntfs_malloc_nofs_nofail(new_size);
+	BUG_ON(!new_rl);
+
+	if (likely(rl != NULL)) {
+		if (unlikely(old_size > new_size))
+			old_size = new_size;
+		memcpy(new_rl, rl, old_size);
+		ntfs_free(rl);
+	}
+	return new_rl;
+}
+
+/**
  * ntfs_are_rl_mergeable - test if two runlists can be joined together
  * @dst:	original runlist
  * @src:	new runlist to test for mergeability with @dst
@@ -621,11 +666,8 @@ runlist_element *ntfs_runlists_merge(run
 			if (drl[ds].lcn != LCN_RL_NOT_MAPPED) {
 				/* Add an unmapped runlist element. */
 				if (!slots) {
-					/* FIXME/TODO: We need to have the
-					 * extra memory already! (AIA) */
-					drl = ntfs_rl_realloc(drl, ds, ds + 2);
-					if (!drl)
-						goto critical_error;
+					drl = ntfs_rl_realloc_nofail(drl, ds,
+							ds + 2);
 					slots = 2;
 				}
 				ds++;
@@ -640,13 +682,8 @@ runlist_element *ntfs_runlists_merge(run
 			drl[ds].length = marker_vcn - drl[ds].vcn;
 			/* Finally add the ENOENT terminator. */
 			ds++;
-			if (!slots) {
-				/* FIXME/TODO: We need to have the extra
-				 * memory already! (AIA) */
-				drl = ntfs_rl_realloc(drl, ds, ds + 1);
-				if (!drl)
-					goto critical_error;
-			}
+			if (!slots)
+				drl = ntfs_rl_realloc_nofail(drl, ds, ds + 1);
 			drl[ds].vcn = marker_vcn;
 			drl[ds].lcn = LCN_ENOENT;
 			drl[ds].length = (s64)0;
@@ -659,11 +696,6 @@ finished:
 	ntfs_debug("Merged runlist:");
 	ntfs_debug_dump_runlist(drl);
 	return drl;
-
-critical_error:
-	/* Critical error! We cannot afford to fail here. */
-	ntfs_error(NULL, "Critical error! Not enough memory.");
-	panic("NTFS: Cannot continue.");
 }
 
 /**

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 4/25] NTFS: Fix two nasty runlist merging bugs that had gone unnoticed so far.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (2 preceding siblings ...)
  2005-09-09  9:21 ` [PATCH 3/25] NTFS: Use ntfs_malloc_nofs_nofail() in ntfs_runlists_merge() Anton Altaparmakov
@ 2005-09-09  9:22 ` Anton Altaparmakov
  2005-09-09  9:22 ` [PATCH 5/25] NTFS: Remove two bogus BUG_ON()s from fs/ntfs/mft.c Anton Altaparmakov
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 4/25] NTFS: Fix two nasty runlist merging bugs that had gone unnoticed
so far.  Thanks to Stefano Picerno for the bug report.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/runlist.c |    5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)

84d6ebe63f50b6efd8be252b58a207132157c60f
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -43,6 +43,8 @@ ToDo/Notes:
 	- Use ntfs_malloc_nofs_nofail() in the two critical regions in
 	  fs/ntfs/runlist.c::ntfs_runlists_merge().  This means we no longer
 	  need to panic() if the allocation fails as it now cannot fail.
+	- Fix two nasty runlist merging bugs that had gone unnoticed so far.
+	  Thanks to Stefano Picerno for the bug report.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -542,6 +542,7 @@ runlist_element *ntfs_runlists_merge(run
 			/* Scan to the end of the source runlist. */
 			for (dend = 0; likely(drl[dend].length); dend++)
 				;
+			dend++;
 			drl = ntfs_rl_realloc(drl, dend, dend + 1);
 			if (IS_ERR(drl))
 				return drl;
@@ -611,8 +612,8 @@ runlist_element *ntfs_runlists_merge(run
 		 ((drl[dins].vcn + drl[dins].length) <=      /* End of hole   */
 		  (srl[send - 1].vcn + srl[send - 1].length)));
 
-	/* Or we'll lose an end marker */
-	if (start && finish && (drl[dins].length == 0))
+	/* Or we will lose an end marker. */
+	if (finish && !drl[dins].length)
 		ss++;
 	if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
 		finish = FALSE;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 5/25] NTFS: Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (3 preceding siblings ...)
  2005-09-09  9:22 ` [PATCH 4/25] NTFS: Fix two nasty runlist merging bugs that had gone unnoticed so far Anton Altaparmakov
@ 2005-09-09  9:22 ` Anton Altaparmakov
  2005-09-09  9:22 ` [PATCH 6/25] NTFS: Fix handling of valid but empty mapping pairs array Anton Altaparmakov
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 5/25] NTFS: Remove two bogus BUG_ON()s from fs/ntfs/mft.c.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    1 +
 fs/ntfs/mft.c     |    2 --
 2 files changed, 1 insertions(+), 2 deletions(-)

8bb735216a0675e247bbe8b8b92c09d6884d1a17
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -45,6 +45,7 @@ ToDo/Notes:
 	  need to panic() if the allocation fails as it now cannot fail.
 	- Fix two nasty runlist merging bugs that had gone unnoticed so far.
 	  Thanks to Stefano Picerno for the bug report.
+	- Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -511,7 +511,6 @@ int ntfs_sync_mft_mirror(ntfs_volume *vo
 		} while (bh);
 		tail->b_this_page = head;
 		attach_page_buffers(page, head);
-		BUG_ON(!page_has_buffers(page));
 	}
 	bh = head = page_buffers(page);
 	BUG_ON(!bh);
@@ -692,7 +691,6 @@ int write_mft_record_nolock(ntfs_inode *
 	 */
 	if (!NInoTestClearDirty(ni))
 		goto done;
-	BUG_ON(!page_has_buffers(page));
 	bh = head = page_buffers(page);
 	BUG_ON(!bh);
 	rl = NULL;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 6/25] NTFS: Fix handling of valid but empty mapping pairs array
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (4 preceding siblings ...)
  2005-09-09  9:22 ` [PATCH 5/25] NTFS: Remove two bogus BUG_ON()s from fs/ntfs/mft.c Anton Altaparmakov
@ 2005-09-09  9:22 ` Anton Altaparmakov
  2005-09-09  9:23 ` [PATCH 7/25] NTFS: Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING Anton Altaparmakov
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 6/25] NTFS: Fix handling of valid but empty mapping pairs array in
      fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/runlist.c |    3 +++
 2 files changed, 5 insertions(+), 0 deletions(-)

2b0ada2b8e086c267dd116a39ad41ff0a717b665
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -46,6 +46,8 @@ ToDo/Notes:
 	- Fix two nasty runlist merging bugs that had gone unnoticed so far.
 	  Thanks to Stefano Picerno for the bug report.
 	- Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
+	- Fix handling of valid but empty mapping pairs array in
+	  fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -760,6 +760,9 @@ runlist_element *ntfs_mapping_pairs_deco
 		ntfs_error(vol->sb, "Corrupt attribute.");
 		return ERR_PTR(-EIO);
 	}
+	/* If the mapping pairs array is valid but empty, nothing to do. */
+	if (!vcn && !*buf)
+		return old_rl;
 	/* Current position in runlist array. */
 	rlpos = 0;
 	/* Allocate first page and set current runlist size to one page. */

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 7/25] NTFS: Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (5 preceding siblings ...)
  2005-09-09  9:22 ` [PATCH 6/25] NTFS: Fix handling of valid but empty mapping pairs array Anton Altaparmakov
@ 2005-09-09  9:23 ` Anton Altaparmakov
  2005-09-09  9:23 ` [PATCH 8/25] NTFS: Change ntfs_rl_truncate_nolock() to throw away the runlist if the new Anton Altaparmakov
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 7/25] NTFS: Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
      messages and include the inode number.  Thanks to Yura Pakhuchiy for
      pointing this out.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    3 +++
 fs/ntfs/dir.c     |    3 ++-
 fs/ntfs/unistr.c  |    3 ++-
 3 files changed, 7 insertions(+), 2 deletions(-)

f94ad38e68e1623660fdbb063d0c580ba6661c29
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -48,6 +48,9 @@ ToDo/Notes:
 	- Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
 	- Fix handling of valid but empty mapping pairs array in
 	  fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
+	- Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
+	  messages and include the inode number.  Thanks to Yura Pakhuchiy for
+	  pointing this out.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1051,7 +1051,8 @@ static inline int ntfs_filldir(ntfs_volu
 			ie->key.file_name.file_name_length, &name,
 			NTFS_MAX_NAME_LEN * NLS_MAX_CHARSET_SIZE + 1);
 	if (name_len <= 0) {
-		ntfs_debug("Skipping unrepresentable file.");
+		ntfs_warning(vol->sb, "Skipping unrepresentable inode 0x%llx.",
+				(long long)MREF_LE(ie->data.dir.indexed_file));
 		return 0;
 	}
 	if (ie->key.file_name.file_attributes &
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -372,7 +372,8 @@ retry:			wc = nls->uni2char(le16_to_cpu(
 	return -EINVAL;
 conversion_err:
 	ntfs_error(vol->sb, "Unicode name contains characters that cannot be "
-			"converted to character set %s.", nls->charset);
+			"converted to character set %s.  You might want to "
+			"try to use the mount option nls=utf8.", nls->charset);
 	if (ns != *outs)
 		kfree(ns);
 	if (wc != -ENAMETOOLONG)

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 8/25] NTFS: Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (6 preceding siblings ...)
  2005-09-09  9:23 ` [PATCH 7/25] NTFS: Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING Anton Altaparmakov
@ 2005-09-09  9:23 ` Anton Altaparmakov
  2005-09-09  9:24 ` [PATCH 9/25] NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist Anton Altaparmakov
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 8/25] NTFS: Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
      length is zero.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/runlist.c |   14 +++++++++++++-
 2 files changed, 15 insertions(+), 1 deletions(-)

3ffc5a443824fcf426d8d35dc632acc4dd9fb6d1
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -51,6 +51,8 @@ ToDo/Notes:
 	- Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
 	  messages and include the inode number.  Thanks to Yura Pakhuchiy for
 	  pointing this out.
+	- Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
+	  length is zero.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -1455,6 +1455,7 @@ err_out:
 
 /**
  * ntfs_rl_truncate_nolock - truncate a runlist starting at a specified vcn
+ * @vol:	ntfs volume (needed for error output)
  * @runlist:	runlist to truncate
  * @new_length:	the new length of the runlist in VCNs
  *
@@ -1462,12 +1463,16 @@ err_out:
  * holding the runlist elements to a length of @new_length VCNs.
  *
  * If @new_length lies within the runlist, the runlist elements with VCNs of
- * @new_length and above are discarded.
+ * @new_length and above are discarded.  As a special case if @new_length is
+ * zero, the runlist is discarded and set to NULL.
  *
  * If @new_length lies beyond the runlist, a sparse runlist element is added to
  * the end of the runlist @runlist or if the last runlist element is a sparse
  * one already, this is extended.
  *
+ * Note, no checking is done for unmapped runlist elements.  It is assumed that
+ * the caller has mapped any elements that need to be mapped already.
+ *
  * Return 0 on success and -errno on error.
  *
  * Locking: The caller must hold @runlist->lock for writing.
@@ -1482,6 +1487,13 @@ int ntfs_rl_truncate_nolock(const ntfs_v
 	BUG_ON(!runlist);
 	BUG_ON(new_length < 0);
 	rl = runlist->rl;
+	if (!new_length) {
+		ntfs_debug("Freeing runlist.");
+		runlist->rl = NULL;
+		if (rl)
+			ntfs_free(rl);
+		return 0;
+	}
 	if (unlikely(!rl)) {
 		/*
 		 * Create a runlist consisting of a sparse runlist element of

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 9/25] NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (7 preceding siblings ...)
  2005-09-09  9:23 ` [PATCH 8/25] NTFS: Change ntfs_rl_truncate_nolock() to throw away the runlist if the new Anton Altaparmakov
@ 2005-09-09  9:24 ` Anton Altaparmakov
  2005-09-09  9:24 ` [PATCH 10/25] NTFS: Fix a bug in fs/ntfs/index.c::ntfs_index_lookup() Anton Altaparmakov
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 9/25] NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 
 fs/ntfs/runlist.c |  284 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ntfs/runlist.h |    3 +
 3 files changed, 289 insertions(+), 0 deletions(-)

6e48321a40610f7213e3ac75ba234f6f8b3ed5f5
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -53,6 +53,8 @@ ToDo/Notes:
 	  pointing this out.
 	- Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
 	  length is zero.
+	- Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
+	  specified hole into a runlist.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -1601,4 +1601,288 @@ int ntfs_rl_truncate_nolock(const ntfs_v
 	return 0;
 }
 
+/**
+ * ntfs_rl_punch_nolock - punch a hole into a runlist
+ * @vol:	ntfs volume (needed for error output)
+ * @runlist:	runlist to punch a hole into
+ * @start:	starting VCN of the hole to be created
+ * @length:	size of the hole to be created in units of clusters
+ *
+ * Punch a hole into the runlist @runlist starting at VCN @start and of size
+ * @length clusters.
+ *
+ * Return 0 on success and -errno on error, in which case @runlist has not been
+ * modified.
+ *
+ * If @start and/or @start + @length are outside the runlist return error code
+ * -ENOENT.
+ *
+ * If the runlist contains unmapped or error elements between @start and @start
+ * + @length return error code -EINVAL.
+ *
+ * Locking: The caller must hold @runlist->lock for writing.
+ */
+int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
+		const VCN start, const s64 length)
+{
+	const VCN end = start + length;
+	s64 delta;
+	runlist_element *rl, *rl_end, *rl_real_end, *trl;
+	int old_size;
+	BOOL lcn_fixup = FALSE;
+
+	ntfs_debug("Entering for start 0x%llx, length 0x%llx.",
+			(long long)start, (long long)length);
+	BUG_ON(!runlist);
+	BUG_ON(start < 0);
+	BUG_ON(length < 0);
+	BUG_ON(end < 0);
+	rl = runlist->rl;
+	if (unlikely(!rl)) {
+		if (likely(!start && !length))
+			return 0;
+		return -ENOENT;
+	}
+	/* Find @start in the runlist. */
+	while (likely(rl->length && start >= rl[1].vcn))
+		rl++;
+	rl_end = rl;
+	/* Find @end in the runlist. */
+	while (likely(rl_end->length && end >= rl_end[1].vcn)) {
+		/* Verify there are no unmapped or error elements. */
+		if (unlikely(rl_end->lcn < LCN_HOLE))
+			return -EINVAL;
+		rl_end++;
+	}
+	/* Check the last element. */
+	if (unlikely(rl_end->length && rl_end->lcn < LCN_HOLE))
+		return -EINVAL;
+	/* This covers @start being out of bounds, too. */
+	if (!rl_end->length && end > rl_end->vcn)
+		return -ENOENT;
+	if (!length)
+		return 0;
+	if (!rl->length)
+		return -ENOENT;
+	rl_real_end = rl_end;
+	/* Determine the runlist size. */
+	while (likely(rl_real_end->length))
+		rl_real_end++;
+	old_size = rl_real_end - runlist->rl + 1;
+	/* If @start is in a hole simply extend the hole. */
+	if (rl->lcn == LCN_HOLE) {
+		/*
+		 * If both @start and @end are in the same sparse run, we are
+		 * done.
+		 */
+		if (end <= rl[1].vcn) {
+			ntfs_debug("Done (requested hole is already sparse).");
+			return 0;
+		}
+extend_hole:
+		/* Extend the hole. */
+		rl->length = end - rl->vcn;
+		/* If @end is in a hole, merge it with the current one. */
+		if (rl_end->lcn == LCN_HOLE) {
+			rl_end++;
+			rl->length = rl_end->vcn - rl->vcn;
+		}
+		/* We have done the hole.  Now deal with the remaining tail. */
+		rl++;
+		/* Cut out all runlist elements up to @end. */
+		if (rl < rl_end)
+			memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
+					sizeof(*rl));
+		/* Adjust the beginning of the tail if necessary. */
+		if (end > rl->vcn) {
+			s64 delta = end - rl->vcn;
+			rl->vcn = end;
+			rl->length -= delta;
+			/* Only adjust the lcn if it is real. */
+			if (rl->lcn >= 0)
+				rl->lcn += delta;
+		}
+shrink_allocation:
+		/* Reallocate memory if the allocation changed. */
+		if (rl < rl_end) {
+			rl = ntfs_rl_realloc(runlist->rl, old_size,
+					old_size - (rl_end - rl));
+			if (IS_ERR(rl))
+				ntfs_warning(vol->sb, "Failed to shrink "
+						"runlist buffer.  This just "
+						"wastes a bit of memory "
+						"temporarily so we ignore it "
+						"and return success.");
+			else
+				runlist->rl = rl;
+		}
+		ntfs_debug("Done (extend hole).");
+		return 0;
+	}
+	/*
+	 * If @start is at the beginning of a run things are easier as there is
+	 * no need to split the first run.
+	 */
+	if (start == rl->vcn) {
+		/*
+		 * @start is at the beginning of a run.
+		 *
+		 * If the previous run is sparse, extend its hole.
+		 *
+		 * If @end is not in the same run, switch the run to be sparse
+		 * and extend the newly created hole.
+		 *
+		 * Thus both of these cases reduce the problem to the above
+		 * case of "@start is in a hole".
+		 */
+		if (rl > runlist->rl && (rl - 1)->lcn == LCN_HOLE) {
+			rl--;
+			goto extend_hole;
+		}
+		if (end >= rl[1].vcn) {
+			rl->lcn = LCN_HOLE;
+			goto extend_hole;
+		}
+		/*
+		 * The final case is when @end is in the same run as @start.
+		 * For this need to split the run into two.  One run for the
+		 * sparse region between the beginning of the old run, i.e.
+		 * @start, and @end and one for the remaining non-sparse
+		 * region, i.e. between @end and the end of the old run.
+		 */
+		trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
+		if (IS_ERR(trl))
+			goto enomem_out;
+		old_size++;
+		if (runlist->rl != trl) {
+			rl = trl + (rl - runlist->rl);
+			rl_end = trl + (rl_end - runlist->rl);
+			rl_real_end = trl + (rl_real_end - runlist->rl);
+			runlist->rl = trl;
+		}
+split_end:
+		/* Shift all the runs up by one. */
+		memmove(rl + 1, rl, (rl_real_end - rl + 1) * sizeof(*rl));
+		/* Finally, setup the two split runs. */
+		rl->lcn = LCN_HOLE;
+		rl->length = length;
+		rl++;
+		rl->vcn += length;
+		/* Only adjust the lcn if it is real. */
+		if (rl->lcn >= 0 || lcn_fixup)
+			rl->lcn += length;
+		rl->length -= length;
+		ntfs_debug("Done (split one).");
+		return 0;
+	}
+	/*
+	 * @start is neither in a hole nor at the beginning of a run.
+	 *
+	 * If @end is in a hole, things are easier as simply truncating the run
+	 * @start is in to end at @start - 1, deleting all runs after that up
+	 * to @end, and finally extending the beginning of the run @end is in
+	 * to be @start is all that is needed.
+	 */
+	if (rl_end->lcn == LCN_HOLE) {
+		/* Truncate the run containing @start. */
+		rl->length = start - rl->vcn;
+		rl++;
+		/* Cut out all runlist elements up to @end. */
+		if (rl < rl_end)
+			memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
+					sizeof(*rl));
+		/* Extend the beginning of the run @end is in to be @start. */
+		rl->vcn = start;
+		rl->length = rl[1].vcn - start;
+		goto shrink_allocation;
+	}
+	/* 
+	 * If @end is not in a hole there are still two cases to distinguish.
+	 * Either @end is or is not in the same run as @start.
+	 *
+	 * The second case is easier as it can be reduced to an already solved
+	 * problem by truncating the run @start is in to end at @start - 1.
+	 * Then, if @end is in the next run need to split the run into a sparse
+	 * run followed by a non-sparse run (already covered above) and if @end
+	 * is not in the next run switching it to be sparse, again reduces the
+	 * problem to the already covered case of "@start is in a hole".
+	 */
+	if (end >= rl[1].vcn) {
+		/*
+		 * If @end is not in the next run, reduce the problem to the
+		 * case of "@start is in a hole".
+		 */
+		if (rl[1].length && end >= rl[2].vcn) {
+			/* Truncate the run containing @start. */
+			rl->length = start - rl->vcn;
+			rl++;
+			rl->vcn = start;
+			rl->lcn = LCN_HOLE;
+			goto extend_hole;
+		}
+		trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
+		if (IS_ERR(trl))
+			goto enomem_out;
+		old_size++;
+		if (runlist->rl != trl) {
+			rl = trl + (rl - runlist->rl);
+			rl_end = trl + (rl_end - runlist->rl);
+			rl_real_end = trl + (rl_real_end - runlist->rl);
+			runlist->rl = trl;
+		}
+		/* Truncate the run containing @start. */
+		rl->length = start - rl->vcn;
+		rl++;
+		/*
+		 * @end is in the next run, reduce the problem to the case
+		 * where "@start is at the beginning of a run and @end is in
+		 * the same run as @start".
+		 */
+		delta = rl->vcn - start;
+		rl->vcn = start;
+		if (rl->lcn >= 0) {
+			rl->lcn -= delta;
+			/* Need this in case the lcn just became negative. */
+			lcn_fixup = TRUE;
+		}
+		rl->length += delta;
+		goto split_end;
+	}
+	/*
+	 * The first case from above, i.e. @end is in the same run as @start.
+	 * We need to split the run into three.  One run for the non-sparse
+	 * region between the beginning of the old run and @start, one for the
+	 * sparse region between @start and @end, and one for the remaining
+	 * non-sparse region, i.e. between @end and the end of the old run.
+	 */
+	trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 2);
+	if (IS_ERR(trl))
+		goto enomem_out;
+	old_size += 2;
+	if (runlist->rl != trl) {
+		rl = trl + (rl - runlist->rl);
+		rl_end = trl + (rl_end - runlist->rl);
+		rl_real_end = trl + (rl_real_end - runlist->rl);
+		runlist->rl = trl;
+	}
+	/* Shift all the runs up by two. */
+	memmove(rl + 2, rl, (rl_real_end - rl + 1) * sizeof(*rl));
+	/* Finally, setup the three split runs. */
+	rl->length = start - rl->vcn;
+	rl++;
+	rl->vcn = start;
+	rl->lcn = LCN_HOLE;
+	rl->length = length;
+	rl++;
+	delta = end - rl->vcn;
+	rl->vcn = end;
+	rl->lcn += delta;
+	rl->length -= delta;
+	ntfs_debug("Done (split both).");
+	return 0;
+enomem_out:
+	ntfs_error(vol->sb, "Not enough memory to extend runlist buffer.");
+	return -ENOMEM;
+}
+
 #endif /* NTFS_RW */
diff --git a/fs/ntfs/runlist.h b/fs/ntfs/runlist.h
--- a/fs/ntfs/runlist.h
+++ b/fs/ntfs/runlist.h
@@ -94,6 +94,9 @@ extern int ntfs_mapping_pairs_build(cons
 extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,
 		runlist *const runlist, const s64 new_length);
 
+int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
+		const VCN start, const s64 length);
+
 #endif /* NTFS_RW */
 
 #endif /* _LINUX_NTFS_RUNLIST_H */

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 10/25] NTFS: Fix a bug in fs/ntfs/index.c::ntfs_index_lookup().
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (8 preceding siblings ...)
  2005-09-09  9:24 ` [PATCH 9/25] NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist Anton Altaparmakov
@ 2005-09-09  9:24 ` Anton Altaparmakov
  2005-09-09  9:25 ` [PATCH 11/25] NTFS: Remove bogus setting of PageError in ntfs_read_compressed_block() Anton Altaparmakov
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 10/25] NTFS: Fix a bug in fs/ntfs/index.c::ntfs_index_lookup().  When the returned
      index entry is in the index root, we forgot to set the @ir pointer in
      the index context.  Thanks for Yura Pakhuchiy for finding this bug.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    3 +++
 fs/ntfs/index.c   |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

8e08ceaeacd5d300aaad166f2eef8bfc37e09831
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -55,6 +55,9 @@ ToDo/Notes:
 	  length is zero.
 	- Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
 	  specified hole into a runlist.
+	- Fix a bug in fs/ntfs/index.c::ntfs_index_lookup().  When the returned
+	  index entry is in the index root, we forgot to set the @ir pointer in
+	  the index context.  Thanks to Yura Pakhuchiy for finding this bug.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -205,6 +205,7 @@ int ntfs_index_lookup(const void *key, c
 				&ie->key, key_len)) {
 ir_done:
 			ictx->is_in_root = TRUE;
+			ictx->ir = ir;
 			ictx->actx = actx;
 			ictx->base_ni = base_ni;
 			ictx->ia = NULL;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 11/25] NTFS: Remove bogus setting of PageError in ntfs_read_compressed_block().
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (9 preceding siblings ...)
  2005-09-09  9:24 ` [PATCH 10/25] NTFS: Fix a bug in fs/ntfs/index.c::ntfs_index_lookup() Anton Altaparmakov
@ 2005-09-09  9:25 ` Anton Altaparmakov
  2005-09-09  9:26 ` [PATCH 12/25] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize() Anton Altaparmakov
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 11/25] NTFS: Remove bogus setting of PageError in ntfs_read_compressed_block().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog  |    1 +
 fs/ntfs/compress.c |    8 --------
 fs/ntfs/file.c     |    9 +++++++--
 3 files changed, 8 insertions(+), 10 deletions(-)

f25dfb5e44fa8641961780d681bc1871abcfb861
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -58,6 +58,7 @@ ToDo/Notes:
 	- Fix a bug in fs/ntfs/index.c::ntfs_index_lookup().  When the returned
 	  index entry is in the index root, we forgot to set the @ir pointer in
 	  the index context.  Thanks to Yura Pakhuchiy for finding this bug.
+	- Remove bogus setting of PageError in ntfs_read_compressed_block().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -539,7 +539,6 @@ int ntfs_read_compressed_block(struct pa
 	if (unlikely(!pages || !bhs)) {
 		kfree(bhs);
 		kfree(pages);
-		SetPageError(page);
 		unlock_page(page);
 		ntfs_error(vol->sb, "Failed to allocate internal buffers.");
 		return -ENOMEM;
@@ -871,9 +870,6 @@ lock_retry_remap:
 			for (; prev_cur_page < cur_page; prev_cur_page++) {
 				page = pages[prev_cur_page];
 				if (page) {
-					if (prev_cur_page == xpage &&
-							!xpage_done)
-						SetPageError(page);
 					flush_dcache_page(page);
 					kunmap(page);
 					unlock_page(page);
@@ -904,8 +900,6 @@ lock_retry_remap:
 					"Terminating them with extreme "
 					"prejudice.  Inode 0x%lx, page index "
 					"0x%lx.", ni->mft_no, page->index);
-			if (cur_page == xpage && !xpage_done)
-				SetPageError(page);
 			flush_dcache_page(page);
 			kunmap(page);
 			unlock_page(page);
@@ -953,8 +947,6 @@ err_out:
 	for (i = cur_page; i < max_page; i++) {
 		page = pages[i];
 		if (page) {
-			if (i == xpage && !xpage_done)
-				SetPageError(page);
 			flush_dcache_page(page);
 			kunmap(page);
 			unlock_page(page);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1,7 +1,7 @@
 /*
- * file.c - NTFS kernel file operations. Part of the Linux-NTFS project.
+ * file.c - NTFS kernel file operations.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -94,6 +94,11 @@ static int ntfs_file_fsync(struct file *
 	if (!datasync || !NInoNonResident(NTFS_I(vi)))
 		ret = ntfs_write_inode(vi, 1);
 	write_inode_now(vi, !datasync);
+	/*
+	 * NOTE: If we were to use mapping->private_list (see ext2 and
+	 * fs/buffer.c) for dirty blocks then we could optimize the below to be
+	 * sync_mapping_buffers(vi->i_mapping).
+	 */
 	err = sync_blockdev(vi->i_sb->s_bdev);
 	if (unlikely(err && !ret))
 		ret = err;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 12/25] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (10 preceding siblings ...)
  2005-09-09  9:25 ` [PATCH 11/25] NTFS: Remove bogus setting of PageError in ntfs_read_compressed_block() Anton Altaparmakov
@ 2005-09-09  9:26 ` Anton Altaparmakov
  2005-09-09  9:26 ` [PATCH 13/25] NTFS: Fix several bugs in fs/ntfs/attrib.c Anton Altaparmakov
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 12/25] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    1 +
 fs/ntfs/attrib.c  |   40 ++++++++++++++++++++++++++++++++++++++++
 fs/ntfs/attrib.h  |    2 ++
 3 files changed, 43 insertions(+), 0 deletions(-)

0aacceacf35451ffb771ec825555e98c5dce8b01
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -59,6 +59,7 @@ ToDo/Notes:
 	  index entry is in the index root, we forgot to set the @ir pointer in
 	  the index context.  Thanks to Yura Pakhuchiy for finding this bug.
 	- Remove bogus setting of PageError in ntfs_read_compressed_block().
+	- Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1247,6 +1247,46 @@ int ntfs_attr_record_resize(MFT_RECORD *
 }
 
 /**
+ * ntfs_resident_attr_value_resize - resize the value of a resident attribute
+ * @m:		mft record containing attribute record
+ * @a:		attribute record whose value to resize
+ * @new_size:	new size in bytes to which to resize the attribute value of @a
+ *
+ * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
+ * If the value is made bigger, the newly allocated space is cleared.
+ *
+ * Return 0 on success and -errno on error.  The following error codes are
+ * defined:
+ *	-ENOSPC	- Not enough space in the mft record @m to perform the resize.
+ *
+ * Note: On error, no modifications have been performed whatsoever.
+ *
+ * Warning: If you make a record smaller without having copied all the data you
+ *	    are interested in the data may be overwritten.
+ */
+int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+		const u32 new_size)
+{
+	u32 old_size;
+
+	/* Resize the resident part of the attribute record. */
+	if (ntfs_attr_record_resize(m, a,
+			le16_to_cpu(a->data.resident.value_offset) + new_size))
+		return -ENOSPC;
+	/*
+	 * The resize succeeded!  If we made the attribute value bigger, clear
+	 * the area between the old size and @new_size.
+	 */
+	old_size = le32_to_cpu(a->data.resident.value_length);
+	if (new_size > old_size)
+		memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
+				old_size, 0, new_size - old_size);
+	/* Finally update the length of the attribute value. */
+	a->data.resident.value_length = cpu_to_le32(new_size);
+	return 0;
+}
+
+/**
  * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
  * @ni:		ntfs inode describing the attribute to convert
  *
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -99,6 +99,8 @@ extern int ntfs_attr_can_be_resident(con
 		const ATTR_TYPE type);
 
 extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
+extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+		const u32 new_size);
 
 extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 13/25] NTFS: Fix several bugs in fs/ntfs/attrib.c.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (11 preceding siblings ...)
  2005-09-09  9:26 ` [PATCH 12/25] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize() Anton Altaparmakov
@ 2005-09-09  9:26 ` Anton Altaparmakov
  2005-09-09  9:27 ` [PATCH 14/25] NTFS: Fix handling of sparse attributes in ntfs_attr_make_non_resident() Anton Altaparmakov
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 13/25] NTFS: Fix several bugs in fs/ntfs/attrib.c.

- Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
  access to the allocated size in the ntfs inode with the size lock.
- Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
  return LCN_ENOENT when there is no runlist and the allocated size is
  zero.
- Fix load_attribute_list() to handle the case of a NULL runlist.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    6 ++++++
 fs/ntfs/attrib.c  |   32 +++++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletions(-)

2983d1bd1a596e88cdddc0c2d45b9e97728f3f41
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -60,6 +60,12 @@ ToDo/Notes:
 	  the index context.  Thanks to Yura Pakhuchiy for finding this bug.
 	- Remove bogus setting of PageError in ntfs_read_compressed_block().
 	- Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
+	- Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
+	  access to the allocated size in the ntfs inode with the size lock.
+	- Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
+	  return LCN_ENOENT when there is no runlist and the allocated size is
+	  zero.
+	- Fix load_attribute_list() to handle the case of a NULL runlist.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -43,6 +43,9 @@
  * which is not an error as such.  This is -ENOENT.  It means that @vcn is out
  * of bounds of the runlist.
  *
+ * Note the runlist can be NULL after this function returns if @vcn is zero and
+ * the attribute has zero allocated size, i.e. there simply is no runlist.
+ *
  * Locking: - The runlist must be locked for writing.
  *	    - This function modifies the runlist.
  */
@@ -54,6 +57,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *
 	ATTR_RECORD *a;
 	ntfs_attr_search_ctx *ctx;
 	runlist_element *rl;
+	unsigned long flags;
 	int err = 0;
 
 	ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
@@ -85,8 +89,11 @@ int ntfs_map_runlist_nolock(ntfs_inode *
 	 * ntfs_mapping_pairs_decompress() fails.
 	 */
 	end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
-	if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
+	if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
+		read_lock_irqsave(&ni->size_lock, flags);
 		end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
+		read_unlock_irqrestore(&ni->size_lock, flags);
+	}
 	if (unlikely(vcn >= end_vcn)) {
 		err = -ENOENT;
 		goto err_out;
@@ -165,6 +172,7 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_ino
 		const BOOL write_locked)
 {
 	LCN lcn;
+	unsigned long flags;
 	BOOL is_retry = FALSE;
 
 	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
@@ -173,6 +181,14 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_ino
 	BUG_ON(!ni);
 	BUG_ON(!NInoNonResident(ni));
 	BUG_ON(vcn < 0);
+	if (!ni->runlist.rl) {
+		read_lock_irqsave(&ni->size_lock, flags);
+		if (!ni->allocated_size) {
+			read_unlock_irqrestore(&ni->size_lock, flags);
+			return LCN_ENOENT;
+		}
+		read_unlock_irqrestore(&ni->size_lock, flags);
+	}
 retry_remap:
 	/* Convert vcn to lcn.  If that fails map the runlist and retry once. */
 	lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
@@ -255,6 +271,7 @@ retry_remap:
 runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
 		const BOOL write_locked)
 {
+	unsigned long flags;
 	runlist_element *rl;
 	int err = 0;
 	BOOL is_retry = FALSE;
@@ -265,6 +282,14 @@ runlist_element *ntfs_attr_find_vcn_nolo
 	BUG_ON(!ni);
 	BUG_ON(!NInoNonResident(ni));
 	BUG_ON(vcn < 0);
+	if (!ni->runlist.rl) {
+		read_lock_irqsave(&ni->size_lock, flags);
+		if (!ni->allocated_size) {
+			read_unlock_irqrestore(&ni->size_lock, flags);
+			return ERR_PTR(-ENOENT);
+		}
+		read_unlock_irqrestore(&ni->size_lock, flags);
+	}
 retry_remap:
 	rl = ni->runlist.rl;
 	if (likely(rl && vcn >= rl[0].vcn)) {
@@ -528,6 +553,11 @@ int load_attribute_list(ntfs_volume *vol
 	block_size_bits = sb->s_blocksize_bits;
 	down_read(&runlist->lock);
 	rl = runlist->rl;
+	if (!rl) {
+		ntfs_error(sb, "Cannot read attribute list since runlist is "
+				"missing.");
+		goto err_out;	
+	}
 	/* Read all clusters specified by the runlist one run at a time. */
 	while (rl->length) {
 		lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 14/25] NTFS: Fix handling of sparse attributes in ntfs_attr_make_non_resident().
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (12 preceding siblings ...)
  2005-09-09  9:26 ` [PATCH 13/25] NTFS: Fix several bugs in fs/ntfs/attrib.c Anton Altaparmakov
@ 2005-09-09  9:27 ` Anton Altaparmakov
  2005-09-09  9:27 ` [PATCH 15/25] NTFS: Fix cluster (de)allocators to work when the runlist is NULL and more Anton Altaparmakov
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:27 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 14/25] NTFS: Fix handling of sparse attributes in ntfs_attr_make_non_resident().
      Also, add BUG() checks to ntfs_attr_make_non_resident() and
      ntfs_attr_set() to ensure that these functions are never called
      for compressed or encrypted attributes.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    4 ++++
 fs/ntfs/attrib.c  |   53 ++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 40 insertions(+), 17 deletions(-)

807c453de7c5487d2e5eece76bafdea8f39d249e
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -66,6 +66,10 @@ ToDo/Notes:
 	  return LCN_ENOENT when there is no runlist and the allocated size is
 	  zero.
 	- Fix load_attribute_list() to handle the case of a NULL runlist.
+	- Fix handling of sparse attributes in ntfs_attr_make_non_resident().
+	- Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
+	  to ensure that these functions are never called for compressed or
+	  encrypted attributes.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1372,6 +1372,12 @@ int ntfs_attr_make_non_resident(ntfs_ino
 		return err;
 	}
 	/*
+	 * FIXME: Compressed and encrypted attributes are not supported when
+	 * writing and we should never have gotten here for them.
+	 */
+	BUG_ON(NInoCompressed(ni));
+	BUG_ON(NInoEncrypted(ni));
+	/*
 	 * The size needs to be aligned to a cluster boundary for allocation
 	 * purposes.
 	 */
@@ -1447,10 +1453,15 @@ int ntfs_attr_make_non_resident(ntfs_ino
 	BUG_ON(a->non_resident);
 	/*
 	 * Calculate new offsets for the name and the mapping pairs array.
-	 * We assume the attribute is not compressed or sparse.
 	 */
-	name_ofs = (offsetof(ATTR_REC,
-			data.non_resident.compressed_size) + 7) & ~7;
+	if (NInoSparse(ni) || NInoCompressed(ni))
+		name_ofs = (offsetof(ATTR_REC,
+				data.non_resident.compressed_size) +
+				sizeof(a->data.non_resident.compressed_size) +
+				7) & ~7;
+	else
+		name_ofs = (offsetof(ATTR_REC,
+				data.non_resident.compressed_size) + 7) & ~7;
 	mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
 	/*
 	 * Determine the size of the resident part of the now non-resident
@@ -1489,24 +1500,23 @@ int ntfs_attr_make_non_resident(ntfs_ino
 		memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
 				a->name_length * sizeof(ntfschar));
 	a->name_offset = cpu_to_le16(name_ofs);
-	/*
-	 * FIXME: For now just clear all of these as we do not support them
-	 * when writing.
-	 */
-	a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
-			ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
 	/* Setup the fields specific to non-resident attributes. */
 	a->data.non_resident.lowest_vcn = 0;
 	a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
 			vol->cluster_size_bits);
 	a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
-	a->data.non_resident.compression_unit = 0;
 	memset(&a->data.non_resident.reserved, 0,
 			sizeof(a->data.non_resident.reserved));
 	a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
 	a->data.non_resident.data_size =
 			a->data.non_resident.initialized_size =
 			cpu_to_sle64(attr_size);
+	if (NInoSparse(ni) || NInoCompressed(ni)) {
+		a->data.non_resident.compression_unit = 4;
+		a->data.non_resident.compressed_size =
+				a->data.non_resident.allocated_size;
+	} else
+		a->data.non_resident.compression_unit = 0;
 	/* Generate the mapping pairs array into the attribute record. */
 	err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
 			arec_size - mp_ofs, rl, 0, -1, NULL);
@@ -1516,16 +1526,19 @@ int ntfs_attr_make_non_resident(ntfs_ino
 		goto undo_err_out;
 	}
 	/* Setup the in-memory attribute structure to be non-resident. */
-	/*
-	 * FIXME: For now just clear all of these as we do not support them
-	 * when writing.
-	 */
-	NInoClearSparse(ni);
-	NInoClearEncrypted(ni);
-	NInoClearCompressed(ni);
 	ni->runlist.rl = rl;
 	write_lock_irqsave(&ni->size_lock, flags);
 	ni->allocated_size = new_size;
+	if (NInoSparse(ni) || NInoCompressed(ni)) {
+		ni->itype.compressed.size = ni->allocated_size;
+		ni->itype.compressed.block_size = 1U <<
+				(a->data.non_resident.compression_unit +
+				vol->cluster_size_bits);
+		ni->itype.compressed.block_size_bits =
+				ffs(ni->itype.compressed.block_size) - 1;
+		ni->itype.compressed.block_clusters = 1U <<
+				a->data.non_resident.compression_unit;
+	}
 	write_unlock_irqrestore(&ni->size_lock, flags);
 	/*
 	 * This needs to be last since the address space operations ->readpage
@@ -1673,6 +1686,12 @@ int ntfs_attr_set(ntfs_inode *ni, const 
 	BUG_ON(cnt < 0);
 	if (!cnt)
 		goto done;
+	/*
+	 * FIXME: Compressed and encrypted attributes are not supported when
+	 * writing and we should never have gotten here for them.
+	 */
+	BUG_ON(NInoCompressed(ni));
+	BUG_ON(NInoEncrypted(ni));
 	mapping = VFS_I(ni)->i_mapping;
 	/* Work out the starting index and page offset. */
 	idx = ofs >> PAGE_CACHE_SHIFT;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 15/25] NTFS: Fix cluster (de)allocators to work when the runlist is NULL and more
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (13 preceding siblings ...)
  2005-09-09  9:27 ` [PATCH 14/25] NTFS: Fix handling of sparse attributes in ntfs_attr_make_non_resident() Anton Altaparmakov
@ 2005-09-09  9:27 ` Anton Altaparmakov
  2005-09-09  9:28 ` [PATCH 16/25] NTFS: Truncate {a,c,m}time to the ntfs supported time granularity when Anton Altaparmakov
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:27 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 15/25] NTFS: Fix cluster (de)allocators to work when the runlist is NULL and more
      importantly to take a locked runlist rather than them locking it
      which leads to lock reversal.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog  |    3 +++
 fs/ntfs/lcnalloc.c |   39 ++++++++++++++++-----------------------
 fs/ntfs/lcnalloc.h |   21 ++++++++++++---------
 fs/ntfs/mft.c      |    2 +-
 4 files changed, 32 insertions(+), 33 deletions(-)

bbf1813fb8ff9d21171bf22e6d1f0e0393601e86
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -70,6 +70,9 @@ ToDo/Notes:
 	- Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
 	  to ensure that these functions are never called for compressed or
 	  encrypted attributes.
+	- Fix cluster (de)allocators to work when the runlist is NULL and more
+	  importantly to take a locked runlist rather than them locking it
+	  which leads to lock reversal.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -54,6 +54,8 @@ int ntfs_cluster_free_from_rl_nolock(ntf
 	int ret = 0;
 
 	ntfs_debug("Entering.");
+	if (!rl)
+		return 0;
 	for (; rl->length; rl++) {
 		int err;
 
@@ -163,17 +165,9 @@ runlist_element *ntfs_cluster_alloc(ntfs
 	BUG_ON(zone < FIRST_ZONE);
 	BUG_ON(zone > LAST_ZONE);
 
-	/* Return empty runlist if @count == 0 */
-	// FIXME: Do we want to just return NULL instead? (AIA)
-	if (!count) {
-		rl = ntfs_malloc_nofs(PAGE_SIZE);
-		if (!rl)
-			return ERR_PTR(-ENOMEM);
-		rl[0].vcn = start_vcn;
-		rl[0].lcn = LCN_RL_NOT_MAPPED;
-		rl[0].length = 0;
-		return rl;
-	}
+	/* Return NULL if @count is zero. */
+	if (!count)
+		return NULL;
 	/* Take the lcnbmp lock for writing. */
 	down_write(&vol->lcnbmp_lock);
 	/*
@@ -788,7 +782,8 @@ out:
  * @vi:		vfs inode whose runlist describes the clusters to free
  * @start_vcn:	vcn in the runlist of @vi at which to start freeing clusters
  * @count:	number of clusters to free or -1 for all clusters
- * @is_rollback:	if TRUE this is a rollback operation
+ * @write_locked:	true if the runlist is locked for writing
+ * @is_rollback:	true if this is a rollback operation
  *
  * Free @count clusters starting at the cluster @start_vcn in the runlist
  * described by the vfs inode @vi.
@@ -806,17 +801,17 @@ out:
  * Return the number of deallocated clusters (not counting sparse ones) on
  * success and -errno on error.
  *
- * Locking: - The runlist described by @vi must be unlocked on entry and is
- *	      unlocked on return.
- *	    - This function takes the runlist lock of @vi for reading and
- *	      sometimes for writing and sometimes modifies the runlist.
+ * Locking: - The runlist described by @vi must be locked on entry and is
+ *	      locked on return.  Note if the runlist is locked for reading the
+ *	      lock may be dropped and reacquired.  Note the runlist may be
+ *	      modified when needed runlist fragments need to be mapped.
  *	    - The volume lcn bitmap must be unlocked on entry and is unlocked
  *	      on return.
  *	    - This function takes the volume lcn bitmap lock for writing and
  *	      modifies the bitmap contents.
  */
 s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
-		const BOOL is_rollback)
+		const BOOL write_locked, const BOOL is_rollback)
 {
 	s64 delta, to_free, total_freed, real_freed;
 	ntfs_inode *ni;
@@ -848,8 +843,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 
 	total_freed = real_freed = 0;
 
-	down_read(&ni->runlist.lock);
-	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);
+	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, write_locked);
 	if (IS_ERR(rl)) {
 		if (!is_rollback)
 			ntfs_error(vol->sb, "Failed to find first runlist "
@@ -903,7 +897,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 
 			/* Attempt to map runlist. */
 			vcn = rl->vcn;
-			rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE);
+			rl = ntfs_attr_find_vcn_nolock(ni, vcn, write_locked);
 			if (IS_ERR(rl)) {
 				err = PTR_ERR(rl);
 				if (!is_rollback)
@@ -950,7 +944,6 @@ s64 __ntfs_cluster_free(struct inode *vi
 		/* Update the total done clusters. */
 		total_freed += to_free;
 	}
-	up_read(&ni->runlist.lock);
 	if (likely(!is_rollback))
 		up_write(&vol->lcnbmp_lock);
 
@@ -960,7 +953,6 @@ s64 __ntfs_cluster_free(struct inode *vi
 	ntfs_debug("Done.");
 	return real_freed;
 err_out:
-	up_read(&ni->runlist.lock);
 	if (is_rollback)
 		return err;
 	/* If no real clusters were freed, no need to rollback. */
@@ -973,7 +965,8 @@ err_out:
 	 * If rollback fails, set the volume errors flag, emit an error
 	 * message, and return the error code.
 	 */
-	delta = __ntfs_cluster_free(vi, start_vcn, total_freed, TRUE);
+	delta = __ntfs_cluster_free(vi, start_vcn, total_freed, write_locked,
+			TRUE);
 	if (delta < 0) {
 		ntfs_error(vol->sb, "Failed to rollback (error %i).  Leaving "
 				"inconsistent metadata!  Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -43,13 +43,14 @@ extern runlist_element *ntfs_cluster_all
 		const NTFS_CLUSTER_ALLOCATION_ZONES zone);
 
 extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
-		s64 count, const BOOL is_rollback);
+		s64 count, const BOOL write_locked, const BOOL is_rollback);
 
 /**
  * ntfs_cluster_free - free clusters on an ntfs volume
  * @vi:		vfs inode whose runlist describes the clusters to free
  * @start_vcn:	vcn in the runlist of @vi at which to start freeing clusters
  * @count:	number of clusters to free or -1 for all clusters
+ * @write_locked:	true if the runlist is locked for writing
  *
  * Free @count clusters starting at the cluster @start_vcn in the runlist
  * described by the vfs inode @vi.
@@ -64,19 +65,19 @@ extern s64 __ntfs_cluster_free(struct in
  * Return the number of deallocated clusters (not counting sparse ones) on
  * success and -errno on error.
  *
- * Locking: - The runlist described by @vi must be unlocked on entry and is
- *	      unlocked on return.
- *	    - This function takes the runlist lock of @vi for reading and
- *	      sometimes for writing and sometimes modifies the runlist.
+ * Locking: - The runlist described by @vi must be locked on entry and is
+ *	      locked on return.  Note if the runlist is locked for reading the
+ *	      lock may be dropped and reacquired.  Note the runlist may be
+ *	      modified when needed runlist fragments need to be mapped.
  *	    - The volume lcn bitmap must be unlocked on entry and is unlocked
  *	      on return.
  *	    - This function takes the volume lcn bitmap lock for writing and
  *	      modifies the bitmap contents.
  */
 static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
-		s64 count)
+		s64 count, const BOOL write_locked)
 {
-	return __ntfs_cluster_free(vi, start_vcn, count, FALSE);
+	return __ntfs_cluster_free(vi, start_vcn, count, write_locked, FALSE);
 }
 
 extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
@@ -93,8 +94,10 @@ extern int ntfs_cluster_free_from_rl_nol
  *
  * Return 0 on success and -errno on error.
  *
- * Locking: This function takes the volume lcn bitmap lock for writing and
- *	    modifies the bitmap contents.
+ * Locking: - This function takes the volume lcn bitmap lock for writing and
+ *	      modifies the bitmap contents.
+ *	    - The caller must have locked the runlist @rl for reading or
+ *	      writing.
  */
 static inline int ntfs_cluster_free_from_rl(ntfs_volume *vol,
 		const runlist_element *rl)
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1953,7 +1953,7 @@ restore_undo_alloc:
 	a = ctx->attr;
 	a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
 undo_alloc:
-	if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1) < 0) {
+	if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1, TRUE) < 0) {
 		ntfs_error(vol->sb, "Failed to free clusters from mft data "
 				"attribute.%s", es);
 		NVolSetErrors(vol);

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 16/25] NTFS: Truncate {a,c,m}time to the ntfs supported time granularity when
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (14 preceding siblings ...)
  2005-09-09  9:27 ` [PATCH 15/25] NTFS: Fix cluster (de)allocators to work when the runlist is NULL and more Anton Altaparmakov
@ 2005-09-09  9:28 ` Anton Altaparmakov
  2005-09-09  9:28 ` [PATCH 17/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:28 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 16/25] NTFS: Truncate {a,c,m}time to the ntfs supported time granularity when
      updating the times in the inode in ntfs_setattr().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/inode.c   |   12 +++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

1c7d469d47668f4664b892a6cd1c452a0c02d710
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -73,6 +73,8 @@ ToDo/Notes:
 	- Fix cluster (de)allocators to work when the runlist is NULL and more
 	  importantly to take a locked runlist rather than them locking it
 	  which leads to lock reversal.
+	- Truncate {a,c,m}time to the ntfs supported time granularity when
+	  updating the times in the inode in ntfs_setattr().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2430,16 +2430,18 @@ int ntfs_setattr(struct dentry *dentry, 
 			 * We skipped the truncate but must still update
 			 * timestamps.
 			 */
-			ia_valid |= ATTR_MTIME|ATTR_CTIME;
+			ia_valid |= ATTR_MTIME | ATTR_CTIME;
 		}
 	}
-
 	if (ia_valid & ATTR_ATIME)
-		vi->i_atime = attr->ia_atime;
+		vi->i_atime = timespec_trunc(attr->ia_atime,
+				vi->i_sb->s_time_gran);
 	if (ia_valid & ATTR_MTIME)
-		vi->i_mtime = attr->ia_mtime;
+		vi->i_mtime = timespec_trunc(attr->ia_mtime,
+				vi->i_sb->s_time_gran);
 	if (ia_valid & ATTR_CTIME)
-		vi->i_ctime = attr->ia_ctime;
+		vi->i_ctime = timespec_trunc(attr->ia_ctime,
+				vi->i_sb->s_time_gran);
 	mark_inode_dirty(vi);
 out:
 	return err;

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 17/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (15 preceding siblings ...)
  2005-09-09  9:28 ` [PATCH 16/25] NTFS: Truncate {a,c,m}time to the ntfs supported time granularity when Anton Altaparmakov
@ 2005-09-09  9:28 ` Anton Altaparmakov
  2005-09-09  9:28 ` [PATCH 18/25] NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero Anton Altaparmakov
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:28 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 17/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
      fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 
 fs/ntfs/inode.c   |  215 ++++++++++++++++++++++++++++-------------------------
 2 files changed, 116 insertions(+), 101 deletions(-)

67bb103725e4cde322cb4ddb160a12933c5c7072
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -75,6 +75,8 @@ ToDo/Notes:
 	  which leads to lock reversal.
 	- Truncate {a,c,m}time to the ntfs supported time granularity when
 	  updating the times in the inode in ntfs_setattr().
+	- Fixup handling of sparse, compressed, and encrypted attributes in
+	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1013,41 +1013,50 @@ skip_large_dir_stuff:
 		}
 		a = ctx->attr;
 		/* Setup the state. */
-		if (a->non_resident) {
-			NInoSetNonResident(ni);
-			if (a->flags & (ATTR_COMPRESSION_MASK |
-					ATTR_IS_SPARSE)) {
-				if (a->flags & ATTR_COMPRESSION_MASK) {
-					NInoSetCompressed(ni);
-					if (vol->cluster_size > 4096) {
-						ntfs_error(vi->i_sb, "Found "
+		if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
+			if (a->flags & ATTR_COMPRESSION_MASK) {
+				NInoSetCompressed(ni);
+				if (vol->cluster_size > 4096) {
+					ntfs_error(vi->i_sb, "Found "
 							"compressed data but "
 							"compression is "
 							"disabled due to "
 							"cluster size (%i) > "
 							"4kiB.",
 							vol->cluster_size);
-						goto unm_err_out;
-					}
-					if ((a->flags & ATTR_COMPRESSION_MASK)
-							!= ATTR_IS_COMPRESSED) {
-						ntfs_error(vi->i_sb, "Found "
-							"unknown compression "
-							"method or corrupt "
-							"file.");
-						goto unm_err_out;
-					}
+					goto unm_err_out;
+				}
+				if ((a->flags & ATTR_COMPRESSION_MASK)
+						!= ATTR_IS_COMPRESSED) {
+					ntfs_error(vi->i_sb, "Found unknown "
+							"compression method "
+							"or corrupt file.");
+					goto unm_err_out;
 				}
-				if (a->flags & ATTR_IS_SPARSE)
-					NInoSetSparse(ni);
+			}
+			if (a->flags & ATTR_IS_SPARSE)
+				NInoSetSparse(ni);
+		}
+		if (a->flags & ATTR_IS_ENCRYPTED) {
+			if (NInoCompressed(ni)) {
+				ntfs_error(vi->i_sb, "Found encrypted and "
+						"compressed data.");
+				goto unm_err_out;
+			}
+			NInoSetEncrypted(ni);
+		}
+		if (a->non_resident) {
+			NInoSetNonResident(ni);
+			if (NInoCompressed(ni) || NInoSparse(ni)) {
 				if (a->data.non_resident.compression_unit !=
 						4) {
 					ntfs_error(vi->i_sb, "Found "
-						"nonstandard compression unit "
-						"(%u instead of 4).  Cannot "
-						"handle this.",
-						a->data.non_resident.
-						compression_unit);
+							"nonstandard "
+							"compression unit (%u "
+							"instead of 4).  "
+							"Cannot handle this.",
+							a->data.non_resident.
+							compression_unit);
 					err = -EOPNOTSUPP;
 					goto unm_err_out;
 				}
@@ -1065,14 +1074,6 @@ skip_large_dir_stuff:
 						a->data.non_resident.
 						compressed_size);
 			}
-			if (a->flags & ATTR_IS_ENCRYPTED) {
-				if (a->flags & ATTR_COMPRESSION_MASK) {
-					ntfs_error(vi->i_sb, "Found encrypted "
-							"and compressed data.");
-					goto unm_err_out;
-				}
-				NInoSetEncrypted(ni);
-			}
 			if (a->data.non_resident.lowest_vcn) {
 				ntfs_error(vi->i_sb, "First extent of $DATA "
 						"attribute has non zero "
@@ -1212,6 +1213,75 @@ static int ntfs_read_locked_attr_inode(s
 	if (unlikely(err))
 		goto unm_err_out;
 	a = ctx->attr;
+	if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
+		if (a->flags & ATTR_COMPRESSION_MASK) {
+			NInoSetCompressed(ni);
+			if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&
+					ni->name_len)) {
+				ntfs_error(vi->i_sb, "Found compressed "
+						"non-data or named data "
+						"attribute.  Please report "
+						"you saw this message to "
+						"linux-ntfs-dev@lists."
+						"sourceforge.net");
+				goto unm_err_out;
+			}
+			if (vol->cluster_size > 4096) {
+				ntfs_error(vi->i_sb, "Found compressed "
+						"attribute but compression is "
+						"disabled due to cluster size "
+						"(%i) > 4kiB.",
+						vol->cluster_size);
+				goto unm_err_out;
+			}
+			if ((a->flags & ATTR_COMPRESSION_MASK) !=
+					ATTR_IS_COMPRESSED) {
+				ntfs_error(vi->i_sb, "Found unknown "
+						"compression method.");
+				goto unm_err_out;
+			}
+		}
+		/*
+		 * The encryption flag set in an index root just means to
+		 * compress all files.
+		 */
+		if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
+			ntfs_error(vi->i_sb, "Found mst protected attribute "
+					"but the attribute is %s.  Please "
+					"report you saw this message to "
+					"linux-ntfs-dev@lists.sourceforge.net",
+					NInoCompressed(ni) ? "compressed" :
+					"sparse");
+			goto unm_err_out;
+		}
+		if (a->flags & ATTR_IS_SPARSE)
+			NInoSetSparse(ni);
+	}
+	if (a->flags & ATTR_IS_ENCRYPTED) {
+		if (NInoCompressed(ni)) {
+			ntfs_error(vi->i_sb, "Found encrypted and compressed "
+					"data.");
+			goto unm_err_out;
+		}
+		/*
+		 * The encryption flag set in an index root just means to
+		 * encrypt all files.
+		 */
+		if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
+			ntfs_error(vi->i_sb, "Found mst protected attribute "
+					"but the attribute is encrypted.  "
+					"Please report you saw this message "
+					"to linux-ntfs-dev@lists.sourceforge."
+					"net");
+			goto unm_err_out;
+		}
+		if (ni->type != AT_DATA) {
+			ntfs_error(vi->i_sb, "Found encrypted non-data "
+					"attribute.");
+			goto unm_err_out;
+		}
+		NInoSetEncrypted(ni);
+	}
 	if (!a->non_resident) {
 		/* Ensure the attribute name is placed before the value. */
 		if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
@@ -1220,11 +1290,10 @@ static int ntfs_read_locked_attr_inode(s
 					"the attribute value.");
 			goto unm_err_out;
 		}
-		if (NInoMstProtected(ni) || a->flags) {
+		if (NInoMstProtected(ni)) {
 			ntfs_error(vi->i_sb, "Found mst protected attribute "
-					"or attribute with non-zero flags but "
-					"the attribute is resident.  Please "
-					"report you saw this message to "
+					"but the attribute is resident.  "
+					"Please report you saw this message to "
 					"linux-ntfs-dev@lists.sourceforge.net");
 			goto unm_err_out;
 		}
@@ -1250,50 +1319,8 @@ static int ntfs_read_locked_attr_inode(s
 					"the mapping pairs array.");
 			goto unm_err_out;
 		}
-		if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
-			if (a->flags & ATTR_COMPRESSION_MASK) {
-				NInoSetCompressed(ni);
-				if ((ni->type != AT_DATA) || (ni->type ==
-						AT_DATA && ni->name_len)) {
-					ntfs_error(vi->i_sb, "Found compressed "
-							"non-data or named "
-							"data attribute.  "
-							"Please report you "
-							"saw this message to "
-							"linux-ntfs-dev@lists."
-							"sourceforge.net");
-					goto unm_err_out;
-				}
-				if (vol->cluster_size > 4096) {
-					ntfs_error(vi->i_sb, "Found compressed "
-							"attribute but "
-							"compression is "
-							"disabled due to "
-							"cluster size (%i) > "
-							"4kiB.",
-							vol->cluster_size);
-					goto unm_err_out;
-				}
-				if ((a->flags & ATTR_COMPRESSION_MASK) !=
-						ATTR_IS_COMPRESSED) {
-					ntfs_error(vi->i_sb, "Found unknown "
-							"compression method.");
-					goto unm_err_out;
-				}
-			}
-			if (NInoMstProtected(ni)) {
-				ntfs_error(vi->i_sb, "Found mst protected "
-						"attribute but the attribute "
-						"is %s.  Please report you "
-						"saw this message to "
-						"linux-ntfs-dev@lists."
-						"sourceforge.net",
-						NInoCompressed(ni) ?
-						"compressed" : "sparse");
-				goto unm_err_out;
-			}
-			if (a->flags & ATTR_IS_SPARSE)
-				NInoSetSparse(ni);
+		if ((NInoCompressed(ni) || NInoSparse(ni)) &&
+				ni->type != AT_INDEX_ROOT) {
 			if (a->data.non_resident.compression_unit != 4) {
 				ntfs_error(vi->i_sb, "Found nonstandard "
 						"compression unit (%u instead "
@@ -1313,23 +1340,6 @@ static int ntfs_read_locked_attr_inode(s
 			ni->itype.compressed.size = sle64_to_cpu(
 					a->data.non_resident.compressed_size);
 		}
-		if (a->flags & ATTR_IS_ENCRYPTED) {
-			if (a->flags & ATTR_COMPRESSION_MASK) {
-				ntfs_error(vi->i_sb, "Found encrypted and "
-						"compressed data.");
-				goto unm_err_out;
-			}
-			if (NInoMstProtected(ni)) {
-				ntfs_error(vi->i_sb, "Found mst protected "
-						"attribute but the attribute "
-						"is encrypted.  Please report "
-						"you saw this message to "
-						"linux-ntfs-dev@lists."
-						"sourceforge.net");
-				goto unm_err_out;
-			}
-			NInoSetEncrypted(ni);
-		}
 		if (a->data.non_resident.lowest_vcn) {
 			ntfs_error(vi->i_sb, "First extent of attribute has "
 					"non-zero lowest_vcn.");
@@ -1348,12 +1358,12 @@ static int ntfs_read_locked_attr_inode(s
 		vi->i_mapping->a_ops = &ntfs_mst_aops;
 	else
 		vi->i_mapping->a_ops = &ntfs_aops;
-	if (NInoCompressed(ni) || NInoSparse(ni))
+	if ((NInoCompressed(ni) || NInoSparse(ni)) && ni->type != AT_INDEX_ROOT)
 		vi->i_blocks = ni->itype.compressed.size >> 9;
 	else
 		vi->i_blocks = ni->allocated_size >> 9;
 	/*
-	 * Make sure the base inode doesn't go away and attach it to the
+	 * Make sure the base inode does not go away and attach it to the
 	 * attribute inode.
 	 */
 	igrab(base_vi);
@@ -1480,7 +1490,10 @@ static int ntfs_read_locked_index_inode(
 				"after the attribute value.");
 		goto unm_err_out;
 	}
-	/* Compressed/encrypted/sparse index root is not allowed. */
+	/*
+	 * Compressed/encrypted/sparse index root is not allowed, except for
+	 * directories of course but those are not dealt with here.
+	 */
 	if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
 			ATTR_IS_SPARSE)) {
 		ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 18/25] NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (16 preceding siblings ...)
  2005-09-09  9:28 ` [PATCH 17/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
@ 2005-09-09  9:28 ` Anton Altaparmakov
  2005-09-09  9:29 ` [PATCH 19/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:28 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 18/25] NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/aops.c    |   21 +++++++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

8dcdebafb848415eae25924b00c4f0b9ec907da0
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -77,6 +77,8 @@ ToDo/Notes:
 	  updating the times in the inode in ntfs_setattr().
 	- Fixup handling of sparse, compressed, and encrypted attributes in
 	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
+	- Make ntfs_write_block() not instantiate sparse blocks if they contain
+	  only zeroes.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -670,6 +670,27 @@ lock_retry_remap:
 		}
 		/* It is a hole, need to instantiate it. */
 		if (lcn == LCN_HOLE) {
+			u8 *kaddr;
+			unsigned long *bpos, *bend;
+
+			/* Check if the buffer is zero. */
+			kaddr = kmap_atomic(page, KM_USER0);
+			bpos = (unsigned long *)(kaddr + bh_offset(bh));
+			bend = (unsigned long *)((u8*)bpos + blocksize);
+			do {
+				if (unlikely(*bpos))
+					break;
+			} while (likely(++bpos < bend));
+			kunmap_atomic(kaddr, KM_USER0);
+			if (bpos == bend) {
+				/*
+				 * Buffer is zero and sparse, no need to write
+				 * it.
+				 */
+				bh->b_blocknr = -1;
+				clear_buffer_dirty(bh);
+				continue;
+			}
 			// TODO: Instantiate the hole.
 			// clear_buffer_new(bh);
 			// unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 19/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (17 preceding siblings ...)
  2005-09-09  9:28 ` [PATCH 18/25] NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero Anton Altaparmakov
@ 2005-09-09  9:29 ` Anton Altaparmakov
  2005-09-09  9:29 ` [PATCH 20/25] NTFS: Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page Anton Altaparmakov
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 19/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
      fs/ntfs/aops.c::ntfs_writepage().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 +
 fs/ntfs/aops.c    |  104 ++++++++++++++++++++++++-----------------------------
 2 files changed, 49 insertions(+), 57 deletions(-)

bd45fdd209ca49c5010ac9af469c41ae6dd3f145
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -79,6 +79,8 @@ ToDo/Notes:
 	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
 	- Make ntfs_write_block() not instantiate sparse blocks if they contain
 	  only zeroes.
+	- Fixup handling of sparse, compressed, and encrypted attributes in
+	  fs/ntfs/aops.c::ntfs_writepage().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1301,38 +1301,42 @@ retry_writepage:
 		ntfs_debug("Write outside i_size - truncated?");
 		return 0;
 	}
+	/*
+	 * Only $DATA attributes can be encrypted and only unnamed $DATA
+	 * attributes can be compressed.  Index root can have the flags set but
+	 * this means to create compressed/encrypted files, not that the
+	 * attribute is compressed/encrypted.
+	 */
+	if (ni->type != AT_INDEX_ROOT) {
+		/* If file is encrypted, deny access, just like NT4. */
+		if (NInoEncrypted(ni)) {
+			unlock_page(page);
+			BUG_ON(ni->type != AT_DATA);
+			ntfs_debug("Denying write access to encrypted "
+					"file.");
+			return -EACCES;
+		}
+		/* Compressed data streams are handled in compress.c. */
+		if (NInoNonResident(ni) && NInoCompressed(ni)) {
+			BUG_ON(ni->type != AT_DATA);
+			BUG_ON(ni->name_len);
+			// TODO: Implement and replace this with
+			// return ntfs_write_compressed_block(page);
+			unlock_page(page);
+			ntfs_error(vi->i_sb, "Writing to compressed files is "
+					"not supported yet.  Sorry.");
+			return -EOPNOTSUPP;
+		}
+		// TODO: Implement and remove this check.
+		if (NInoNonResident(ni) && NInoSparse(ni)) {
+			unlock_page(page);
+			ntfs_error(vi->i_sb, "Writing to sparse files is not "
+					"supported yet.  Sorry.");
+			return -EOPNOTSUPP;
+		}
+	}
 	/* NInoNonResident() == NInoIndexAllocPresent() */
 	if (NInoNonResident(ni)) {
-		/*
-		 * Only unnamed $DATA attributes can be compressed, encrypted,
-		 * and/or sparse.
-		 */
-		if (ni->type == AT_DATA && !ni->name_len) {
-			/* If file is encrypted, deny access, just like NT4. */
-			if (NInoEncrypted(ni)) {
-				unlock_page(page);
-				ntfs_debug("Denying write access to encrypted "
-						"file.");
-				return -EACCES;
-			}
-			/* Compressed data streams are handled in compress.c. */
-			if (NInoCompressed(ni)) {
-				// TODO: Implement and replace this check with
-				// return ntfs_write_compressed_block(page);
-				unlock_page(page);
-				ntfs_error(vi->i_sb, "Writing to compressed "
-						"files is not supported yet. "
-						"Sorry.");
-				return -EOPNOTSUPP;
-			}
-			// TODO: Implement and remove this check.
-			if (NInoSparse(ni)) {
-				unlock_page(page);
-				ntfs_error(vi->i_sb, "Writing to sparse files "
-						"is not supported yet. Sorry.");
-				return -EOPNOTSUPP;
-			}
-		}
 		/* We have to zero every time due to mmap-at-end-of-file. */
 		if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) {
 			/* The page straddles i_size. */
@@ -1345,14 +1349,16 @@ retry_writepage:
 		/* Handle mst protected attributes. */
 		if (NInoMstProtected(ni))
 			return ntfs_write_mst_block(page, wbc);
-		/* Normal data stream. */
+		/* Normal, non-resident data stream. */
 		return ntfs_write_block(page, wbc);
 	}
 	/*
-	 * Attribute is resident, implying it is not compressed, encrypted,
-	 * sparse, or mst protected.  This also means the attribute is smaller
-	 * than an mft record and hence smaller than a page, so can simply
-	 * return error on any pages with index above 0.
+	 * Attribute is resident, implying it is not compressed, encrypted, or
+	 * mst protected.  This also means the attribute is smaller than an mft
+	 * record and hence smaller than a page, so can simply return error on
+	 * any pages with index above 0.  Note the attribute can actually be
+	 * marked compressed but if it is resident the actual data is not
+	 * compressed so we are ok to ignore the compressed flag here.
 	 */
 	BUG_ON(page_has_buffers(page));
 	BUG_ON(!PageUptodate(page));
@@ -1401,30 +1407,14 @@ retry_writepage:
 	BUG_ON(PageWriteback(page));
 	set_page_writeback(page);
 	unlock_page(page);
-
 	/*
-	 * Here, we don't need to zero the out of bounds area everytime because
-	 * the below memcpy() already takes care of the mmap-at-end-of-file
-	 * requirements. If the file is converted to a non-resident one, then
-	 * the code path use is switched to the non-resident one where the
-	 * zeroing happens on each ntfs_writepage() invocation.
-	 *
-	 * The above also applies nicely when i_size is decreased.
-	 *
-	 * When i_size is increased, the memory between the old and new i_size
-	 * _must_ be zeroed (or overwritten with new data). Otherwise we will
-	 * expose data to userspace/disk which should never have been exposed.
-	 *
-	 * FIXME: Ensure that i_size increases do the zeroing/overwriting and
-	 * if we cannot guarantee that, then enable the zeroing below.  If the
-	 * zeroing below is enabled, we MUST move the unlock_page() from above
-	 * to after the kunmap_atomic(), i.e. just before the
-	 * end_page_writeback().
-	 * UPDATE: ntfs_prepare/commit_write() do the zeroing on i_size
-	 * increases for resident attributes so those are ok.
-	 * TODO: ntfs_truncate(), others?
+	 * Here, we do not need to zero the out of bounds area everytime
+	 * because the below memcpy() already takes care of the
+	 * mmap-at-end-of-file requirements.  If the file is converted to a
+	 * non-resident one, then the code path use is switched to the
+	 * non-resident one where the zeroing happens on each ntfs_writepage()
+	 * invocation.
 	 */
-
 	attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
 	i_size = i_size_read(vi);
 	if (unlikely(attr_len > i_size)) {

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 20/25] NTFS: Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (18 preceding siblings ...)
  2005-09-09  9:29 ` [PATCH 19/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
@ 2005-09-09  9:29 ` Anton Altaparmakov
  2005-09-09  9:30 ` [PATCH 21/25] NTFS: Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case Anton Altaparmakov
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 20/25] NTFS: Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
      lock protection over the buffer submission for i/o which allows the
      removal of the get_bh()/put_bh() pairs for each buffer.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    3 +++
 fs/ntfs/aops.c    |   13 +++----------
 2 files changed, 6 insertions(+), 10 deletions(-)

54b02eb01c0172294e43e2b54d6815f65637c111
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -81,6 +81,9 @@ ToDo/Notes:
 	  only zeroes.
 	- Fixup handling of sparse, compressed, and encrypted attributes in
 	  fs/ntfs/aops.c::ntfs_writepage().
+	- Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
+	  lock protection over the buffer submission for i/o which allows the
+	  removal of the get_bh()/put_bh() pairs for each buffer.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -735,7 +735,7 @@ lock_retry_remap:
 	/* For the error case, need to reset bh to the beginning. */
 	bh = head;
 
-	/* Just an optimization, so ->readpage() isn't called later. */
+	/* Just an optimization, so ->readpage() is not called later. */
 	if (unlikely(!PageUptodate(page))) {
 		int uptodate = 1;
 		do {
@@ -751,7 +751,6 @@ lock_retry_remap:
 
 	/* Setup all mapped, dirty buffers for async write i/o. */
 	do {
-		get_bh(bh);
 		if (buffer_mapped(bh) && buffer_dirty(bh)) {
 			lock_buffer(bh);
 			if (test_clear_buffer_dirty(bh)) {
@@ -789,14 +788,8 @@ lock_retry_remap:
 
 	BUG_ON(PageWriteback(page));
 	set_page_writeback(page);	/* Keeps try_to_free_buffers() away. */
-	unlock_page(page);
 
-	/*
-	 * Submit the prepared buffers for i/o. Note the page is unlocked,
-	 * and the async write i/o completion handler can end_page_writeback()
-	 * at any time after the *first* submit_bh(). So the buffers can then
-	 * disappear...
-	 */
+	/* Submit the prepared buffers for i/o. */
 	need_end_writeback = TRUE;
 	do {
 		struct buffer_head *next = bh->b_this_page;
@@ -804,9 +797,9 @@ lock_retry_remap:
 			submit_bh(WRITE, bh);
 			need_end_writeback = FALSE;
 		}
-		put_bh(bh);
 		bh = next;
 	} while (bh != head);
+	unlock_page(page);
 
 	/* If no i/o was started, need to end_page_writeback(). */
 	if (unlikely(need_end_writeback))

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 21/25] NTFS: Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (19 preceding siblings ...)
  2005-09-09  9:29 ` [PATCH 20/25] NTFS: Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page Anton Altaparmakov
@ 2005-09-09  9:30 ` Anton Altaparmakov
  2005-09-09  9:30 ` [PATCH 22/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 21/25] NTFS: Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
      where a concurrent truncate has truncated the runlist under our feet.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    2 ++
 fs/ntfs/aops.c    |   51 ++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 42 insertions(+), 11 deletions(-)

8273d5d4c28a9fde68f830cc6ff61e37e8ae1dca
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -84,6 +84,8 @@ ToDo/Notes:
 	- Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
 	  lock protection over the buffer submission for i/o which allows the
 	  removal of the get_bh()/put_bh() pairs for each buffer.
+	- Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
+	  where a concurrent truncate has truncated the runlist under our feet.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -204,6 +204,7 @@ static int ntfs_read_block(struct page *
 	nr = i = 0;
 	do {
 		u8 *kaddr;
+		int err;
 
 		if (unlikely(buffer_uptodate(bh)))
 			continue;
@@ -211,6 +212,7 @@ static int ntfs_read_block(struct page *
 			arr[nr++] = bh;
 			continue;
 		}
+		err = 0;
 		bh->b_bdev = vol->sb->s_bdev;
 		/* Is the block within the allowed limits? */
 		if (iblock < lblock) {
@@ -252,7 +254,6 @@ lock_retry_remap:
 				goto handle_hole;
 			/* If first try and runlist unmapped, map and retry. */
 			if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
-				int err;
 				is_retry = TRUE;
 				/*
 				 * Attempt to map runlist, dropping lock for
@@ -263,20 +264,30 @@ lock_retry_remap:
 				if (likely(!err))
 					goto lock_retry_remap;
 				rl = NULL;
-				lcn = err;
 			} else if (!rl)
 				up_read(&ni->runlist.lock);
+			/*
+			 * If buffer is outside the runlist, treat it as a
+			 * hole.  This can happen due to concurrent truncate
+			 * for example.
+			 */
+			if (err == -ENOENT || lcn == LCN_ENOENT) {
+				err = 0;
+				goto handle_hole;
+			}
 			/* Hard error, zero out region. */
+			if (!err)
+				err = -EIO;
 			bh->b_blocknr = -1;
 			SetPageError(page);
 			ntfs_error(vol->sb, "Failed to read from inode 0x%lx, "
 					"attribute type 0x%x, vcn 0x%llx, "
 					"offset 0x%x because its location on "
 					"disk could not be determined%s "
-					"(error code %lli).", ni->mft_no,
+					"(error code %i).", ni->mft_no,
 					ni->type, (unsigned long long)vcn,
 					vcn_ofs, is_retry ? " even after "
-					"retrying" : "", (long long)lcn);
+					"retrying" : "", err);
 		}
 		/*
 		 * Either iblock was outside lblock limits or
@@ -289,9 +300,10 @@ handle_hole:
 handle_zblock:
 		kaddr = kmap_atomic(page, KM_USER0);
 		memset(kaddr + i * blocksize, 0, blocksize);
-		flush_dcache_page(page);
 		kunmap_atomic(kaddr, KM_USER0);
-		set_buffer_uptodate(bh);
+		flush_dcache_page(page);
+		if (likely(!err))
+			set_buffer_uptodate(bh);
 	} while (i++, iblock++, (bh = bh->b_this_page) != head);
 
 	/* Release the lock if we took it. */
@@ -711,20 +723,37 @@ lock_retry_remap:
 			if (likely(!err))
 				goto lock_retry_remap;
 			rl = NULL;
-			lcn = err;
 		} else if (!rl)
 			up_read(&ni->runlist.lock);
+		/*
+		 * If buffer is outside the runlist, truncate has cut it out
+		 * of the runlist.  Just clean and clear the buffer and set it
+		 * uptodate so it can get discarded by the VM.
+		 */
+		if (err == -ENOENT || lcn == LCN_ENOENT) {
+			u8 *kaddr;
+
+			bh->b_blocknr = -1;
+			clear_buffer_dirty(bh);
+			kaddr = kmap_atomic(page, KM_USER0);
+			memset(kaddr + bh_offset(bh), 0, blocksize);
+			kunmap_atomic(kaddr, KM_USER0);
+			flush_dcache_page(page);
+			set_buffer_uptodate(bh);
+			err = 0;
+			continue;
+		}
 		/* Failed to map the buffer, even after retrying. */
+		if (!err)
+			err = -EIO;
 		bh->b_blocknr = -1;
 		ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
 				"attribute type 0x%x, vcn 0x%llx, offset 0x%x "
 				"because its location on disk could not be "
-				"determined%s (error code %lli).", ni->mft_no,
+				"determined%s (error code %i).", ni->mft_no,
 				ni->type, (unsigned long long)vcn,
 				vcn_ofs, is_retry ? " even after "
-				"retrying" : "", (long long)lcn);
-		if (!err)
-			err = -EIO;
+				"retrying" : "", err);
 		break;
 	} while (block++, (bh = bh->b_this_page) != head);
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 22/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (20 preceding siblings ...)
  2005-09-09  9:30 ` [PATCH 21/25] NTFS: Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case Anton Altaparmakov
@ 2005-09-09  9:30 ` Anton Altaparmakov
  2005-09-09  9:30 ` [PATCH 23/25] NTFS: Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c Anton Altaparmakov
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 22/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in
      fs/ntfs/aops.c::ntfs_readpage().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    5 ++---
 fs/ntfs/aops.c    |   41 ++++++++++++++++++++++++-----------------
 2 files changed, 26 insertions(+), 20 deletions(-)

311120eca0013083f5eb0aff13ffb8aa9fdd050c
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -76,11 +76,10 @@ ToDo/Notes:
 	- Truncate {a,c,m}time to the ntfs supported time granularity when
 	  updating the times in the inode in ntfs_setattr().
 	- Fixup handling of sparse, compressed, and encrypted attributes in
-	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
+	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
+	  fs/ntfs/aops.c::ntfs_{read,write}page().
 	- Make ntfs_write_block() not instantiate sparse blocks if they contain
 	  only zeroes.
-	- Fixup handling of sparse, compressed, and encrypted attributes in
-	  fs/ntfs/aops.c::ntfs_writepage().
 	- Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
 	  lock protection over the buffer submission for i/o which allows the
 	  removal of the get_bh()/put_bh() pairs for each buffer.
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -379,31 +379,38 @@ retry_readpage:
 		return 0;
 	}
 	ni = NTFS_I(page->mapping->host);
-
+	/*
+	 * Only $DATA attributes can be encrypted and only unnamed $DATA
+	 * attributes can be compressed.  Index root can have the flags set but
+	 * this means to create compressed/encrypted files, not that the
+	 * attribute is compressed/encrypted.
+	 */
+	if (ni->type != AT_INDEX_ROOT) {
+		/* If attribute is encrypted, deny access, just like NT4. */
+		if (NInoEncrypted(ni)) {
+			BUG_ON(ni->type != AT_DATA);
+			err = -EACCES;
+			goto err_out;
+		}
+		/* Compressed data streams are handled in compress.c. */
+		if (NInoNonResident(ni) && NInoCompressed(ni)) {
+			BUG_ON(ni->type != AT_DATA);
+			BUG_ON(ni->name_len);
+			return ntfs_read_compressed_block(page);
+		}
+	}
 	/* NInoNonResident() == NInoIndexAllocPresent() */
 	if (NInoNonResident(ni)) {
-		/*
-		 * Only unnamed $DATA attributes can be compressed or
-		 * encrypted.
-		 */
-		if (ni->type == AT_DATA && !ni->name_len) {
-			/* If file is encrypted, deny access, just like NT4. */
-			if (NInoEncrypted(ni)) {
-				err = -EACCES;
-				goto err_out;
-			}
-			/* Compressed data streams are handled in compress.c. */
-			if (NInoCompressed(ni))
-				return ntfs_read_compressed_block(page);
-		}
-		/* Normal data stream. */
+		/* Normal, non-resident data stream. */
 		return ntfs_read_block(page);
 	}
 	/*
 	 * Attribute is resident, implying it is not compressed or encrypted.
 	 * This also means the attribute is smaller than an mft record and
 	 * hence smaller than a page, so can simply zero out any pages with
-	 * index above 0.
+	 * index above 0.  Note the attribute can actually be marked compressed
+	 * but if it is resident the actual data is not compressed so we are
+	 * ok to ignore the compressed flag here.
 	 */
 	if (unlikely(page->index > 0)) {
 		kaddr = kmap_atomic(page, KM_USER0);


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 23/25] NTFS: Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (21 preceding siblings ...)
  2005-09-09  9:30 ` [PATCH 22/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
@ 2005-09-09  9:30 ` Anton Altaparmakov
  2005-09-09  9:31 ` [PATCH 24/25] NTFS: Improve scalability by changing the driver global spin lock in Anton Altaparmakov
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 23/25] NTFS: Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    1 +
 fs/ntfs/aops.c    |   38 +++++++++++++++++++++-----------------
 2 files changed, 22 insertions(+), 17 deletions(-)

a01ac532b519dc0e0b4d8bc4e12373e4e4cd1b1a
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -85,6 +85,7 @@ ToDo/Notes:
 	  removal of the get_bh()/put_bh() pairs for each buffer.
 	- Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
 	  where a concurrent truncate has truncated the runlist under our feet.
+	- Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -185,13 +185,15 @@ static int ntfs_read_block(struct page *
 	blocksize_bits = VFS_I(ni)->i_blkbits;
 	blocksize = 1 << blocksize_bits;
 
-	if (!page_has_buffers(page))
+	if (!page_has_buffers(page)) {
 		create_empty_buffers(page, blocksize, 0);
-	bh = head = page_buffers(page);
-	if (unlikely(!bh)) {
-		unlock_page(page);
-		return -ENOMEM;
+		if (unlikely(!page_has_buffers(page))) {
+			unlock_page(page);
+			return -ENOMEM;
+		}
 	}
+	bh = head = page_buffers(page);
+	BUG_ON(!bh);
 
 	iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
 	read_lock_irqsave(&ni->size_lock, flags);
@@ -530,19 +532,21 @@ static int ntfs_write_block(struct page 
 		BUG_ON(!PageUptodate(page));
 		create_empty_buffers(page, blocksize,
 				(1 << BH_Uptodate) | (1 << BH_Dirty));
+		if (unlikely(!page_has_buffers(page))) {
+			ntfs_warning(vol->sb, "Error allocating page "
+					"buffers.  Redirtying page so we try "
+					"again later.");
+			/*
+			 * Put the page back on mapping->dirty_pages, but leave
+			 * its buffers' dirty state as-is.
+			 */
+			redirty_page_for_writepage(wbc, page);
+			unlock_page(page);
+			return 0;
+		}
 	}
 	bh = head = page_buffers(page);
-	if (unlikely(!bh)) {
-		ntfs_warning(vol->sb, "Error allocating page buffers. "
-				"Redirtying page so we try again later.");
-		/*
-		 * Put the page back on mapping->dirty_pages, but leave its
-		 * buffer's dirty state as-is.
-		 */
-		redirty_page_for_writepage(wbc, page);
-		unlock_page(page);
-		return 0;
-	}
+	BUG_ON(!bh);
 
 	/* NOTE: Different naming scheme to ntfs_read_block()! */
 
@@ -910,7 +914,6 @@ static int ntfs_write_mst_block(struct p
 	sync = (wbc->sync_mode == WB_SYNC_ALL);
 
 	/* Make sure we have mapped buffers. */
-	BUG_ON(!page_has_buffers(page));
 	bh = head = page_buffers(page);
 	BUG_ON(!bh);
 
@@ -2397,6 +2400,7 @@ void mark_ntfs_record_dirty(struct page 
 			buffers_to_free = bh;
 	}
 	bh = head = page_buffers(page);
+	BUG_ON(!bh);
 	do {
 		bh_ofs = bh_offset(bh);
 		if (bh_ofs + bh_size <= ofs)

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 24/25] NTFS: Improve scalability by changing the driver global spin lock in
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (22 preceding siblings ...)
  2005-09-09  9:30 ` [PATCH 23/25] NTFS: Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c Anton Altaparmakov
@ 2005-09-09  9:31 ` Anton Altaparmakov
  2005-09-09  9:32 ` [PATCH 25/25] NTFS: 2.1.24 release and some minor final fixes Anton Altaparmakov
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 24/25] NTFS: Improve scalability by changing the driver global spin lock in
      fs/ntfs/aops.c::ntfs_end_buffer_async_read() to a bit spin lock
      in the first buffer head of a page.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 fs/ntfs/ChangeLog |    3 +++
 fs/ntfs/aops.c    |   15 +++++++++------
 2 files changed, 12 insertions(+), 6 deletions(-)

e604635c8bea16f6177e6133eb3efbfb4a029ef6
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -86,6 +86,9 @@ ToDo/Notes:
 	- Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
 	  where a concurrent truncate has truncated the runlist under our feet.
 	- Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
+	- In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
+	  in the first buffer head instead of a driver global spin lock to
+	  improve scalability.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -55,9 +55,8 @@
  */
 static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
-	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
-	struct buffer_head *tmp;
+	struct buffer_head *first, *tmp;
 	struct page *page;
 	ntfs_inode *ni;
 	int page_uptodate = 1;
@@ -89,11 +88,13 @@ static void ntfs_end_buffer_async_read(s
 		}
 	} else {
 		clear_buffer_uptodate(bh);
+		SetPageError(page);
 		ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.",
 				(unsigned long long)bh->b_blocknr);
-		SetPageError(page);
 	}
-	spin_lock_irqsave(&page_uptodate_lock, flags);
+	first = page_buffers(page);
+	local_irq_save(flags);
+	bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
 	clear_buffer_async_read(bh);
 	unlock_buffer(bh);
 	tmp = bh;
@@ -108,7 +109,8 @@ static void ntfs_end_buffer_async_read(s
 		}
 		tmp = tmp->b_this_page;
 	} while (tmp != bh);
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 	/*
 	 * If none of the buffers had errors then we can set the page uptodate,
 	 * but we first have to perform the post read mst fixups, if the
@@ -141,7 +143,8 @@ static void ntfs_end_buffer_async_read(s
 	unlock_page(page);
 	return;
 still_busy:
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 	return;
 }
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 25/25] NTFS: 2.1.24 release and some minor final fixes.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (23 preceding siblings ...)
  2005-09-09  9:31 ` [PATCH 24/25] NTFS: Improve scalability by changing the driver global spin lock in Anton Altaparmakov
@ 2005-09-09  9:32 ` Anton Altaparmakov
  2005-09-10 10:05 ` [2.6-GIT] NTFS: Release 2.1.24 Giuseppe Bilotta
  2005-09-10 13:15 ` Alistair John Strachan
  26 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09  9:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

[PATCH 25/25] NTFS: 2.1.24 release and some minor final fixes.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

---

 Documentation/filesystems/ntfs.txt |   12 ++++++++++++
 fs/ntfs/ChangeLog                  |    4 +++-
 fs/ntfs/Makefile                   |    2 +-
 fs/ntfs/aops.c                     |   10 ++++------
 fs/ntfs/super.c                    |    2 +-
 5 files changed, 21 insertions(+), 9 deletions(-)

7d333d6c739a5cd6d60102ea1a9940cbbb0546ec
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -439,6 +439,18 @@ ChangeLog
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.1.24:
+	- Support journals ($LogFile) which have been modified by chkdsk.  This
+	  means users can boot into Windows after we marked the volume dirty.
+	  The Windows boot will run chkdsk and then reboot.  The user can then
+	  immediately boot into Linux rather than having to do a full Windows
+	  boot first before rebooting into Linux and we will recognize such a
+	  journal and empty it as it is clean by definition.
+	- Support journals ($LogFile) with only one restart page as well as
+	  journals with two different restart pages.  We sanity check both and
+	  either use the only sane one or the more recent one of the two in the
+	  case that both are valid.
+	- Lots of bug fixes and enhancements across the board.
 2.1.23:
 	- Stamp the user space journal, aka transaction log, aka $UsnJrnl, if
 	  it is present and active thus telling Windows and applications using
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,7 +22,7 @@ ToDo/Notes:
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
-2.1.24-WIP
+2.1.24 - Lots of bug fixes and support more clean journal states.
 
 	- Support journals ($LogFile) which have been modified by chkdsk.  This
 	  means users can boot into Windows after we marked the volume dirty.
@@ -89,6 +89,8 @@ ToDo/Notes:
 	- In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
 	  in the first buffer head instead of a driver global spin lock to
 	  improve scalability.
+	- Minor fix to error handling and error message display in
+	  fs/ntfs/aops.c::ntfs_prepare_nonresident_write(). 
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
 	     index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
 	     unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24-WIP\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1727,27 +1727,25 @@ lock_retry_remap:
 					if (likely(!err))
 						goto lock_retry_remap;
 					rl = NULL;
-					lcn = err;
 				} else if (!rl)
 					up_read(&ni->runlist.lock);
 				/*
 				 * Failed to map the buffer, even after
 				 * retrying.
 				 */
+				if (!err)
+					err = -EIO;
 				bh->b_blocknr = -1;
 				ntfs_error(vol->sb, "Failed to write to inode "
 						"0x%lx, attribute type 0x%x, "
 						"vcn 0x%llx, offset 0x%x "
 						"because its location on disk "
 						"could not be determined%s "
-						"(error code %lli).",
+						"(error code %i).",
 						ni->mft_no, ni->type,
 						(unsigned long long)vcn,
 						vcn_ofs, is_retry ? " even "
-						"after retrying" : "",
-						(long long)lcn);
-				if (!err)
-					err = -EIO;
+						"after retrying" : "", err);
 				goto err_out;
 			}
 			/* We now have a successful remap, i.e. lcn >= 0. */
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1688,9 +1688,9 @@ static BOOL load_system_files(ntfs_volum
 	struct super_block *sb = vol->sb;
 	MFT_RECORD *m;
 	VOLUME_INFORMATION *vi;
-	RESTART_PAGE_HEADER *rp;
 	ntfs_attr_search_ctx *ctx;
 #ifdef NTFS_RW
+	RESTART_PAGE_HEADER *rp;
 	int err;
 #endif /* NTFS_RW */
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09  9:19 ` [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version Anton Altaparmakov
@ 2005-09-09 10:36   ` Pekka Enberg
  2005-09-09 11:02     ` Anton Altaparmakov
  2005-09-09 14:51   ` Roland Dreier
  1 sibling, 1 reply; 53+ messages in thread
From: Pekka Enberg @ 2005-09-09 10:36 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On 9/9/05, Anton Altaparmakov <aia21@cam.ac.uk> wrote:
> -static inline void *ntfs_malloc_nofs(unsigned long size)
> +static inline void *__ntfs_malloc(unsigned long size,
> +               unsigned int __nocast gfp_mask)
>  {
>         if (likely(size <= PAGE_SIZE)) {
>                 BUG_ON(!size);
>                 /* kmalloc() has per-CPU caches so is faster for now. */
> -               return kmalloc(PAGE_SIZE, GFP_NOFS);
> -               /* return (void *)__get_free_page(GFP_NOFS | __GFP_HIGHMEM); */
> +               return kmalloc(PAGE_SIZE, gfp_mask);
> +               /* return (void *)__get_free_page(gfp_mask); */
>         }
>         if (likely(size >> PAGE_SHIFT < num_physpages))
> -               return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL);
> +               return __vmalloc(size, gfp_mask, PAGE_KERNEL);

Unrelated to this patch but why do you have this wrapper instead of
using kmalloc() where you can and__vmalloc() where you really have to?

                                     Pekka

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 10:36   ` Pekka Enberg
@ 2005-09-09 11:02     ` Anton Altaparmakov
  2005-09-09 11:15       ` Pekka J Enberg
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 11:02 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, 2005-09-09 at 13:36 +0300, Pekka Enberg wrote:
> On 9/9/05, Anton Altaparmakov <aia21@cam.ac.uk> wrote:
> > -static inline void *ntfs_malloc_nofs(unsigned long size)
> > +static inline void *__ntfs_malloc(unsigned long size,
> > +               unsigned int __nocast gfp_mask)
> >  {
> >         if (likely(size <= PAGE_SIZE)) {
> >                 BUG_ON(!size);
> >                 /* kmalloc() has per-CPU caches so is faster for now. */
> > -               return kmalloc(PAGE_SIZE, GFP_NOFS);
> > -               /* return (void *)__get_free_page(GFP_NOFS | __GFP_HIGHMEM); */
> > +               return kmalloc(PAGE_SIZE, gfp_mask);
> > +               /* return (void *)__get_free_page(gfp_mask); */
> >         }
> >         if (likely(size >> PAGE_SHIFT < num_physpages))
> > -               return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL);
> > +               return __vmalloc(size, gfp_mask, PAGE_KERNEL);
> 
> Unrelated to this patch but why do you have this wrapper instead of
> using kmalloc() where you can and__vmalloc() where you really have to?

Very easy.  Allocations are variable sized.  Without the wrapper I would
have to copy and paste the wrapped code all over the ntfs driver as
there is no way to tell which one I would need in advance.

I used to simply use vmalloc() but that caused loads of people's
machines to run out of vmalloc space in a matter of hours and also
vmalloc is much slower so I added the kmalloc if a page and vmalloc
otherwise.

Note just using kmalloc is no good as it doesn't go high enough in size
(again this problem was being hit by people which is why I had switched
to vmalloc in the first place).

Also kmalloc with size > PAGE_SIZE used to cause machines to run OOM and
give page order > 1 allocation failures, hence why I never use kmalloc
for more than one page any more.

Also note I only use the ntfs_malloc_nofs() wrapper if I have to.  If I
know how much I am allocating or at least know that the maximum is quite
small, I use kmalloc() directly.  It is pretty much only for the runlist
allocations that I use the wrapper as the runlist is typically small but
for fragmented files it can grow huge.  I have seen runlists consuming
over 256kiB of ram, without vmalloc that would be a real problem...

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:02     ` Anton Altaparmakov
@ 2005-09-09 11:15       ` Pekka J Enberg
  2005-09-09 11:25         ` Anton Altaparmakov
  0 siblings, 1 reply; 53+ messages in thread
From: Pekka J Enberg @ 2005-09-09 11:15 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> Also note I only use the ntfs_malloc_nofs() wrapper if I have to.  If I
> know how much I am allocating or at least know that the maximum is quite
> small, I use kmalloc() directly.  It is pretty much only for the runlist
> allocations that I use the wrapper as the runlist is typically small but
> for fragmented files it can grow huge.  I have seen runlists consuming
> over 256kiB of ram, without vmalloc that would be a real problem...

So things like

	rl = ntfs_malloc_nofs(rlsize = PAGE_SIZE);

should be changed to kmalloc(), right?

			Pekka

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:15       ` Pekka J Enberg
@ 2005-09-09 11:25         ` Anton Altaparmakov
  2005-09-09 11:38           ` Pekka J Enberg
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 11:25 UTC (permalink / raw)
  To: Pekka J Enberg; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, 2005-09-09 at 14:15 +0300, Pekka J Enberg wrote:
> On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> > Also note I only use the ntfs_malloc_nofs() wrapper if I have to.  If I
> > know how much I am allocating or at least know that the maximum is quite
> > small, I use kmalloc() directly.  It is pretty much only for the runlist
> > allocations that I use the wrapper as the runlist is typically small but
> > for fragmented files it can grow huge.  I have seen runlists consuming
> > over 256kiB of ram, without vmalloc that would be a real problem...
> 
> So things like
> 
> 	rl = ntfs_malloc_nofs(rlsize = PAGE_SIZE);
> 
> should be changed to kmalloc(), right?

They could be but I would rather not.  What if one day I decide to
change how ntfs_malloc_nofs() works?  Then it would be needed to
carefully go through the whole driver looking for places where kmalloc
is used and change those, too.

>From a software design point of view you should never mix interfaces
when accessing an object if you want clean and maintainable code.  And
using kmalloc() sometimes and ntfs_malloc_nofs() at other times for the
same object would violate that.

The wrapper is a static inline so I would assume gcc can optimize away
everything when a constant size is passed in like in the example you
point out above.

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:25         ` Anton Altaparmakov
@ 2005-09-09 11:38           ` Pekka J Enberg
  2005-09-09 11:48             ` Anton Altaparmakov
  0 siblings, 1 reply; 53+ messages in thread
From: Pekka J Enberg @ 2005-09-09 11:38 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> They could be but I would rather not.  What if one day I decide to
> change how ntfs_malloc_nofs() works?  Then it would be needed to
> carefully go through the whole driver looking for places where kmalloc
> is used and change those, too.
> 
> From a software design point of view you should never mix interfaces
> when accessing an object if you want clean and maintainable code.  And
> using kmalloc() sometimes and ntfs_malloc_nofs() at other times for the
> same object would violate that.
> 
> The wrapper is a static inline so I would assume gcc can optimize away
> everything when a constant size is passed in like in the example you
> point out above.

Hey, I am not worried about performance. It's just that filesystems (or 
any other subsystem for that matter) should not invent their own memory 
allocators. Perhaps should provide a generic __vmalloc_fast() if this is 
really required?

				Pekka

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:38           ` Pekka J Enberg
@ 2005-09-09 11:48             ` Anton Altaparmakov
  2005-09-09 11:51               ` Anton Altaparmakov
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 11:48 UTC (permalink / raw)
  To: Pekka J Enberg; +Cc: linux-ntfs-dev, linux-kernel, Linus Torvalds

On Fri, 2005-09-09 at 14:38 +0300, Pekka J Enberg wrote: 
> On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> > They could be but I would rather not.  What if one day I decide to
> > change how ntfs_malloc_nofs() works?  Then it would be needed to
> > carefully go through the whole driver looking for places where kmalloc
> > is used and change those, too.
> > 
> > From a software design point of view you should never mix interfaces
> > when accessing an object if you want clean and maintainable code.  And
> > using kmalloc() sometimes and ntfs_malloc_nofs() at other times for the
> > same object would violate that.
> > 
> > The wrapper is a static inline so I would assume gcc can optimize away
> > everything when a constant size is passed in like in the example you
> > point out above.
> 
> Hey, I am not worried about performance. It's just that filesystems (or 
> any other subsystem for that matter) should not invent their own memory 
> allocators. Perhaps should provide a generic __vmalloc_fast() if this is 
> really required?

Even if that were the case I would still use a wrapper.  I am far too
lazy to write __vmalloc(x, GFP_NOFS | __GFP_HIGHMEM); or even
__vmalloc(x, GFP_NOFS | __GFP_HIGHMEM | __GFP_NOFAIL); when I can get
away with ntfs_malloc_nofs{,nofail}()...  (-;

I completely disagree with you given that this is not "inventing [...]
own memory allocators", it is just a convenient short hand.  I am sure a
lot of people would agree with you though.  It is just a matter of
personal preference.

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:48             ` Anton Altaparmakov
@ 2005-09-09 11:51               ` Anton Altaparmakov
  2005-09-09 12:02                 ` Pekka J Enberg
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 11:51 UTC (permalink / raw)
  To: Pekka J Enberg; +Cc: linux-ntfs-dev, linux-kernel, Linus Torvalds

On Fri, 2005-09-09 at 12:48 +0100, Anton Altaparmakov wrote:
> On Fri, 2005-09-09 at 14:38 +0300, Pekka J Enberg wrote: 
> > On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> > > They could be but I would rather not.  What if one day I decide to
> > > change how ntfs_malloc_nofs() works?  Then it would be needed to
> > > carefully go through the whole driver looking for places where kmalloc
> > > is used and change those, too.
> > > 
> > > From a software design point of view you should never mix interfaces
> > > when accessing an object if you want clean and maintainable code.  And
> > > using kmalloc() sometimes and ntfs_malloc_nofs() at other times for the
> > > same object would violate that.
> > > 
> > > The wrapper is a static inline so I would assume gcc can optimize away
> > > everything when a constant size is passed in like in the example you
> > > point out above.
> > 
> > Hey, I am not worried about performance. It's just that filesystems (or 
> > any other subsystem for that matter) should not invent their own memory 
> > allocators. Perhaps should provide a generic __vmalloc_fast() if this is 
> > really required?
> 
> Even if that were the case I would still use a wrapper.  I am far too
> lazy to write __vmalloc(x, GFP_NOFS | __GFP_HIGHMEM); or even
> __vmalloc(x, GFP_NOFS | __GFP_HIGHMEM | __GFP_NOFAIL); when I can get
> away with ntfs_malloc_nofs{,nofail}()...  (-;
> 
> I completely disagree with you given that this is not "inventing [...]
> own memory allocators", it is just a convenient short hand.  I am sure a
> lot of people would agree with you though.  It is just a matter of
> personal preference.

I should add that this is not ntfs only, the idea is from another file
system which uses it, too.  Can't remember which one it was, though (xfs
maybe?).

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 11:51               ` Anton Altaparmakov
@ 2005-09-09 12:02                 ` Pekka J Enberg
  2005-09-09 12:08                   ` Anton Altaparmakov
  0 siblings, 1 reply; 53+ messages in thread
From: Pekka J Enberg @ 2005-09-09 12:02 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: linux-ntfs-dev, linux-kernel, Linus Torvalds

On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> > I completely disagree with you given that this is not "inventing [...]
> > own memory allocators", it is just a convenient short hand.  I am sure a
> > lot of people would agree with you though.  It is just a matter of
> > personal preference.
> 
> I should add that this is not ntfs only, the idea is from another file
> system which uses it, too.  Can't remember which one it was, though (xfs
> maybe?).

Indeed. It is not just a matter of personal preference but also a matter 
of subsystems introducing duplicate code like this. Quick grepping shows 
UDF doing same thing  and XFS doing slightly differently but I am pretty 
sure I've seen it elsewhere too.

				Pekka

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 12:02                 ` Pekka J Enberg
@ 2005-09-09 12:08                   ` Anton Altaparmakov
  2005-09-09 19:15                     ` Horst von Brand
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 12:08 UTC (permalink / raw)
  To: Pekka J Enberg; +Cc: linux-ntfs-dev, linux-kernel, Linus Torvalds

On Fri, 2005-09-09 at 15:02 +0300, Pekka J Enberg wrote:
> On Fri, 9 Sep 2005, Anton Altaparmakov wrote:
> > > I completely disagree with you given that this is not "inventing [...]
> > > own memory allocators", it is just a convenient short hand.  I am sure a
> > > lot of people would agree with you though.  It is just a matter of
> > > personal preference.
> > 
> > I should add that this is not ntfs only, the idea is from another file
> > system which uses it, too.  Can't remember which one it was, though (xfs
> > maybe?).
> 
> Indeed. It is not just a matter of personal preference but also a matter 
> of subsystems introducing duplicate code like this. Quick grepping shows 
> UDF doing same thing  and XFS doing slightly differently but I am pretty 
> sure I've seen it elsewhere too.

Yes, that is usually a good indication that a generic function should be
provided.  However having a generic function with complicated and long
arguments is no use as everyone will want their own shorter one anyway.
And given the function is static inline it actually makes no difference
to the generated code size.  Also calling it __vmalloc_fast makes no
sense as it doesn't always use vmalloc...  Given we have kmalloc and
vmalloc maybe it should be just malloc?

Obviously if there were a suitable generic function I would use it but I
and I imagine all the other users would still wrap it with the old name.

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09  9:19 ` [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version Anton Altaparmakov
  2005-09-09 10:36   ` Pekka Enberg
@ 2005-09-09 14:51   ` Roland Dreier
  2005-09-09 14:53     ` Christoph Hellwig
  1 sibling, 1 reply; 53+ messages in thread
From: Roland Dreier @ 2005-09-09 14:51 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

    Anton> fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc()
    Anton> based allocations with __GFP_HIGHMEM, analogous to how the
    Anton> vmalloc() based allocations are done.

Does it make sense to pass __GFP_HIGHMEM to kmalloc()?  kmalloc() has
to return memory from lowmem, since it gives you an address from the
direct-mapped kernel area, so at best kmalloc() ignores this flag.

 - R.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 14:51   ` Roland Dreier
@ 2005-09-09 14:53     ` Christoph Hellwig
  2005-09-09 14:58       ` Anton Altaparmakov
  0 siblings, 1 reply; 53+ messages in thread
From: Christoph Hellwig @ 2005-09-09 14:53 UTC (permalink / raw)
  To: Roland Dreier
  Cc: Anton Altaparmakov, Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, Sep 09, 2005 at 07:51:23AM -0700, Roland Dreier wrote:
>     Anton> fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc()
>     Anton> based allocations with __GFP_HIGHMEM, analogous to how the
>     Anton> vmalloc() based allocations are done.
> 
> Does it make sense to pass __GFP_HIGHMEM to kmalloc()?

Not at all (as you indicated below..)

> kmalloc() has
> to return memory from lowmem, since it gives you an address from the
> direct-mapped kernel area, so at best kmalloc() ignores this flag.


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 14:53     ` Christoph Hellwig
@ 2005-09-09 14:58       ` Anton Altaparmakov
  0 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-09 14:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Roland Dreier, Linus Torvalds, linux-kernel, linux-ntfs-dev

On Fri, 2005-09-09 at 15:53 +0100, Christoph Hellwig wrote:
> On Fri, Sep 09, 2005 at 07:51:23AM -0700, Roland Dreier wrote:
> >     Anton> fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc()
> >     Anton> based allocations with __GFP_HIGHMEM, analogous to how the
> >     Anton> vmalloc() based allocations are done.
> > 
> > Does it make sense to pass __GFP_HIGHMEM to kmalloc()?
> 
> Not at all (as you indicated below..)
> 
> > kmalloc() has
> > to return memory from lowmem, since it gives you an address from the
> > direct-mapped kernel area, so at best kmalloc() ignores this flag.

Correct, but it doesn't do any harm either AFAICS (it gets masked out by
kmalloc) and it makes the ntfs code simpler since I can then use the
same gfp_flags parameter both for the kmalloc and the vmalloc rather
than needing two different ones.

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version.
  2005-09-09 12:08                   ` Anton Altaparmakov
@ 2005-09-09 19:15                     ` Horst von Brand
  0 siblings, 0 replies; 53+ messages in thread
From: Horst von Brand @ 2005-09-09 19:15 UTC (permalink / raw)
  To: Anton Altaparmakov
  Cc: Pekka J Enberg, linux-ntfs-dev, linux-kernel, Linus Torvalds

Anton Altaparmakov <aia21@cam.ac.uk> wrote:
> On Fri, 2005-09-09 at 15:02 +0300, Pekka J Enberg wrote:
> > On Fri, 9 Sep 2005, Anton Altaparmakov wrote:

> > > > I completely disagree with you given that this is not "inventing
> > > > [...] own memory allocators", it is just a convenient short hand.
> > > > I am sure a lot of people would agree with you though.  It is just
> > > > a matter of personal preference.

> > > I should add that this is not ntfs only, the idea is from another file
> > > system which uses it, too.  Can't remember which one it was, though (xfs
> > > maybe?).

> > Indeed. It is not just a matter of personal preference but also a matter 
> > of subsystems introducing duplicate code like this. Quick grepping shows 
> > UDF doing same thing  and XFS doing slightly differently but I am pretty 
> > sure I've seen it elsewhere too.

> Yes, that is usually a good indication that a generic function should be
> provided.  However having a generic function with complicated and long
> arguments is no use as everyone will want their own shorter one anyway.
> And given the function is static inline it actually makes no difference
> to the generated code size.  Also calling it __vmalloc_fast makes no
> sense as it doesn't always use vmalloc...  Given we have kmalloc and
> vmalloc maybe it should be just malloc?

That it makes no difference to the generated code isn't enough. If somebody
if going over the kernel with a fine comb trying to fix memory allocations
(example as here), she will have to remember half a dozen slightly
different ways of doing the same thing, for no good reason. And probably
miss a bundle in the process. This is bad in itself.

> Obviously if there were a suitable generic function I would use it but I
> and I imagine all the other users would still wrap it with the old name.

I'd hope not.

[Yes, I can understand that each subsystem has its own "culture", and
 trying to force them all into the same mold is friction too.]
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (24 preceding siblings ...)
  2005-09-09  9:32 ` [PATCH 25/25] NTFS: 2.1.24 release and some minor final fixes Anton Altaparmakov
@ 2005-09-10 10:05 ` Giuseppe Bilotta
  2005-09-10 13:28   ` Anton Altaparmakov
  2005-09-10 13:15 ` Alistair John Strachan
  26 siblings, 1 reply; 53+ messages in thread
From: Giuseppe Bilotta @ 2005-09-10 10:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ntfs-dev

On Fri, 9 Sep 2005 10:18:01 +0100 (BST), Anton Altaparmakov wrote:

> Hi Linus, please pull from
> 
> rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD
> 
> This is the next NTFS update containing a ton of bug fixes several of 
> which fix bugs people actually hit in the big bad world...
> 
> Please apply.  Thanks!
> 
> I am sending the changesets as actual patches generated using git 
> format-patch for non-git users in follow up emails (in reply to this one).
> 
> Best regards,
> 
> 	Anton

BTW Anton, while looking for the best permission masks to be used when
mounting my NTFS paritions, I spotted what I think is a bug, or at
least an inconsistency between the way all fs drivers I use handle
umasks & friends, and the way NTFS does it. Basically, all the other
fs drivers take an octal representation of the masks. NTFS, instead,
seems to use _decimal_

(Of course, the spontaneous question is how comes that there isn't a
common fs code to read the common options?)

-- 
Giuseppe "Oblomov" Bilotta

Hic manebimus optime


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
                   ` (25 preceding siblings ...)
  2005-09-10 10:05 ` [2.6-GIT] NTFS: Release 2.1.24 Giuseppe Bilotta
@ 2005-09-10 13:15 ` Alistair John Strachan
  2005-09-10 13:23   ` Anton Altaparmakov
  26 siblings, 1 reply; 53+ messages in thread
From: Alistair John Strachan @ 2005-09-10 13:15 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Friday 09 September 2005 10:18, Anton Altaparmakov wrote:
> Hi Linus, please pull from
>
> rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD
>
> This is the next NTFS update containing a ton of bug fixes several of
> which fix bugs people actually hit in the big bad world...
>
> Please apply.  Thanks!
>
> I am sending the changesets as actual patches generated using git
> format-patch for non-git users in follow up emails (in reply to this one).
>

Anton,

Do these changes allow us to mount an NTFS volume created by Windows 
Vista/Longhorn beta 1 yet? I tried the driver in 2.6.13, and it complains 
about these $LogFile states, and ntfscp refuses to work.

If you're unaware of the problem, I'm happy to help debug it.

-- 
Cheers,
Alistair.

'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 13:15 ` Alistair John Strachan
@ 2005-09-10 13:23   ` Anton Altaparmakov
  2005-09-25 19:12     ` Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.) Szakacsits Szabolcs
  0 siblings, 1 reply; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-10 13:23 UTC (permalink / raw)
  To: Alistair John Strachan; +Cc: Linus Torvalds, linux-kernel, linux-ntfs-dev

On Sat, 10 Sep 2005, Alistair John Strachan wrote:
> On Friday 09 September 2005 10:18, Anton Altaparmakov wrote:
> > Hi Linus, please pull from
> >
> > rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD
> >
> > This is the next NTFS update containing a ton of bug fixes several of
> > which fix bugs people actually hit in the big bad world...
> >
> > Please apply.  Thanks!
> >
> > I am sending the changesets as actual patches generated using git
> > format-patch for non-git users in follow up emails (in reply to this one).
> 
> Do these changes allow us to mount an NTFS volume created by Windows 
> Vista/Longhorn beta 1 yet? I tried the driver in 2.6.13, and it complains 
> about these $LogFile states, and ntfscp refuses to work.
> 
> If you're unaware of the problem, I'm happy to help debug it.

I am indeed unaware of the problem.  Could you try the latest kernel with 
the ntfs patches in it (Linus already merged them in the official git 
tree) and tell me if it now works?  Thanks a lot in advance!

Note you will need to try the ntfs driver itself and not ntfscp as libntfs 
does not have these changes yet hence ntfscp will not work just the same 
(it does not use the kernel driver at all, it only uses libntfs).

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 10:05 ` [2.6-GIT] NTFS: Release 2.1.24 Giuseppe Bilotta
@ 2005-09-10 13:28   ` Anton Altaparmakov
  2005-09-10 13:38     ` Anton Altaparmakov
                       ` (3 more replies)
  0 siblings, 4 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-10 13:28 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: linux-kernel, linux-ntfs-dev

On Sat, 10 Sep 2005, Giuseppe Bilotta wrote:
> On Fri, 9 Sep 2005 10:18:01 +0100 (BST), Anton Altaparmakov wrote:
> > This is the next NTFS update containing a ton of bug fixes several of 
> > which fix bugs people actually hit in the big bad world...
> > 
> > Please apply.  Thanks!
> > 
> > I am sending the changesets as actual patches generated using git 
> > format-patch for non-git users in follow up emails (in reply to this one).
> 
> BTW Anton, while looking for the best permission masks to be used when
> mounting my NTFS paritions, I spotted what I think is a bug, or at
> least an inconsistency between the way all fs drivers I use handle
> umasks & friends, and the way NTFS does it. Basically, all the other
> fs drivers take an octal representation of the masks. NTFS, instead,
> seems to use _decimal_

NTFS takes any.  It is happy with octal, decimal, and hex.  The ntfs 
driver uses linux/lib/vsprintf.c::simple_strtoul() with a zero base which 
autodetects which base to use so if you use umask=0222 it will take this 
as octal and if you use umask=222 it will take this as decimal and if you 
use 0x222 it will take this as decimal.

I do not see what is wrong with that.  It behaves exactly like I would 
expect it to.  Maybe I have strange expectations?  (-;

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 13:28   ` Anton Altaparmakov
@ 2005-09-10 13:38     ` Anton Altaparmakov
  2005-09-10 14:53     ` Bernd Eckenfels
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-10 13:38 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: linux-kernel, linux-ntfs-dev

On Sat, 10 Sep 2005, Anton Altaparmakov wrote:
> On Sat, 10 Sep 2005, Giuseppe Bilotta wrote:
> > On Fri, 9 Sep 2005 10:18:01 +0100 (BST), Anton Altaparmakov wrote:
> > > This is the next NTFS update containing a ton of bug fixes several of 
> > > which fix bugs people actually hit in the big bad world...
> > > 
> > > Please apply.  Thanks!
> > > 
> > > I am sending the changesets as actual patches generated using git 
> > > format-patch for non-git users in follow up emails (in reply to this one).
> > 
> > BTW Anton, while looking for the best permission masks to be used when
> > mounting my NTFS paritions, I spotted what I think is a bug, or at
> > least an inconsistency between the way all fs drivers I use handle
> > umasks & friends, and the way NTFS does it. Basically, all the other
> > fs drivers take an octal representation of the masks. NTFS, instead,
> > seems to use _decimal_
> 
> NTFS takes any.  It is happy with octal, decimal, and hex.  The ntfs 
> driver uses linux/lib/vsprintf.c::simple_strtoul() with a zero base which 
> autodetects which base to use so if you use umask=0222 it will take this 
> as octal and if you use umask=222 it will take this as decimal and if you 
> use 0x222 it will take this as decimal.
                                 ^^^^^^^ hexadecimal

> I do not see what is wrong with that.  It behaves exactly like I would 
> expect it to.  Maybe I have strange expectations?  (-;

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 13:28   ` Anton Altaparmakov
  2005-09-10 13:38     ` Anton Altaparmakov
@ 2005-09-10 14:53     ` Bernd Eckenfels
  2005-09-11 11:30     ` Giuseppe Bilotta
  2005-09-12  2:13     ` Horst von Brand
  3 siblings, 0 replies; 53+ messages in thread
From: Bernd Eckenfels @ 2005-09-10 14:53 UTC (permalink / raw)
  To: linux-kernel

In article <Pine.LNX.4.60.0509101424260.20200@hermes-1.csi.cam.ac.uk> you wrote:
> I do not see what is wrong with that.  It behaves exactly like I would 
> expect it to.  Maybe I have strange expectations?  (-;

Well, the others bahave differently, so we need to fix all others.

Greetings
Bernd

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 13:28   ` Anton Altaparmakov
  2005-09-10 13:38     ` Anton Altaparmakov
  2005-09-10 14:53     ` Bernd Eckenfels
@ 2005-09-11 11:30     ` Giuseppe Bilotta
  2005-09-12  2:13     ` Horst von Brand
  3 siblings, 0 replies; 53+ messages in thread
From: Giuseppe Bilotta @ 2005-09-11 11:30 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ntfs-dev

On Sat, 10 Sep 2005 14:28:49 +0100 (BST), Anton Altaparmakov wrote:

> NTFS takes any.  It is happy with octal, decimal, and hex.  The ntfs 
> driver uses linux/lib/vsprintf.c::simple_strtoul() with a zero base which 
> autodetects which base to use so if you use umask=0222 it will take this 
> as octal and if you use umask=222 it will take this as decimal and if you 
> use 0x222 it will take this as decimal.

Uh. I was pretty sure I had tried the 0 prefix to get octal but it
failed, IIRC. Maybe I didn't run the test correctly, though.

> I do not see what is wrong with that.  It behaves exactly like I would 
> expect it to.  Maybe I have strange expectations?  (-;

I don't actually care one way or the other. I was just hoping for more
consistency across drivers :) This is why I went as far as suggesting
code sharing.

-- 
Giuseppe "Oblomov" Bilotta

"E la storia dell'umanità, babbo?"
"Ma niente: prima si fanno delle cazzate,
 poi si studia che cazzate si sono fatte"
(Altan)
("And what about the history of the human race, dad?"
 "Oh, nothing special: first they make some foolish things,
  then you study what foolish things have been made")


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-10 13:28   ` Anton Altaparmakov
                       ` (2 preceding siblings ...)
  2005-09-11 11:30     ` Giuseppe Bilotta
@ 2005-09-12  2:13     ` Horst von Brand
  2005-09-12  9:08       ` Anton Altaparmakov
  3 siblings, 1 reply; 53+ messages in thread
From: Horst von Brand @ 2005-09-12  2:13 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Giuseppe Bilotta, linux-kernel, linux-ntfs-dev

Anton Altaparmakov <aia21@cam.ac.uk> wrote:
> On Sat, 10 Sep 2005, Giuseppe Bilotta wrote:

[...]

> > BTW Anton, while looking for the best permission masks to be used when
> > mounting my NTFS paritions, I spotted what I think is a bug, or at
> > least an inconsistency between the way all fs drivers I use handle
> > umasks & friends, and the way NTFS does it. Basically, all the other
> > fs drivers take an octal representation of the masks. NTFS, instead,
> > seems to use _decimal_

> NTFS takes any.  It is happy with octal, decimal, and hex.  The ntfs 
> driver uses linux/lib/vsprintf.c::simple_strtoul() with a zero base which 
> autodetects which base to use so if you use umask=0222 it will take this 
> as octal and if you use umask=222 it will take this as decimal and if you 
> use 0x222 it will take this as decimal.

> I do not see what is wrong with that.  It behaves exactly like I would 
> expect it to.  Maybe I have strange expectations?  (-;

At least chmod(1) takes /only/ octal, so 666 isn't the number of the beast,
but plain rw for everybody ;-)

I think this should be consistent with that.
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [2.6-GIT] NTFS: Release 2.1.24.
  2005-09-12  2:13     ` Horst von Brand
@ 2005-09-12  9:08       ` Anton Altaparmakov
  0 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-09-12  9:08 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Giuseppe Bilotta, linux-kernel, linux-ntfs-dev

On Sun, 11 Sep 2005, Horst von Brand wrote:
> Anton Altaparmakov <aia21@cam.ac.uk> wrote:
> > On Sat, 10 Sep 2005, Giuseppe Bilotta wrote:
> [...]
> > > BTW Anton, while looking for the best permission masks to be used when
> > > mounting my NTFS paritions, I spotted what I think is a bug, or at
> > > least an inconsistency between the way all fs drivers I use handle
> > > umasks & friends, and the way NTFS does it. Basically, all the other
> > > fs drivers take an octal representation of the masks. NTFS, instead,
> > > seems to use _decimal_
> 
> > NTFS takes any.  It is happy with octal, decimal, and hex.  The ntfs 
> > driver uses linux/lib/vsprintf.c::simple_strtoul() with a zero base which 
> > autodetects which base to use so if you use umask=0222 it will take this 
> > as octal and if you use umask=222 it will take this as decimal and if you 
> > use 0x222 it will take this as decimal.
> 
> > I do not see what is wrong with that.  It behaves exactly like I would 
> > expect it to.  Maybe I have strange expectations?  (-;
> 
> At least chmod(1) takes /only/ octal, so 666 isn't the number of the beast,
> but plain rw for everybody ;-)

Ah, oops.  I don't think I ever noticed that.  I always have given it 
0xyz, i.e. "proper" octal.

> I think this should be consistent with that.

Yes, I fully agree.  It should be consistent.  I will patch ntfs and send 
it to Linus for 2.6.14.

Thanks to both of you for pointing this out.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.)
  2005-09-10 13:23   ` Anton Altaparmakov
@ 2005-09-25 19:12     ` Szakacsits Szabolcs
  2005-09-25 22:35       ` Alistair John Strachan
  0 siblings, 1 reply; 53+ messages in thread
From: Szakacsits Szabolcs @ 2005-09-25 19:12 UTC (permalink / raw)
  To: Anton Altaparmakov
  Cc: Alistair John Strachan, Linus Torvalds, linux-kernel,
	linux-ntfs-dev


On Sat, 10 Sep 2005, Anton Altaparmakov wrote:
> On Sat, 10 Sep 2005, Alistair John Strachan wrote:
> >
> > Do these changes allow us to mount an NTFS volume created by Windows 
> > Vista/Longhorn beta 1 yet? 

So far the current NTFS code worked fine with Longhorn/Vista releases.
WinFS and TxFS (transactional NTFS) are on top of current NTFS and MS
engineers claim that they work hard to avoid on-disk NTFS format changes.

> > I tried the driver in 2.6.13, and it complains about these
> > $LogFile states, and ntfscp refuses to work. 

This happens probably due to the recent, strict $LogFile check changes.
Several people reported these and Anton is investigating it. 

> > If you're unaware of the problem, I'm happy to help debug it.

Anybody [keep] confirming that the current Linux NTFS code still works 
on the latest Vista beta releases would be highly encouraging for all 
of us ;)
 
> I am indeed unaware of the problem.  Could you try the latest kernel
> with the ntfs patches in it (Linus already merged them in the official
> git tree) and tell me if it now works?  Thanks a lot in advance!

Alistair, any result?
 
> Note you will need to try the ntfs driver itself and not ntfscp as libntfs 
> does not have these changes yet hence ntfscp will not work just the same 
> (it does not use the kernel driver at all, it only uses libntfs).

The latest ntfsprogs CVS has also these changes and every tool should work
fine with Vista (ntfscp, ntfsresize, ntfsundelete, ntfsclone, etc).

	Szaka


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.)
  2005-09-25 19:12     ` Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.) Szakacsits Szabolcs
@ 2005-09-25 22:35       ` Alistair John Strachan
  2005-09-25 23:39         ` Szakacsits Szabolcs
  2005-10-13 15:13         ` Alistair John Strachan
  0 siblings, 2 replies; 53+ messages in thread
From: Alistair John Strachan @ 2005-09-25 22:35 UTC (permalink / raw)
  To: Szakacsits Szabolcs
  Cc: Anton Altaparmakov, Linus Torvalds, linux-kernel, linux-ntfs-dev

On Sunday 25 September 2005 20:12, Szakacsits Szabolcs wrote:
> On Sat, 10 Sep 2005, Anton Altaparmakov wrote:
> > On Sat, 10 Sep 2005, Alistair John Strachan wrote:
> > > Do these changes allow us to mount an NTFS volume created by Windows
> > > Vista/Longhorn beta 1 yet?
>
> So far the current NTFS code worked fine with Longhorn/Vista releases.
> WinFS and TxFS (transactional NTFS) are on top of current NTFS and MS
> engineers claim that they work hard to avoid on-disk NTFS format changes.
>
> > > I tried the driver in 2.6.13, and it complains about these
> > > $LogFile states, and ntfscp refuses to work.
>
> This happens probably due to the recent, strict $LogFile check changes.
> Several people reported these and Anton is investigating it.
>
> > > If you're unaware of the problem, I'm happy to help debug it.
>
> Anybody [keep] confirming that the current Linux NTFS code still works
> on the latest Vista beta releases would be highly encouraging for all
> of us ;)
>
> > I am indeed unaware of the problem.  Could you try the latest kernel
> > with the ntfs patches in it (Linus already merged them in the official
> > git tree) and tell me if it now works?  Thanks a lot in advance!
>
> Alistair, any result?
>
> > Note you will need to try the ntfs driver itself and not ntfscp as
> > libntfs does not have these changes yet hence ntfscp will not work just
> > the same (it does not use the kernel driver at all, it only uses
> > libntfs).
>
> The latest ntfsprogs CVS has also these changes and every tool should work
> fine with Vista (ntfscp, ntfsresize, ntfsundelete, ntfsclone, etc).

I have limited access to the beta, as it expires every 30 days and forces me 
to reinstall it. I promise to get back to all of you after 2.6.14 is released 
with the LogFile changes.

To clarify, I did not leave the Vista NTFS volume in an inconsistent state. I 
even forced a chkdsk, rebooted, let it run through, then attempted again to 
mount it with the NTFS code in 2.6.13. This categorically fails.

-- 
Cheers,
Alistair.

'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.)
  2005-09-25 22:35       ` Alistair John Strachan
@ 2005-09-25 23:39         ` Szakacsits Szabolcs
  2005-10-13 15:13         ` Alistair John Strachan
  1 sibling, 0 replies; 53+ messages in thread
From: Szakacsits Szabolcs @ 2005-09-25 23:39 UTC (permalink / raw)
  To: Alistair John Strachan
  Cc: Anton Altaparmakov, Linus Torvalds, linux-kernel, linux-ntfs-dev


On Sun, 25 Sep 2005, Alistair John Strachan wrote:

> I have limited access to the beta, as it expires every 30 days and forces 
> me to reinstall it. I promise to get back to all of you after 2.6.14 is 
> released with the LogFile changes.

Thanks. Also, if you don't want to patch or compile yourself now then you 
could just download and unpack this latest CVS ntfsclone binary (used by us 
to collect NTFS metadata images for investigation):

     http://linux-ntfs.sf.net/snapshots/ntfsclone-static-1.11.3-WIP2.tgz

and run e.g.

     ntfsclone --metadata --output vista-ntfs.img <partition>

If it gives an error then rerun with the --debug option and the end of the 
output will tell what's the reason for the failure.

> To clarify, I did not leave the Vista NTFS volume in an inconsistent 
> state. I even forced a chkdsk, rebooted, let it run through, then 
> attempted again to mount it with the NTFS code in 2.6.13. This 
> categorically fails.

Currently this is the expected behavior if you "interrupt" the chkdsk 
procedure. If you schedule chkdsk then you must boot Windows twice, not 
only once. Otherwise you get the below error message

   NTFS error: ntfs_check_logfile(): Did not find any restart pages in
   $LogFile and it was not empty.

which means that the log was used by chkdsk which will be handled by the 
next Windows boot. At present the Linux NTFS code can't cope with this 
scenario so you must boot Windows again and then Linux. If you did so, then 
well, the above command could tell the reason.

BTW, this is not Vista only feature.

 	Szaka

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.)
  2005-09-25 22:35       ` Alistair John Strachan
  2005-09-25 23:39         ` Szakacsits Szabolcs
@ 2005-10-13 15:13         ` Alistair John Strachan
  2005-10-13 15:18           ` Anton Altaparmakov
  1 sibling, 1 reply; 53+ messages in thread
From: Alistair John Strachan @ 2005-10-13 15:13 UTC (permalink / raw)
  To: Szakacsits Szabolcs
  Cc: Anton Altaparmakov, Linus Torvalds, linux-kernel, linux-ntfs-dev

On Sunday 25 September 2005 23:35, Alistair John Strachan wrote:
[snip]
> >
> > Alistair, any result?
> >
> > > Note you will need to try the ntfs driver itself and not ntfscp as
> > > libntfs does not have these changes yet hence ntfscp will not work just
> > > the same (it does not use the kernel driver at all, it only uses
> > > libntfs).
> >
> > The latest ntfsprogs CVS has also these changes and every tool should
> > work fine with Vista (ntfscp, ntfsresize, ntfsundelete, ntfsclone, etc).
>
> I have limited access to the beta, as it expires every 30 days and forces
> me to reinstall it. I promise to get back to all of you after 2.6.14 is
> released with the LogFile changes.
>
> To clarify, I did not leave the Vista NTFS volume in an inconsistent state.
> I even forced a chkdsk, rebooted, let it run through, then attempted again
> to mount it with the NTFS code in 2.6.13. This categorically fails.

I was free today, so I built a 2.6.14-rc4 kernel on the machine with the 
Longhorn NTFS volume. It now mounts without warnings in dmesg, and I've 
verified that ntfscp works properly.

Thanks!

-- 
Cheers,
Alistair.

'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.)
  2005-10-13 15:13         ` Alistair John Strachan
@ 2005-10-13 15:18           ` Anton Altaparmakov
  0 siblings, 0 replies; 53+ messages in thread
From: Anton Altaparmakov @ 2005-10-13 15:18 UTC (permalink / raw)
  To: Alistair John Strachan
  Cc: Szakacsits Szabolcs, Linus Torvalds, linux-kernel, linux-ntfs-dev

On Thu, 2005-10-13 at 16:13 +0100, Alistair John Strachan wrote:
> On Sunday 25 September 2005 23:35, Alistair John Strachan wrote:
> [snip]
> > >
> > > Alistair, any result?
> > >
> > > > Note you will need to try the ntfs driver itself and not ntfscp as
> > > > libntfs does not have these changes yet hence ntfscp will not work just
> > > > the same (it does not use the kernel driver at all, it only uses
> > > > libntfs).
> > >
> > > The latest ntfsprogs CVS has also these changes and every tool should
> > > work fine with Vista (ntfscp, ntfsresize, ntfsundelete, ntfsclone, etc).
> >
> > I have limited access to the beta, as it expires every 30 days and forces
> > me to reinstall it. I promise to get back to all of you after 2.6.14 is
> > released with the LogFile changes.
> >
> > To clarify, I did not leave the Vista NTFS volume in an inconsistent state.
> > I even forced a chkdsk, rebooted, let it run through, then attempted again
> > to mount it with the NTFS code in 2.6.13. This categorically fails.
> 
> I was free today, so I built a 2.6.14-rc4 kernel on the machine with the 
> Longhorn NTFS volume. It now mounts without warnings in dmesg, and I've 
> verified that ntfscp works properly.

Great!  Thanks for letting us know!

Best regards,

        Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2005-10-13 15:18 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-09  9:18 [2.6-GIT] NTFS: Release 2.1.24 Anton Altaparmakov
2005-09-09  9:19 ` [PATCH 1/25] NTFS: Support more clean journal ($LogFile) states Anton Altaparmakov
2005-09-09  9:19 ` [PATCH 2/25] NTFS: Allow highmem kmalloc() in ntfs_malloc_nofs() and add _nofail() version Anton Altaparmakov
2005-09-09 10:36   ` Pekka Enberg
2005-09-09 11:02     ` Anton Altaparmakov
2005-09-09 11:15       ` Pekka J Enberg
2005-09-09 11:25         ` Anton Altaparmakov
2005-09-09 11:38           ` Pekka J Enberg
2005-09-09 11:48             ` Anton Altaparmakov
2005-09-09 11:51               ` Anton Altaparmakov
2005-09-09 12:02                 ` Pekka J Enberg
2005-09-09 12:08                   ` Anton Altaparmakov
2005-09-09 19:15                     ` Horst von Brand
2005-09-09 14:51   ` Roland Dreier
2005-09-09 14:53     ` Christoph Hellwig
2005-09-09 14:58       ` Anton Altaparmakov
2005-09-09  9:21 ` [PATCH 3/25] NTFS: Use ntfs_malloc_nofs_nofail() in ntfs_runlists_merge() Anton Altaparmakov
2005-09-09  9:22 ` [PATCH 4/25] NTFS: Fix two nasty runlist merging bugs that had gone unnoticed so far Anton Altaparmakov
2005-09-09  9:22 ` [PATCH 5/25] NTFS: Remove two bogus BUG_ON()s from fs/ntfs/mft.c Anton Altaparmakov
2005-09-09  9:22 ` [PATCH 6/25] NTFS: Fix handling of valid but empty mapping pairs array Anton Altaparmakov
2005-09-09  9:23 ` [PATCH 7/25] NTFS: Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING Anton Altaparmakov
2005-09-09  9:23 ` [PATCH 8/25] NTFS: Change ntfs_rl_truncate_nolock() to throw away the runlist if the new Anton Altaparmakov
2005-09-09  9:24 ` [PATCH 9/25] NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist Anton Altaparmakov
2005-09-09  9:24 ` [PATCH 10/25] NTFS: Fix a bug in fs/ntfs/index.c::ntfs_index_lookup() Anton Altaparmakov
2005-09-09  9:25 ` [PATCH 11/25] NTFS: Remove bogus setting of PageError in ntfs_read_compressed_block() Anton Altaparmakov
2005-09-09  9:26 ` [PATCH 12/25] NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize() Anton Altaparmakov
2005-09-09  9:26 ` [PATCH 13/25] NTFS: Fix several bugs in fs/ntfs/attrib.c Anton Altaparmakov
2005-09-09  9:27 ` [PATCH 14/25] NTFS: Fix handling of sparse attributes in ntfs_attr_make_non_resident() Anton Altaparmakov
2005-09-09  9:27 ` [PATCH 15/25] NTFS: Fix cluster (de)allocators to work when the runlist is NULL and more Anton Altaparmakov
2005-09-09  9:28 ` [PATCH 16/25] NTFS: Truncate {a,c,m}time to the ntfs supported time granularity when Anton Altaparmakov
2005-09-09  9:28 ` [PATCH 17/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
2005-09-09  9:28 ` [PATCH 18/25] NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero Anton Altaparmakov
2005-09-09  9:29 ` [PATCH 19/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
2005-09-09  9:29 ` [PATCH 20/25] NTFS: Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page Anton Altaparmakov
2005-09-09  9:30 ` [PATCH 21/25] NTFS: Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case Anton Altaparmakov
2005-09-09  9:30 ` [PATCH 22/25] NTFS: Fixup handling of sparse, compressed, and encrypted attributes in Anton Altaparmakov
2005-09-09  9:30 ` [PATCH 23/25] NTFS: Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c Anton Altaparmakov
2005-09-09  9:31 ` [PATCH 24/25] NTFS: Improve scalability by changing the driver global spin lock in Anton Altaparmakov
2005-09-09  9:32 ` [PATCH 25/25] NTFS: 2.1.24 release and some minor final fixes Anton Altaparmakov
2005-09-10 10:05 ` [2.6-GIT] NTFS: Release 2.1.24 Giuseppe Bilotta
2005-09-10 13:28   ` Anton Altaparmakov
2005-09-10 13:38     ` Anton Altaparmakov
2005-09-10 14:53     ` Bernd Eckenfels
2005-09-11 11:30     ` Giuseppe Bilotta
2005-09-12  2:13     ` Horst von Brand
2005-09-12  9:08       ` Anton Altaparmakov
2005-09-10 13:15 ` Alistair John Strachan
2005-09-10 13:23   ` Anton Altaparmakov
2005-09-25 19:12     ` Linux NTFS Vista compatibility (was: Re: [2.6-GIT] NTFS: Release 2.1.24.) Szakacsits Szabolcs
2005-09-25 22:35       ` Alistair John Strachan
2005-09-25 23:39         ` Szakacsits Szabolcs
2005-10-13 15:13         ` Alistair John Strachan
2005-10-13 15:18           ` Anton Altaparmakov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.