[Haiku-commits] r30944 - in haiku/trunk/src/add-ons/kernel/file_systems/ntfs: . libntfs settings

threedeyes at mail.berlios.de threedeyes at mail.berlios.de
Tue Jun 2 14:23:46 CEST 2009


Author: threedeyes
Date: 2009-06-02 14:21:10 +0200 (Tue, 02 Jun 2009)
New Revision: 30944
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=30944&view=rev

Removed:
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fsproto.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/version.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/version.h
Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/Jamfile
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/attributes.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fs_func.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/Jamfile
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrib.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrib.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrlist.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/bitmap.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/bitmap.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/bootsect.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/compat.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/compat.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/compress.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/debug.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/device.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/dir.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/dir.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/endians.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/index.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/index.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/inode.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/inode.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/layout.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/lcnalloc.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/logfile.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/logging.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/logging.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/mft.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/mft.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/misc.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/misc.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/mst.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/runlist.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/security.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/security.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/unistr.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/unistr.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/unix_io.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/volume.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/volume.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/win32_io.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/lock.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/ntfs.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/settings/ntfs
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/utils.c
   haiku/trunk/src/add-ons/kernel/file_systems/ntfs/volume_util.c
Log:
Update NTFS-3g Library to stable 2009.4.4 version. Clean up code. Now write support enabled by default.

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ntfs/Jamfile	2009-06-02 09:34:16 UTC (rev 30943)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ntfs/Jamfile	2009-06-02 12:21:10 UTC (rev 30944)
@@ -2,8 +2,6 @@
 
 SubDirHdrs [ FDirName $(SUBDIR) libntfs ] ;
 
-SetSubDirSupportedPlatformsBeOSCompatible ;
-
 SubDirCcFlags -DHAVE_CONFIG_H=1 ;
 SubDirC++Flags -DHAVE_CONFIG_H=1 ;
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/attributes.c
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ntfs/attributes.c	2009-06-02 09:34:16 UTC (rev 30943)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ntfs/attributes.c	2009-06-02 12:21:10 UTC (rev 30944)
@@ -54,18 +54,11 @@
 }
 
 
-#ifdef __HAIKU__
 status_t 
 fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
-#else
-int 
-fs_open_attrib_dir(void *_ns, void *_node, void **_cookie)
-{
-	nspace *ns = (nspace *)_ns;
-#endif
-	
+		
 	int	result = B_NO_ERROR;
 
 	ERRPRINT("fs_open_attrdir - ENTER\n");
@@ -88,17 +81,10 @@
 	return result;
 }
 
-#ifdef __HAIKU__
 status_t 
 fs_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
-#else
-int 
-fs_close_attrib_dir(void *_ns, void *_node, void *_cookie)
-{
-	nspace *ns = (nspace *)_ns;
-#endif
 	
 	ERRPRINT("fs_close_attrdir - ENTER\n");
 
@@ -113,17 +99,10 @@
 	return B_NO_ERROR;
 }
 
-#ifdef __HAIKU__
 status_t 
 fs_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
-#else
-int
-fs_free_attrib_dir_cookie(void *_ns, void *_node, void *_cookie)
-{
-	nspace *ns = (nspace *)_ns;
-#endif
 
 	int	result = B_NO_ERROR;
 
@@ -149,17 +128,11 @@
 	return result;
 }
 
-#ifdef __HAIKU__
 status_t 
 fs_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
-#else
-int
-fs_rewind_attrib_dir(void *_ns, void *_node, void *_cookie)
-{
-	nspace *ns = (nspace *)_ns;
-#endif
+
 	int	result = B_NO_ERROR;
 
 	LOCK_VOL(ns);
@@ -184,19 +157,12 @@
 }
 
 
-#ifdef __HAIKU__
 status_t 
 fs_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct dirent *entry, size_t bufsize, uint32 *num)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
 	vnode *node = (vnode *)_node->private_node;
-#else
-int
-fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, long *num, struct dirent *entry, size_t bufsize)
-{
-	nspace *ns = (nspace *)_ns;
-	vnode *node = (vnode *)_node;
-#endif
+
 	int32 *cookie = (int32 *)_cookie;
 
 	LOCK_VOL(ns);
@@ -223,28 +189,6 @@
 	return B_NO_ERROR;
 }
 
-#ifndef __HAIKU__
-int
-fs_read_attrib_stat(void *_ns, void *_node, const char *name, struct attr_info *buf)
-{
-	nspace *ns = (nspace *)_ns;
-	vnode *node = (vnode *)_node;
-
-	if (strcmp(name, "BEOS:TYPE"))
-		return ENOENT;
-
-	if (node->mime == NULL) {
-		return ENOENT;
-	}
-	
-	buf->type = MIME_STRING_TYPE;
-	buf->size = strlen(node->mime) + 1;
-
-	return 0;
-}
-#endif
-
-#ifdef __HAIKU__
 status_t
 fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, int openMode, void **_cookie)
 {
@@ -276,25 +220,22 @@
 		
 	return result;
 }
-#endif
 
-#ifdef __HAIKU__
+
 status_t
 fs_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie)
 {
 	return B_NO_ERROR;
 }
-#endif
 
-#ifdef __HAIKU__
+
 status_t
 fs_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie)
 {
 	return B_NO_ERROR;
 }
-#endif
 
-#ifdef __HAIKU__
+
 status_t 
 fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,struct stat *stat)
 {
@@ -327,33 +268,24 @@
 	
 	return B_NO_ERROR;
 }
-#endif
 
-#ifdef __HAIKU__
+
 status_t 
 fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,void *buffer, size_t *_length)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
 	vnode *node = (vnode *)_node->private_node;
-#else
-int
-fs_read_attrib(void *_ns, void *_node, const char *name, int type, void *buffer, size_t *_length, off_t pos)
-{
-	nspace *ns = (nspace *)_ns;
-	vnode *node = (vnode *)_node;
-#endif
+
 	int	result = B_NO_ERROR;
 
 	LOCK_VOL(ns);
 
 	ERRPRINT("fs_read_attr - ENTER\n");
 
-#ifdef __HAIKU_
 	if (_cookie != &kBeOSTypeCookie) {
 		result = ENOENT;
 		goto	exit;
 	}
-#endif
 			
 	if (node->mime == NULL) {
 		result = ENOENT;
@@ -379,17 +311,11 @@
 }
 
 
-#ifdef __HAIKU__
 status_t
 fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,off_t pos, const void *buffer, size_t *_length)
 {
 	nspace *ns = (nspace *)_vol->private_volume;
-#else
-int
-fs_write_attrib(void *_ns, void *_node, const char *name, int type, const void *buffer, size_t *_length, off_t pos)
-{
-	nspace *ns = (nspace *)_ns;
-#endif
+
 	int	result = B_NO_ERROR;
 	
 	LOCK_VOL(ns);
@@ -397,11 +323,10 @@
 	ERRPRINT("fs_write_attr - ENTER\n");
 
 	*_length = 0;
-#ifdef __HAIKU_
+
 	if (_cookie != &kBeOSTypeCookie) {
 		result = ENOSYS;
 	}
-#endif	
 	
 	ERRPRINT("fs_write_attrib - EXIT, result is %s\n", strerror(result));
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fs_func.c
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fs_func.c	2009-06-02 09:34:16 UTC (rev 30943)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fs_func.c	2009-06-02 12:21:10 UTC (rev 30944)
@@ -123,7 +123,7 @@
 	if(!ioctl(fd,B_GET_PATH_FOR_DEVICE,devpath))
 		return -1;
 	//try mount
-	ntVolume = utils_mount_volume(devpath,MS_RDONLY|MS_NOATIME,true);
+	ntVolume = utils_mount_volume(devpath,MS_RDONLY,true);
 	if(!ntVolume)
 		return -1;
 
@@ -208,8 +208,8 @@
 		mnt_flags |= MS_RDONLY;
 		ns->flags |= B_MOUNT_READ_ONLY;
 	}
-	if (ns->noatime)
-		mnt_flags |= MS_NOATIME;
+//	if (ns->noatime)
+//		mnt_flags |= MS_NOATIME;
 
 	ns->ntvol=utils_mount_volume(device,mnt_flags,true);
 	if(ns->ntvol!=NULL)
@@ -367,7 +367,7 @@
 			result = ENOENT;
 	} else {
 			unicode = ntfs_calloc(MAX_PATH);
-			len = ntfs_mbstoucs(file, &unicode, MAX_PATH);
+			len = ntfs_mbstoucs(file, &unicode);
 			if (len < 0) {
 				result = EILSEQ;
 				goto exit;
@@ -882,7 +882,7 @@
 		goto exit;
 	}
 
-	uname_len = ntfs_mbstoucs(name, &uname, 0);
+	uname_len = ntfs_mbstoucs(name, &uname);
 	if (uname_len < 0) {
 		result = EINVAL;
 		goto exit;
@@ -1285,13 +1285,13 @@
 			goto exit;
 	}
 
-	uname_len = ntfs_mbstoucs(name, &uname, 0);
+	uname_len = ntfs_mbstoucs(name, &uname);
 	if (uname_len < 0) {
 		result = EINVAL;
 		goto exit;
 	}
 
-	utarget_len = ntfs_mbstoucs(target, &utarget, 0);
+	utarget_len = ntfs_mbstoucs(target, &utarget);
 	if (utarget_len < 0) {
 		result = EINVAL;
 		goto exit;
@@ -1380,7 +1380,7 @@
 		goto exit;
 	}
 
-	uname_len = ntfs_mbstoucs(name, &uname, 0);
+	uname_len = ntfs_mbstoucs(name, &uname);
 	if (uname_len < 0) {
 		result = EINVAL;
 		goto exit;
@@ -1475,13 +1475,13 @@
 		goto	exit;
 
 	//convert names from utf8 to unicode string
-	unewname_len = ntfs_mbstoucs(newname, &unewname, 0);
+	unewname_len = ntfs_mbstoucs(newname, &unewname);
 	if (unewname_len < 0) {
 		result = EINVAL;
 		goto exit;
 	}
 
-	uoldname_len = ntfs_mbstoucs(oldname, &uoldname, 0);
+	uoldname_len = ntfs_mbstoucs(oldname, &uoldname);
 	if (uoldname_len < 0) {
 		result = EINVAL;
 		goto exit;
@@ -1544,13 +1544,14 @@
 				goto exit;
 			}
 
-			ntfs_delete(oi, odi, uoldname, uoldname_len);
-
 			onode->parent_vnid = MREF( ndi->mft_no );
-
+			
 			notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( ndi->mft_no ), newname, onode->vnid );
 			notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED);
 
+			ntfs_delete(oi, odi, uoldname, uoldname_len);
+			oi = odi = NULL; /* ntfs_delete() always closes ni and dir_ni */
+
 			put_vnode(_vol, onode->vnid );
 
 	} else { //renaming
@@ -1590,10 +1591,12 @@
 				goto exit;
 			}
 
-			ntfs_delete(oi, odi, uoldname, uoldname_len);
 			notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( odi->mft_no ), newname, onode->vnid );
 			notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED);
 			put_vnode(_vol, onode->vnid );
+
+			ntfs_delete(oi, odi, uoldname, uoldname_len);
+			oi = odi = NULL; /* ntfs_delete() always closes ni and dir_ni */
 	}
 
 
@@ -1626,7 +1629,7 @@
 	int 		uname_len;
 	status_t	result = B_NO_ERROR;
 
-	uname_len = ntfs_mbstoucs(name, &uname, 0);
+	uname_len = ntfs_mbstoucs(name, &uname);
 	if (uname_len < 0) {
 		result = EINVAL;
 		goto exit1;
@@ -1675,9 +1678,9 @@
 
 	if(ntfs_delete(ni, bi, uname, uname_len))
 	 	result = errno;
-	else
-		ni = NULL;
 
+	ni = bi = NULL;
+
 	node->parent_vnid = dir->vnid;
 
 	notify_entry_removed(vol->id, dir->vnid, name, vnid);
@@ -1760,7 +1763,7 @@
 
 	ERRPRINT("fs_unlink  - ENTER:  name %s\n", name==NULL?"NULL":name);
 
-	if( ns == NULL || dir == NULL || name ==NULL) {
+	if( ns == NULL || dir == NULL || name == NULL) {
 		result = EINVAL;
 		goto exit;
 	}

Deleted: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/fsproto.h

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/Jamfile	2009-06-02 09:34:16 UTC (rev 30943)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/Jamfile	2009-06-02 12:21:10 UTC (rev 30944)
@@ -1,7 +1,5 @@
 SubDir HAIKU_TOP src add-ons kernel file_systems ntfs libntfs ;
 
-SetSubDirSupportedPlatformsBeOSCompatible ;
-
 SubDirCcFlags -Wall -Wno-multichar -DHAVE_CONFIG_H=1 ;
 
 StaticLibrary libntfs.a :
@@ -27,7 +25,6 @@
 	runlist.c
 	security.c
 	unistr.c
-	version.c
 	volume.c
 ;
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrib.c
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrib.c	2009-06-02 09:34:16 UTC (rev 30943)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ntfs/libntfs/attrib.c	2009-06-02 12:21:10 UTC (rev 30944)
@@ -3,8 +3,9 @@
  *
  * Copyright (c) 2000-2005 Anton Altaparmakov
  * Copyright (c) 2002-2005 Richard Russon
- * Copyright (c) 2002-2006 Szabolcs Szakacsits
- * Copyright (c) 2004-2006 Yura Pakhuchiy
+ * Copyright (c) 2002-2008 Szabolcs Szakacsits
+ * Copyright (c) 2004-2007 Yura Pakhuchiy
+ * Copyright (c) 2007-2008 Jean-Pierre Andre
  *
  * 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
@@ -60,6 +61,37 @@
 
 ntfschar AT_UNNAMED[] = { const_cpu_to_le16('\0') };
 
+static int NAttrFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
+{
+	if (na->type == AT_DATA && na->name == AT_UNNAMED)
+		return (na->ni->flags & flag);
+	return 0;
+}
+
+static void NAttrSetFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
+{
+	if (na->type == AT_DATA && na->name == AT_UNNAMED)
+		na->ni->flags |= flag;
+	else
+		ntfs_log_trace("Denied setting flag %d for not unnamed data "
+			       "attribute\n", flag);
+}
+
+static void NAttrClearFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
+{
+	if (na->type == AT_DATA && na->name == AT_UNNAMED)
+		na->ni->flags &= ~flag;
+}
+
+#define GenNAttrIno(func_name, flag)					\
+int NAttr##func_name(ntfs_attr *na) { return NAttrFlag   (na, flag); } 	\
+void NAttrSet##func_name(ntfs_attr *na)	 { NAttrSetFlag  (na, flag); }	\
+void NAttrClear##func_name(ntfs_attr *na){ NAttrClearFlag(na, flag); }
+
+GenNAttrIno(Compressed, FILE_ATTR_COMPRESSED)
+GenNAttrIno(Encrypted, 	FILE_ATTR_ENCRYPTED)
+GenNAttrIno(Sparse, 	FILE_ATTR_SPARSE_FILE)
+
 /**
  * ntfs_get_attribute_value_length - Find the length of an attribute
  * @a:
@@ -343,63 +375,82 @@
 		ntfschar *name, u32 name_len)
 {
 	ntfs_attr_search_ctx *ctx;
-	ntfs_attr *na;
+	ntfs_attr *na = NULL;
+	ntfschar *newname = NULL;
 	ATTR_RECORD *a;
-	int err;
 	BOOL cs;
 
-	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
-		(unsigned long long)ni->mft_no, type);
+	ntfs_log_enter("Entering for inode %lld, attr 0x%x.\n",
+		       (unsigned long long)ni->mft_no, type);
+	
 	if (!ni || !ni->vol || !ni->mrec) {
 		errno = EINVAL;
-		return NULL;
+		goto out;
 	}
-	na = calloc(sizeof(ntfs_attr), 1);
+	na = ntfs_calloc(sizeof(ntfs_attr));
 	if (!na)
-		return NULL;
+		goto out;
 	if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
 		name = ntfs_ucsndup(name, name_len);
-		if (!name) {
-			free(na);
-			return NULL;
-		}
+		if (!name)
+			goto err_out;
+		newname = name;
 	}
 
 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
-	if (!ctx) {
-		err = errno;
+	if (!ctx)
 		goto err_out;
-	}
-	if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx)) {
-		err = errno;
+
+	if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx))
 		goto put_err_out;
-	}
 
 	a = ctx->attr;
-	/*
-	 * Wipe the flags in case they are not zero for an attribute list
-	 * attribute.  Windows does not complain about invalid flags and chkdsk
-	 * does not detect or fix them so we need to cope with it, too.
-	 */
-	if (type == AT_ATTRIBUTE_LIST)
-		a->flags = 0;
-	cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
+	
 	if (!name) {
 		if (a->name_length) {
 			name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
 					a->name_offset)), a->name_length);
-			if (!name) {
-				err = errno;
+			if (!name)
 				goto put_err_out;
-			}
+			newname = name;
 			name_len = a->name_length;
 		} else {
 			name = AT_UNNAMED;
 			name_len = 0;
 		}
 	}
+	
 	__ntfs_attr_init(na, ni, type, name, name_len);
+	
+	/*
+	 * Wipe the flags in case they are not zero for an attribute list
+	 * attribute.  Windows does not complain about invalid flags and chkdsk
+	 * does not detect or fix them so we need to cope with it, too.
+	 */
+	if (type == AT_ATTRIBUTE_LIST)
+		a->flags = 0;
+	
+	cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
+	
+	if (na->type == AT_DATA && na->name == AT_UNNAMED &&
+	    ((!(a->flags & ATTR_IS_COMPRESSED) != !NAttrCompressed(na)) ||
+	     (!(a->flags & ATTR_IS_SPARSE)     != !NAttrSparse(na)) ||
+	     (!(a->flags & ATTR_IS_ENCRYPTED)  != !NAttrEncrypted(na)))) {
+		errno = EIO;
+		ntfs_log_perror("Inode %lld has corrupt attribute flags "
+				"(0x%x <> 0x%x)",(unsigned long long)ni->mft_no,
+				a->flags, na->ni->flags);
+		goto put_err_out;
+	}
+
 	if (a->non_resident) {
+		if ((a->flags & ATTR_IS_COMPRESSED) && !a->compression_unit) {
+			errno = EIO;
+			ntfs_log_perror("Compressed inode %lld attr 0x%x has "
+					"no compression unit",
+					(unsigned long long)ni->mft_no, type);
+			goto put_err_out;
+		}
 		ntfs_attr_init(na, TRUE, a->flags & ATTR_IS_COMPRESSED,
 				a->flags & ATTR_IS_ENCRYPTED,
 				a->flags & ATTR_IS_SPARSE,
@@ -416,13 +467,17 @@
 				cs ? (l + 7) & ~7 : 0, 0);
 	}
 	ntfs_attr_put_search_ctx(ctx);
+out:
+	ntfs_log_leave("\n");	
 	return na;
+
 put_err_out:
 	ntfs_attr_put_search_ctx(ctx);
 err_out:
+	free(newname);
 	free(na);
-	errno = err;
-	return NULL;
+	na = NULL;
+	goto out;
 }
 
 /**
@@ -449,7 +504,7 @@
  * @na:		ntfs attribute for which to map (part of) a runlist
  * @vcn:	map runlist part containing this vcn
  *
- * Map the part of a runlist containing the @vcn of an the ntfs attribute @na.
+ * Map the part of a runlist containing the @vcn of the ntfs attribute @na.
  *
  * Return 0 on success and -1 on error with errno set to the error code.
  */
@@ -492,8 +547,8 @@
  * ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute
  * @na:		ntfs attribute for which to map the runlist
  *
- * Map the whole runlist of an the ntfs attribute @na.  For an attribute made
- * up of only one attribute extent this is the same as calling
+ * Map the whole runlist of the ntfs attribute @na.  For an attribute made up
+ * of only one attribute extent this is the same as calling
  * ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this
  * will map the runlist fragments from each of the extents thus giving access
  * to the entirety of the disk allocation of an attribute.
@@ -506,14 +561,14 @@
 	ntfs_attr_search_ctx *ctx;
 	ntfs_volume *vol = na->ni->vol;
 	ATTR_RECORD *a;
-	int err;
+	int ret = -1;
 
-	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
-			(unsigned long long)na->ni->mft_no, na->type);
+	ntfs_log_enter("Entering for inode %llu, attr 0x%x.\n",
+		       (unsigned long long)na->ni->mft_no, na->type);
 
 	ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 	if (!ctx)
-		return -1;
+		goto out;
 
 	/* Map all attribute extents one by one. */
 	next_vcn = last_vcn = highest_vcn = 0;
@@ -584,17 +639,13 @@
 				(long long)highest_vcn, (long long)last_vcn);
 		goto err_out;
 	}
-	err = errno;
+	if (errno == ENOENT)
+		ret = 0;
+err_out:	
 	ntfs_attr_put_search_ctx(ctx);
-	if (err == ENOENT)
-		return 0;
-out_now:
-	errno = err;
-	return -1;
-err_out:
-	err = errno;
-	ntfs_attr_put_search_ctx(ctx);
-	goto out_now;
+out:
+	ntfs_log_leave("\n");
+	return ret;
 }
 
 /**
@@ -727,41 +778,16 @@
 }
 
 /**
- * ntfs_attr_pread - read from an attribute specified by an ntfs_attr structure
- * @na:		ntfs attribute to read from
- * @pos:	byte position in the attribute to begin reading from
- * @count:	number of bytes to read
- * @b:		output data buffer
- *
- * This function will read @count bytes starting at offset @pos from the ntfs
- * attribute @na into the data buffer @b.
- *
- * On success, return the number of successfully read bytes. If this number is
- * lower than @count this means that the read reached end of file or that an
- * error was encountered during the read so that the read is partial. 0 means
- * end of file or nothing was read (also return 0 when @count is 0).
- *
- * On error and nothing has been read, return -1 with errno set appropriately
- * to the return code of ntfs_pread(), or to EINVAL in case of invalid
- * arguments.
- */
-s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
+ * ntfs_attr_pread_i - see description at ntfs_attr_pread()
+ */ 
+static s64 ntfs_attr_pread_i(ntfs_attr *na, const s64 pos, s64 count, void *b)
 {
 	s64 br, to_read, ofs, total, total2;
 	ntfs_volume *vol;
 	runlist_element *rl;
 
-	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, count "
-			"0x%llx.\n", (unsigned long long)na->ni->mft_no,
-			na->type, (long long)pos, (long long)count);
-	if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
-		errno = EINVAL;
-		return -1;
-	}
-	/*
-	 * If this is a compressed attribute it needs special treatment, but
-	 * only if it is non-resident.
-	 */
+	/* Sanity checking arguments is done in ntfs_attr_pread(). */
+	
 	if (NAttrCompressed(na) && NAttrNonResident(na))
 		return ntfs_compressed_attr_pread(na, pos, count, b);
 	/*
@@ -773,10 +799,7 @@
 		return -1;
 	}
 	vol = na->ni->vol;
-	/* Update access time if needed. */
-	if (na->type == AT_DATA || na->type == AT_INDEX_ROOT ||
-			na->type == AT_INDEX_ALLOCATION)
-		ntfs_inode_update_atime(na->ni);
+	
 	if (!count)
 		return 0;
 	/* Truncate reads beyond end of attribute. */
@@ -804,6 +827,7 @@
 				le32_to_cpu(ctx->attr->value_length) >
 				(char*)ctx->mrec + vol->mft_record_size) {
 			errno = EIO;
+			ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
 			goto res_err_out;
 		}
 		memcpy(b, val + pos, count);
@@ -829,8 +853,10 @@
 		 * However, we already truncated the read to the data_size,
 		 * so getting this here is an error.
 		 */
-		if (errno == ENOENT)
+		if (errno == ENOENT) {
 			errno = EIO;
+			ntfs_log_perror("%s: Failed to find VCN #1", __FUNCTION__);
+		}
 		return -1;
 	}
 	/*
@@ -843,18 +869,28 @@
 		if (rl->lcn == LCN_RL_NOT_MAPPED) {
 			rl = ntfs_attr_find_vcn(na, rl->vcn);
 			if (!rl) {
-				if (errno == ENOENT)
+				if (errno == ENOENT) {
 					errno = EIO;
+					ntfs_log_perror("%s: Failed to find VCN #2",
+							__FUNCTION__);
+				}
 				goto rl_err_out;
 			}
 			/* Needed for case when runs merged. */
 			ofs = pos + total - (rl->vcn << vol->cluster_size_bits);
 		}
-		if (!rl->length)
+		if (!rl->length) {
+			errno = EIO;
+			ntfs_log_perror("%s: Zero run length", __FUNCTION__);
 			goto rl_err_out;
+		}
 		if (rl->lcn < (LCN)0) {
-			if (rl->lcn != (LCN)LCN_HOLE)
+			if (rl->lcn != (LCN)LCN_HOLE) {
+				ntfs_log_perror("%s: Bad run (%lld)", 
+						__FUNCTION__,
+						(long long)rl->lcn);
 				goto rl_err_out;
+			}
 			/* It is a hole, just zero the matching @b range. */
 			to_read = min(count, (rl->length <<
 					vol->cluster_size_bits) - ofs);
@@ -869,8 +905,9 @@
 		to_read = min(count, (rl->length << vol->cluster_size_bits) -
 				ofs);
 retry:
-		ntfs_log_trace("Reading 0x%llx bytes from vcn 0x%llx, lcn 0x%llx, "
-				"ofs 0x%llx.\n", to_read, rl->vcn, rl->lcn, ofs);
+		ntfs_log_trace("Reading %lld bytes from vcn %lld, lcn %lld, ofs"
+				" %lld.\n", (long long)to_read, (long long)rl->vcn,
+			       (long long )rl->lcn, (long long)ofs);
 		br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) +
 				ofs, to_read, b);
 		/* If everything ok, update progress counters and continue. */
@@ -878,8 +915,9 @@
 			total += br;
 			count -= br;
 			b = (u8*)b + br;
+		}
+		if (br == to_read)
 			continue;
-		}
 		/* If the syscall was interrupted, try again. */
 		if (br == (s64)-1 && errno == EINTR)
 			goto retry;
@@ -887,6 +925,7 @@
 			return total;
 		if (!br)
 			errno = EIO;
+		ntfs_log_perror("%s: ntfs_pread failed", __FUNCTION__);
 		return -1;
 	}
 	/* Finally, return the number of bytes read. */
@@ -898,6 +937,47 @@
 	return -1;
 }
 
+/**
+ * ntfs_attr_pread - read from an attribute specified by an ntfs_attr structure
+ * @na:		ntfs attribute to read from
+ * @pos:	byte position in the attribute to begin reading from
+ * @count:	number of bytes to read
+ * @b:		output data buffer
+ *
+ * This function will read @count bytes starting at offset @pos from the ntfs
+ * attribute @na into the data buffer @b.
+ *
+ * On success, return the number of successfully read bytes. If this number is
+ * lower than @count this means that the read reached end of file or that an
+ * error was encountered during the read so that the read is partial. 0 means
+ * end of file or nothing was read (also return 0 when @count is 0).
+ *
+ * On error and nothing has been read, return -1 with errno set appropriately
+ * to the return code of ntfs_pread(), or to EINVAL in case of invalid
+ * arguments.
+ */
+s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
+{
+	s64 ret;
+	
+	if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
+		errno = EINVAL;
+		ntfs_log_perror("%s: na=%p  b=%p  pos=%lld  count=%lld",
+				__FUNCTION__, na, b, (long long)pos,
+				(long long)count);
+		return -1;
+	}
+	
+	ntfs_log_enter("Entering for inode %lld attr 0x%x pos %lld count "
+		       "%lld\n", (unsigned long long)na->ni->mft_no,
+		       na->type, (long long)pos, (long long)count);
+
+	ret = ntfs_attr_pread_i(na, pos, count, b);
+	
+	ntfs_log_leave("\n");
+	return ret;
+}
+
 static int ntfs_attr_fill_zero(ntfs_attr *na, s64 pos, s64 count)
 {
 	char *buf;
@@ -949,7 +1029,8 @@
 	from_vcn = (*rl)->vcn + (*ofs >> vol->cluster_size_bits);
 	
 	ntfs_log_trace("count: %lld, cur_vcn: %lld, from: %lld, to: %lld, ofs: "
-		       "%lld\n", count, cur_vcn, from_vcn, to_write, *ofs);
+		       "%lld\n", (long long)count, (long long)cur_vcn, 
+		       (long long)from_vcn, (long long)to_write, (long long)*ofs);
 	 
 	/* Map whole runlist to be able update mapping pairs later. */
 	if (ntfs_attr_map_whole_runlist(na))
@@ -1081,17 +1162,20 @@
 	ntfs_volume *vol;
 	ntfs_attr_search_ctx *ctx = NULL;
 	runlist_element *rl;
+	s64 hole_end;
 	int eo;
 	struct {
 		unsigned int undo_initialized_size	: 1;
 		unsigned int undo_data_size		: 1;
 	} need_to = { 0, 0 };
 
-	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, count "
-			"0x%llx.\n", na->ni->mft_no, na->type, (long long)pos,
-			(long long)count);
+	ntfs_log_enter("Entering for inode %lld, attr 0x%x, pos 0x%llx, count "
+		       "0x%llx.\n", (long long)na->ni->mft_no, na->type,
+		       (long long)pos, (long long)count);
+	
 	if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
 		errno = EINVAL;
+		ntfs_log_perror("%s", __FUNCTION__);
 		goto errno_set;
 	}
 	vol = na->ni->vol;
@@ -1111,10 +1195,7 @@
 		errno = EOPNOTSUPP;
 		goto errno_set;
 	}
-	/* Update access and change times if needed. */
-	if (na->type == AT_DATA || na->type == AT_INDEX_ROOT ||
-			na->type == AT_INDEX_ALLOCATION)
-		ntfs_inode_update_time(na->ni);
+	
 	if (!count)
 		goto out;
 	/* If the write reaches beyond the end, extend the attribute. */
@@ -1135,13 +1216,16 @@
 		if (!ctx)
 			goto err_out;
 		if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
-				0, NULL, 0, ctx))
+				0, NULL, 0, ctx)) {
+			ntfs_log_perror("%s: lookup failed", __FUNCTION__);
 			goto err_out;
+		}
 		val = (char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset);
 		if (val < (char*)ctx->attr || val +
 				le32_to_cpu(ctx->attr->value_length) >
 				(char*)ctx->mrec + vol->mft_record_size) {
 			errno = EIO;
+			ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
 			goto err_out;
 		}
 		memcpy(val + pos, b, count);
@@ -1154,6 +1238,7 @@
 			 * it is unlikely to fail writing it, so is ok to just
 			 * return error here... (AIA)
 			 */
+			ntfs_log_perror("%s: failed to write mft record", __FUNCTION__);
 			goto err_out;
 		}
 		ntfs_attr_put_search_ctx(ctx);
@@ -1211,8 +1296,10 @@
 		 * However, we already extended the size of the attribute,
 		 * so getting this here must be an error of some kind.
 		 */
-		if (errno == ENOENT)
+		if (errno == ENOENT) {
 			errno = EIO;
+			ntfs_log_perror("%s: Failed to find VCN #1", __FUNCTION__);
+		}
 		goto err_out;
 	}
 	/*
@@ -1221,12 +1308,15 @@
 	 * length.
 	 */
 	ofs = pos - (rl->vcn << vol->cluster_size_bits);
-	for (; count; rl++, ofs = 0) {
+	for (hole_end = 0; count; rl++, ofs = 0, hole_end = 0) {
 		if (rl->lcn == LCN_RL_NOT_MAPPED) {
 			rl = ntfs_attr_find_vcn(na, rl->vcn);
 			if (!rl) {
-				if (errno == ENOENT)
+				if (errno == ENOENT) {
 					errno = EIO;
+					ntfs_log_perror("%s: Failed to find VCN"
+							" #2", __FUNCTION__);
+				}
 				goto rl_err_out;
 			}
 			/* Needed for case when runs merged. */
@@ -1234,12 +1324,18 @@
 		}
 		if (!rl->length) {
 			errno = EIO;
+			ntfs_log_perror("%s: Zero run length", __FUNCTION__);
 			goto rl_err_out;
 		}
 		if (rl->lcn < (LCN)0) {
+			
+			hole_end = rl->vcn + rl->length;
 
 			if (rl->lcn != (LCN)LCN_HOLE) {
 				errno = EIO;
+				ntfs_log_perror("%s: Unexpected LCN (%lld)", 
+						__FUNCTION__,
+						(long long)rl->lcn);
 				goto rl_err_out;
 			}
 			
@@ -1250,20 +1346,53 @@
 		to_write = min(count, (rl->length << vol->cluster_size_bits) - ofs);
 retry:
 		ntfs_log_trace("Writing %lld bytes to vcn %lld, lcn %lld, ofs "
-			       "%lld.\n", to_write, rl->vcn, rl->lcn, ofs);
-		if (!NVolReadOnly(vol))
-			written = ntfs_pwrite(vol->dev, (rl->lcn <<
-					vol->cluster_size_bits) + ofs,
-					to_write, b);
-		else
+			       "%lld.\n", (long long)to_write, (long long)rl->vcn,
+			       (long long)rl->lcn, (long long)ofs);
+		if (!NVolReadOnly(vol)) {
+			
+			s64 wpos = (rl->lcn << vol->cluster_size_bits) + ofs;
+			s64 wend = (rl->vcn << vol->cluster_size_bits) + ofs + to_write;
+			u32 bsize = vol->cluster_size;
+			/* Byte size needed to zero fill a cluster */
+			s64 rounding = ((wend + bsize - 1) & ~(s64)(bsize - 1)) - wend;
+			/**
+			 * Zero fill to cluster boundary if we're writing at the
+			 * end of the attribute or into an ex-sparse cluster.
+			 * This will cause the kernel not to seek and read disk 
+			 * blocks during write(2) to fill the end of the buffer 
+			 * which increases write speed by 2-10 fold typically.
+			 */
+			if (rounding && ((wend == na->initialized_size) ||
+				(wend < (hole_end << vol->cluster_size_bits)))){
+				
+				char *cb;
+				

[... truncated: 8746 lines follow ...]



More information about the Haiku-commits mailing list