patch-2.4.4 linux/fs/ntfs/attr.c

Next file: linux/fs/ntfs/attr.h
Previous file: linux/fs/ntfs/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/fs/ntfs/attr.c linux/fs/ntfs/attr.c
@@ -1,10 +1,10 @@
-/*
- *  attr.c
+/*  attr.c
  *
  *  Copyright (C) 1996-1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
 #include "ntfstypes.h"
@@ -12,401 +12,389 @@
 #include "attr.h"
 
 #include <linux/errno.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 #include "macros.h"
 #include "support.h"
 #include "util.h"
 #include "super.h"
 #include "inode.h"
 
-/* Look if an attribute already exists in the inode, and if not, create it */
-int 
-ntfs_new_attr(ntfs_inode *ino,int type,void *name,int namelen,int *pos,
-			int *found, int do_search )
+/* Look if an attribute already exists in the inode, and if not, create it. */
+int ntfs_new_attr(ntfs_inode *ino, int type, void *name, int namelen, int *pos,
+		  int *found, int do_search)
 {
-	int do_insert=0;
+	int do_insert = 0;
 	int i;
 
-	for(i=0;i<ino->attr_count;i++)
+	for (i = 0; i < ino->attr_count; i++)
 	{
-		int n=min(namelen,ino->attrs[i].namelen);
-		int s=ntfs_uni_strncmp(ino->attrs[i].name,name,n);
-		if( do_search ) {
-			/*
-			 * We assume that each attribute can be uniquely 
-			 * identified by inode
-			 * number, attribute type and attribute name.
-			 */
-			if(ino->attrs[i].type==type && ino->attrs[i].namelen==namelen && !s){
-				*found=1;
-				*pos=i;
+		int n = min(namelen, ino->attrs[i].namelen);
+		int s = ntfs_uni_strncmp(ino->attrs[i].name, name, n);
+		if (do_search) {
+			/* We assume that each attribute can be uniquely 
+			 * identified by inode number, attribute type and
+			 * attribute name. */
+			if (ino->attrs[i].type == type && 
+			    ino->attrs[i].namelen == namelen && !s) {
+				*found = 1;
+				*pos = i;
 				return 0;
 			}
 		}
-		/* attributes are ordered by type, then by name */
-		if(ino->attrs[i].type>type || (ino->attrs[i].type==type && s==1)){
-			do_insert=1;
+		/* Attributes are ordered by type, then by name. */
+		if (ino->attrs[i].type > type || 
+		    (ino->attrs[i].type == type && s == 1)) {
+			do_insert = 1;
 			break;
 		}
 	}
 
-	/* re-allocate space */
-	if(ino->attr_count % 8 ==0)
+	/* Re-allocate space. */
+	if (ino->attr_count % 8 == 0)
 	{
 		ntfs_attribute* new;
-		new = (ntfs_attribute*)ntfs_malloc((ino->attr_count+8)*
-			     sizeof(ntfs_attribute));
-		if( !new )
-			return ENOMEM;
-		if( ino->attrs ) {
-			ntfs_memcpy( new, ino->attrs, ino->attr_count*sizeof(ntfs_attribute) );
-			ntfs_free( ino->attrs );
+		new = (ntfs_attribute*)ntfs_malloc((ino->attr_count + 8) *
+							sizeof(ntfs_attribute));
+		if (!new)
+			return -ENOMEM;
+		if (ino->attrs) {
+			ntfs_memcpy(new, ino->attrs, ino->attr_count *
+							sizeof(ntfs_attribute));
+			ntfs_free(ino->attrs);
 		}
 		ino->attrs = new;
 	}
-	if(do_insert)
-		ntfs_memmove(ino->attrs+i+1,ino->attrs+i,(ino->attr_count-i)*
-			    sizeof(ntfs_attribute));
-
+	if (do_insert)
+		ntfs_memmove(ino->attrs + i + 1, ino->attrs + i,
+			     (ino->attr_count - i) * sizeof(ntfs_attribute));
 	ino->attr_count++;
-	ino->attrs[i].type=type;
-	ino->attrs[i].namelen=namelen;
-	ino->attrs[i].name=name;
-	*pos=i;
-	*found=0;
+	ino->attrs[i].type = type;
+	ino->attrs[i].namelen = namelen;
+	ino->attrs[i].name = name;
+	*pos = i;
+	*found = 0;
 	return 0;
 }
 
-int 
-ntfs_make_attr_resident(ntfs_inode *ino,ntfs_attribute *attr)
+int ntfs_make_attr_resident(ntfs_inode *ino, ntfs_attribute *attr)
 {
-	int size=attr->size;
-	if(size>0){
+	int size = attr->size;
+	if (size > 0) {
 		/* FIXME: read data, free clusters */
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
-	attr->resident=1;
+	attr->resident = 1;
 	return 0;
 }
 
-/* Store in the inode readable information about a run */
-void
-ntfs_insert_run(ntfs_attribute *attr,int cnum,ntfs_cluster_t cluster,int len)
+/* Store in the inode readable information about a run. */
+void ntfs_insert_run(ntfs_attribute *attr, int cnum, ntfs_cluster_t cluster,
+		     int len)
 {
-	/* (re-)allocate space if necessary */
-	if(attr->d.r.len % 8 == 0) {
+	/* (re-)allocate space if necessary. */
+	if (attr->d.r.len % 8 == 0) {
 		ntfs_runlist* new;
-		new = ntfs_malloc((attr->d.r.len+8)*sizeof(ntfs_runlist));
-		if( !new )
+		new = ntfs_malloc((attr->d.r.len + 8) * sizeof(ntfs_runlist));
+		if (!new)
 			return;
-		if( attr->d.r.runlist ) {
+		if (attr->d.r.runlist) {
 			ntfs_memcpy(new, attr->d.r.runlist, attr->d.r.len
-				    *sizeof(ntfs_runlist));
-			ntfs_free( attr->d.r.runlist );
+							* sizeof(ntfs_runlist));
+			ntfs_free(attr->d.r.runlist);
 		}
 		attr->d.r.runlist = new;
 	}
-	if(attr->d.r.len>cnum)
-		ntfs_memmove(attr->d.r.runlist+cnum+1,attr->d.r.runlist+cnum,
-			    (attr->d.r.len-cnum)*sizeof(ntfs_runlist));
-	attr->d.r.runlist[cnum].cluster=cluster;
-	attr->d.r.runlist[cnum].len=len;
+	if (attr->d.r.len > cnum)
+		ntfs_memmove(attr->d.r.runlist + cnum + 1,
+			     attr->d.r.runlist + cnum,
+			     (attr->d.r.len - cnum) * sizeof(ntfs_runlist));
+	attr->d.r.runlist[cnum].cluster = cluster;
+	attr->d.r.runlist[cnum].len = len;
 	attr->d.r.len++;
 }
 
-/* Extends an attribute. Another run will be added if necessary,
- * but we try to extend the last run in the runlist first.
+/* Extends an attribute. Another run will be added if necessary, but we try to
+ * extend the last run in the runlist first.
  * FIXME: what if there isn't enough contiguous space, we don't create
  * multiple runs?
  *
  * *len: the desired new length of the attr (_not_ the amount to extend by)
  */
-int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, int *len,
-		int flags)
+int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, int *len, int flags)
 {
-	int error=0;
+	int error = 0;
 	ntfs_runlist *rl;
 	int rlen;
 	ntfs_cluster_t cluster;
 	int clen;
 
-	if(attr->compressed)return EOPNOTSUPP;
-	if(ino->record_count>1)return EOPNOTSUPP;
-
-	if(attr->resident) {
-		error = ntfs_make_attr_nonresident(ino,attr);
-		if(error)
+	if (attr->compressed || ino->record_count > 1)
+		return -EOPNOTSUPP;
+	if (attr->resident) {
+		error = ntfs_make_attr_nonresident(ino, attr);
+		if (error)
 			return error;
 	}
-
-	if( *len <= attr->allocated )
-		return 0;	/* truely stupid things do sometimes happen */
-
-	rl=attr->d.r.runlist;
-	rlen=attr->d.r.len-1;
-
-	if(rlen>=0)
-		cluster=rl[rlen].cluster+rl[rlen].len;
+	if (*len <= attr->allocated)
+		return 0;	/* Truely stupid things do sometimes happen. */
+	rl = attr->d.r.runlist;
+	rlen = attr->d.r.len - 1;
+	if (rlen >= 0)
+		cluster = rl[rlen].cluster + rl[rlen].len;
 	else
-		/* no preference for allocation space */
-		cluster=0;
-
-	/* calculate the extra space we need, and round up to multiple of cluster
-	 * size to get number of new clusters needed */
-
-	clen=( (*len - attr->allocated ) + ino->vol->clustersize - 1 ) /
+		/* No preference for allocation space. */
+		cluster = 0;
+	/* Calculate the extra space we need, and round up to multiple of
+	 * cluster size to get number of new clusters needed */
+	clen = ((*len - attr->allocated) + ino->vol->clustersize - 1) /
 		ino->vol->clustersize;
-	if(clen==0)
+	if (clen == 0)
 		return 0;
-
 	/* FIXME: try to allocate smaller pieces */
-	error=ntfs_allocate_clusters(ino->vol,&cluster,&clen,
-				     flags|ALLOC_REQUIRE_SIZE);
-	if(error)return error;
-	attr->allocated += clen*ino->vol->clustersize;
+	error = ntfs_allocate_clusters(ino->vol, &cluster, &clen,
+				       flags | ALLOC_REQUIRE_SIZE);
+	if (error)
+		return error;
+	attr->allocated += clen * ino->vol->clustersize;
 	*len = attr->allocated;
-
-	/* contiguous chunk */
-	if(rlen>=0 && cluster==rl[rlen].cluster+rl[rlen].len){
+	/* Contiguous chunk. */
+	if (rlen >= 0 && cluster == rl[rlen].cluster + rl[rlen].len) {
 		rl[rlen].len += clen;
 		return 0;
 	}
-	ntfs_insert_run(attr,rlen+1,cluster,clen);
+	ntfs_insert_run(attr, rlen + 1, cluster, clen);
 	return 0;
 }
 
-int
-ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr)
+int ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr)
 {
-	void *data=attr->d.data;
-	int len=attr->size;
-	int error,alen;
+	void *data = attr->d.data;
+	int len = attr->size;
+	int error, alen;
 	ntfs_io io;
-	attr->d.r.len=0;
-	attr->d.r.runlist=0;
-	attr->resident=0;
-	attr->allocated=attr->initialized=0;
-	alen=len;
-	error=ntfs_extend_attr(ino,attr,&alen,ALLOC_REQUIRE_SIZE);
-	if(error)return error;/* FIXME: On error, restore old values */
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=data;
-	io.size=len;
-	io.do_read=0;
-	return ntfs_readwrite_attr(ino,attr,0,&io);
+	attr->d.r.len = 0;
+	attr->d.r.runlist = 0;
+	attr->resident = 0;
+	attr->allocated=attr->initialized = 0;
+	alen = len;
+	error = ntfs_extend_attr(ino, attr, &alen, ALLOC_REQUIRE_SIZE);
+	if (error)
+		return error; /* FIXME: On error, restore old values. */
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = data;
+	io.size = len;
+	io.do_read = 0;
+	return ntfs_readwrite_attr(ino, attr, 0, &io);
 }
 
-int
-ntfs_attr_allnonresident(ntfs_inode *ino)
+int ntfs_attr_allnonresident(ntfs_inode *ino)
 {
-	int i, error=0;
+	int i, error = 0;
         ntfs_volume *vol = ino->vol;
 
-	for (i=0; !error && i<ino->attr_count; i++)
+	for (i = 0; !error && i < ino->attr_count; i++)
 	{
-		if (ino->attrs[i].type != vol->at_security_descriptor
-		    && ino->attrs[i].type != vol->at_data)
+		if (ino->attrs[i].type != vol->at_security_descriptor &&
+		    ino->attrs[i].type != vol->at_data)
 			continue;
-		error = ntfs_make_attr_nonresident (ino, ino->attrs+i);
+		error = ntfs_make_attr_nonresident(ino, ino->attrs + i);
 	}
 	return error;
 }
 
-/* Resize the attribute to a newsize */
+/* Resize the attribute to a newsize. */
 int ntfs_resize_attr(ntfs_inode *ino, ntfs_attribute *attr, int newsize)
 {
-	int error=0;
-	int oldsize=attr->size;
-	int clustersize=ino->vol->clustersize;
-	int i,count,newlen,newcount;
+	int error = 0;
+	int oldsize = attr->size;
+	int clustersize = ino->vol->clustersize;
+	int i, count, newlen, newcount;
 	ntfs_runlist *rl;
 
-	if(newsize==oldsize)
+	if (newsize == oldsize)
 		return 0;
-	/* modifying compressed attributes not supported yet */
-	if(attr->compressed)
-		/* extending is easy: just insert sparse runs */
-		return EOPNOTSUPP;
-	if(attr->resident){
+	/* FIXME: Modifying compressed attributes not supported yet. */
+	if (attr->compressed)
+		/* FIXME: Extending is easy: just insert sparse runs. */
+		return -EOPNOTSUPP;
+	if (attr->resident) {
 		void *v;
-		if(newsize>ino->vol->mft_recordsize){
-			error=ntfs_make_attr_nonresident(ino,attr);
-			if(error)return error;
-			return ntfs_resize_attr(ino,attr,newsize);
+		if (newsize > ino->vol->mft_recordsize) {
+			error = ntfs_make_attr_nonresident(ino, attr);
+			if (error)
+				return error;
+			return ntfs_resize_attr(ino, attr, newsize);
 		}
-		v=attr->d.data;
-		if(newsize){
-			attr->d.data=ntfs_malloc(newsize);
-			if(!attr->d.data) {
+		v = attr->d.data;
+		if (newsize) {
+			attr->d.data = ntfs_malloc(newsize);
+			if (!attr->d.data) {
 				ntfs_free(v);
-				return ENOMEM;
+				return -ENOMEM;
 			}
-			if(newsize>oldsize)
-				ntfs_bzero((char*)attr->d.data+oldsize,
-					   newsize-oldsize);
-			ntfs_memcpy((char*)attr->d.data,v,min(newsize,oldsize));
-		}else
-			attr->d.data=0;
+			if (newsize > oldsize)
+				ntfs_bzero((char*)attr->d.data + oldsize,
+					   newsize - oldsize);
+			ntfs_memcpy((char*)attr->d.data, v,
+				    min(newsize, oldsize));
+		} else
+			attr->d.data = 0;
 		ntfs_free(v);
-		attr->size=newsize;
+		attr->size = newsize;
 		return 0;
 	}
-	/* non-resident attribute */
-	rl=attr->d.r.runlist;
-	if(newsize<oldsize){
-		for(i=0,count=0;i<attr->d.r.len;i++){
-			if((count+rl[i].len)*clustersize>newsize)
+	/* Non-resident attribute. */
+	rl = attr->d.r.runlist;
+	if (newsize < oldsize) {
+		for (i = 0, count = 0; i < attr->d.r.len; i++) {
+			if ((count + rl[i].len) * clustersize > newsize)
 				break;
-			count+=(int)rl[i].len;
+			count += (int)rl[i].len;
 		}
-		newlen=i+1;
-		/* free unused clusters in current run, unless sparse */
-		newcount=count;
-		if(rl[i].cluster!=MAX_CLUSTER_T){
-			int rounded=newsize-count*clustersize;
-			rounded=(rounded+clustersize-1)/clustersize;
-			error=ntfs_deallocate_clusters(ino->vol,rl[i].cluster+rounded,
-						       (int)rl[i].len-rounded);
-			if(error)
-				return error; /* FIXME: incomplete operation */
-			rl[i].len=rounded;
-			newcount=count+rounded;
+		newlen = i + 1;
+		/* Free unused clusters in current run, unless sparse. */
+		newcount = count;
+		if (rl[i].cluster != MAX_CLUSTER_T) {
+			int rounded = newsize - count * clustersize;
+			rounded = (rounded + clustersize - 1) / clustersize;
+			error = ntfs_deallocate_clusters(ino->vol, 
+						rl[i].cluster + rounded,
+						(int)rl[i].len - rounded);
+			if (error)
+				return error; /* FIXME: Incomplete operation. */
+			rl[i].len = rounded;
+			newcount = count + rounded;
 		}
-		/* free all other runs */
-		for(i++;i<attr->d.r.len;i++)
-			if(rl[i].cluster!=MAX_CLUSTER_T){
-				error=ntfs_deallocate_clusters(ino->vol,rl[i].cluster,(int)rl[i].len);
-				if(error)
-					return error; /* FIXME: incomplete operation */
+		/* Free all other runs. */
+		for (i++; i < attr->d.r.len; i++)
+			if (rl[i].cluster != MAX_CLUSTER_T) {
+				error = ntfs_deallocate_clusters(ino->vol,
+								rl[i].cluster,
+								(int)rl[i].len);
+				if (error)
+					return error; /* FIXME: Incomplete 
+						       * operation */
 			}
-		/* FIXME? free space for extra runs in memory */
-		attr->d.r.len=newlen;
-	}else{
-		newlen=newsize;
-		error=ntfs_extend_attr(ino,attr,&newlen,ALLOC_REQUIRE_SIZE);
-		if(error)return error; /* FIXME: incomplete */
-		newcount=newlen/clustersize;
+		/* FIXME: Free space for extra runs in memory? */
+		attr->d.r.len = newlen;
+	} else {
+		newlen = newsize;
+		error = ntfs_extend_attr(ino, attr, &newlen,
+					 ALLOC_REQUIRE_SIZE);
+		if (error)
+			return error; /* FIXME: Incomplete operation. */
+		newcount = newlen / clustersize;
 	}
-	/* fill in new sizes */
-	attr->allocated = newcount*clustersize;
+	/* Fill in new sizes. */
+	attr->allocated = newcount * clustersize;
 	attr->size = newsize;
 	/* attr->initialized does not change. */
-	if(!newsize)
-		error=ntfs_make_attr_resident(ino,attr);
+	if (!newsize)
+		error = ntfs_make_attr_resident(ino, attr);
 	return error;
 }
 
 int ntfs_create_attr(ntfs_inode *ino, int anum, char *aname, void *data,
-	int dsize, ntfs_attribute **rattr)
+		     int dsize, ntfs_attribute **rattr)
 {
 	void *name;
 	int namelen;
-	int found,i;
+	int found, i;
 	int error;
 	ntfs_attribute *attr;
-	if(dsize>ino->vol->mft_recordsize)
-		/* FIXME: non-resident attributes */
-		return EOPNOTSUPP;
-	if(aname){
-		namelen=strlen(aname);
-		name=ntfs_malloc(2*namelen);
-		if( !name )
-			return ENOMEM;
-		ntfs_ascii2uni(name,aname,namelen);
-	}else{
-		name=0;
-		namelen=0;
-	}
-
-	error = ntfs_new_attr(ino,anum,name,namelen,&i,&found,1);
-	if( error ) {
-		ntfs_free( name );
+	
+	if (dsize > ino->vol->mft_recordsize)
+		/* FIXME: Non-resident attributes. */
+		return -EOPNOTSUPP;
+	if (aname) {
+		namelen = strlen(aname);
+		name = ntfs_malloc(2 * namelen);
+		if (!name)
+			return -ENOMEM;
+		ntfs_ascii2uni(name, aname, namelen);
+	} else {
+		name = 0;
+		namelen = 0;
+	}
+	error = ntfs_new_attr(ino, anum, name, namelen, &i, &found, 1);
+	if (error) {
+		ntfs_free(name);
 		return error;
 	}
-
-	if(found){
+	if (found) {
 		ntfs_free(name);
-		return EEXIST;
+		return -EEXIST;
 	}
-	*rattr=attr=ino->attrs+i;
-	/* allocate a new number.
-	   FIXME: Should this happen on inode writeback?
-	   FIXME: extensions records not supported */
-	error=ntfs_allocate_attr_number(ino,&i);
-	if(error)
+	*rattr = attr = ino->attrs + i;
+	/* Allocate a new number.
+	 * FIXME: Should this happen on inode writeback?
+	 * FIXME: Extension records not supported. */
+	error = ntfs_allocate_attr_number(ino, &i);
+	if (error)
 		return error;
-	attr->attrno=i;
-
-	attr->resident=1;
-	attr->compressed=attr->cengine=0;
-	attr->size=attr->allocated=attr->initialized=dsize;
+	attr->attrno = i;
+	attr->resident = 1;
+	attr->compressed = attr->cengine = 0;
+	attr->size = attr->allocated = attr->initialized = dsize;
 
 	/* FIXME: INDEXED information should come from $AttrDef
-	   Currently, only file names are indexed */
-	if(anum==ino->vol->at_file_name){
-		attr->indexed=1;
-	}else
-		attr->indexed=0;
-	attr->d.data=ntfs_malloc(dsize);
-
-	if( !attr->d.data )
-		return ENOMEM;
-
-	ntfs_memcpy(attr->d.data,data,dsize);
+	 * Currently, only file names are indexed. As of NTFS v3.0 (Win2k),
+	 * this is no longer true. Different attributes can be indexed now. */
+	if (anum == ino->vol->at_file_name) {
+		attr->indexed = 1;
+	} else
+		attr->indexed = 0;
+	attr->d.data = ntfs_malloc(dsize);
+	if (!attr->d.data)
+		return -ENOMEM;
+	ntfs_memcpy(attr->d.data, data, dsize);
 	return 0;
 }
 
 /* Non-resident attributes are stored in runs (intervals of clusters).
  *
  * This function stores in the inode readable information about a non-resident
- * attribute.
- */
-static int 
-ntfs_process_runs(ntfs_inode *ino,ntfs_attribute* attr,unsigned char *data)
+ * attribute. */
+static int ntfs_process_runs(ntfs_inode *ino, ntfs_attribute* attr,
+			     unsigned char *data)
 {
-	int startvcn,endvcn;
-	int vcn,cnum;
+	int startvcn, endvcn;
+	int vcn, cnum;
 	ntfs_cluster_t cluster;
-	int len,ctype;
-	startvcn = NTFS_GETU64(data+0x10);
-	endvcn = NTFS_GETU64(data+0x18);
-
-	/* check whether this chunk really belongs to the end */
-	for(cnum=0,vcn=0;cnum<attr->d.r.len;cnum++)
-		vcn+=attr->d.r.runlist[cnum].len;
-	if(vcn!=startvcn)
-	{
+	int len, ctype;
+	startvcn = NTFS_GETU64(data + 0x10);
+	endvcn = NTFS_GETU64(data + 0x18);
+
+	/* Check whether this chunk really belongs to the end. */
+	for (cnum = 0, vcn = 0; cnum < attr->d.r.len; cnum++)
+		vcn += attr->d.r.runlist[cnum].len;
+	if (vcn != startvcn) {
 		ntfs_error("Problem with runlist in extended record\n");
 		return -1;
 	}
-	if(!endvcn)
-	{
-		endvcn = NTFS_GETU64(data+0x28)-1; /* allocated length */
+	if (!endvcn) {
+		endvcn = NTFS_GETU64(data + 0x28) - 1; /* Allocated length. */
 		endvcn /= ino->vol->clustersize;
 	}
-	data=data+NTFS_GETU16(data+0x20);
-	cnum=attr->d.r.len;
-	cluster=0;
-	for(vcn=startvcn; vcn<=endvcn; vcn+=len)
-	{
-		if(ntfs_decompress_run(&data,&len,&cluster,&ctype))
+	data = data + NTFS_GETU16(data + 0x20);
+	cnum = attr->d.r.len;
+	cluster = 0;
+	for (vcn = startvcn; vcn <= endvcn; vcn += len)	{
+		if (ntfs_decompress_run(&data, &len, &cluster, &ctype))
 			return -1;
-		if(ctype)
-			ntfs_insert_run(attr,cnum,-1,len);
+		if (ctype)
+			ntfs_insert_run(attr, cnum, -1, len);
 		else
-			ntfs_insert_run(attr,cnum,cluster,len);
+			ntfs_insert_run(attr, cnum, cluster, len);
 		cnum++;
 	}
 	return 0;
 }
   
-/* Insert the attribute starting at attr in the inode ino */
+/* Insert the attribute starting at attr in the inode ino. */
 int ntfs_insert_attribute(ntfs_inode *ino, unsigned char* attrdata)
 {
-	int i,found;
+	int i, found;
 	int type;
 	short int *name;
 	int namelen;
@@ -415,208 +403,207 @@
 	int error;
 
 	type = NTFS_GETU32(attrdata);
-	namelen = NTFS_GETU8(attrdata+9);
-	/* read the attribute's name if it has one */
-	if(!namelen)
-		name=0;
-	else
-	{
-		/* 1 Unicode character fits in 2 bytes */
-		name=ntfs_malloc(2*namelen);
-		if( !name )
-			return ENOMEM;
-
-		ntfs_memcpy(name,attrdata+NTFS_GETU16(attrdata+10),2*namelen);
-	}
-
-	error = ntfs_new_attr(ino,type,name,namelen,&i,&found,1);
-	if( error ) {
-		if( name ) ntfs_free( name );
+	namelen = NTFS_GETU8(attrdata + 9);
+	/* Read the attribute's name if it has one. */
+	if (!namelen)
+		name = 0;
+	else {
+		/* 1 Unicode character fits in 2 bytes. */
+		name = ntfs_malloc(2 * namelen);
+		if (!name)
+			return -ENOMEM;
+		ntfs_memcpy(name, attrdata + NTFS_GETU16(attrdata + 10),
+			    2 * namelen);
+	}
+	error = ntfs_new_attr(ino, type, name, namelen, &i, &found, 1);
+	if (error) {
+		if (name)
+			ntfs_free(name);
 		return error;
 	}
-
-	/* We can have in one inode two attributes with type 0x00000030 (File Name) 
-	   and without name */
-	if(found && /*FIXME*/type!=ino->vol->at_file_name)
+	/* We can have in one inode two attributes with type 0x00000030 (File
+	 * Name) and without name. FIXME: We can have a lot more than two!
+	 * That is how hard links are implemented. (AIA) */
+	if (found && /*FIXME*/ type != ino->vol->at_file_name)
 	{
-		ntfs_process_runs(ino,ino->attrs+i,attrdata);
+		ntfs_process_runs(ino, ino->attrs + i, attrdata);
 		return 0;
- 	} else if( found ) {
- 		/*	Don't understand the above, but I know it leaks memory below
- 			as it overwrites a found entry without freeing it. So here we
- 			call ntfs_new_attr again but this time ask it to always allocate a
- 			new	entry */
- 		ntfs_new_attr(ino,type,name,namelen,&i,&found,0);
-	}
-	attr=ino->attrs+i;
-	attr->resident=NTFS_GETU8(attrdata+8)==0;
-	attr->compressed=NTFS_GETU16(attrdata+0xC);
-	attr->attrno=NTFS_GETU16(attrdata+0xE);
+ 	} else if (found) {
+ 		/* Don't understand the above, but I know it leaks memory below
+		 * as it overwrites a found entry without freeing it. So here
+		 * we call ntfs_new_attr again but this time ask it to always
+		 * allocate a new entry. */
+ 		ntfs_new_attr(ino, type, name, namelen, &i, &found, 0);
+	}
+	attr = ino->attrs + i;
+	attr->resident = NTFS_GETU8(attrdata + 8) == 0;
+	attr->compressed = NTFS_GETU16(attrdata + 0xC);
+	attr->attrno = NTFS_GETU16(attrdata + 0xE);
   
-	if(attr->resident) {
-		attr->size=NTFS_GETU16(attrdata+0x10);
-		data=attrdata+NTFS_GETU16(attrdata+0x14);
+	if (attr->resident) {
+		attr->size = NTFS_GETU16(attrdata + 0x10);
+		data = attrdata + NTFS_GETU16(attrdata + 0x14);
 		attr->d.data = (void*)ntfs_malloc(attr->size);
-		if( !attr->d.data )
-			return ENOMEM;
-		ntfs_memcpy(attr->d.data,data,attr->size);
-		attr->indexed=NTFS_GETU16(attrdata+0x16);
-	}else{
-		attr->allocated=NTFS_GETU32(attrdata+0x28);
-		attr->size=NTFS_GETU32(attrdata+0x30);
-		attr->initialized=NTFS_GETU32(attrdata+0x38);
-		attr->cengine=NTFS_GETU16(attrdata+0x22);
-		if(attr->compressed)
-			attr->compsize=NTFS_GETU32(attrdata+0x40);
-		ino->attrs[i].d.r.runlist=0;
-		ino->attrs[i].d.r.len=0;
-		ntfs_process_runs(ino,attr,attrdata);
+		if (!attr->d.data)
+			return -ENOMEM;
+		ntfs_memcpy(attr->d.data, data, attr->size);
+		attr->indexed = NTFS_GETU16(attrdata + 0x16);
+	} else {
+		attr->allocated = NTFS_GETU32(attrdata + 0x28);
+		attr->size = NTFS_GETU32(attrdata + 0x30);
+		attr->initialized = NTFS_GETU32(attrdata + 0x38);
+		attr->cengine = NTFS_GETU16(attrdata + 0x22);
+		if (attr->compressed)
+			attr->compsize = NTFS_GETU32(attrdata + 0x40);
+		ino->attrs[i].d.r.runlist = 0;
+		ino->attrs[i].d.r.len = 0;
+		ntfs_process_runs(ino, attr, attrdata);
 	}
 	return 0;
 }
 
-int
-ntfs_read_zero(ntfs_io *dest,int size)
+int ntfs_read_zero(ntfs_io *dest, int size)
 {
-	char *sparse=ntfs_calloc(512);
-	if(!sparse)
-		return ENOMEM;
-	while(size){
-		int i=min(size,512);
-		dest->fn_put(dest,sparse,i);
-		size-=i;
+	char *sparse = ntfs_calloc(512);
+	if (!sparse)
+		return -ENOMEM;
+	while (size) {
+		int i = min(size, 512);
+		dest->fn_put(dest, sparse, i);
+		size -= i;
 	}
 	ntfs_free(sparse);
 	return 0;
 }
 
-/* process compressed attributes */
+/* Process compressed attributes. */
 int ntfs_read_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-	ntfs_io *dest)
+			 ntfs_io *dest)
 {
-	int error=0;
-	int clustersize,l;
-	int s_vcn,rnum,vcn,len,chunk,got,l1,offs1,copied;
-	ntfs_cluster_t cluster,cl1;
-	char *comp=0,*comp1;
-	char *decomp=0;
+	int error = 0;
+	int clustersize, l;
+	int s_vcn, rnum, vcn, len, chunk, got, l1, offs1, copied;
+	ntfs_cluster_t cluster, cl1;
+	char *comp = 0, *comp1;
+	char *decomp = 0;
 	ntfs_io io;
 	ntfs_runlist *rl;
 
-	l=dest->size;
-	clustersize=ino->vol->clustersize;
-	/* starting cluster of potential chunk
-	   there are three situations:
-	   a) in a large uncompressible or sparse chunk, 
-	   s_vcn is in the middle of a run
-	   b) s_vcn is right on a run border
-	   c) when several runs make a chunk, s_vcn is before the chunks
-	*/
-	s_vcn=offset/clustersize;
-	/* round down to multiple of 16 */
+	l = dest->size;
+	clustersize = ino->vol->clustersize;
+	/* Starting cluster of potential chunk. There are three situations:
+	   a) In a large uncompressible or sparse chunk, s_vcn is in the middle
+	      of a run.
+	   b) s_vcn is right on a run border.
+	   c) When several runs make a chunk, s_vcn is before the chunks. */
+	s_vcn = offset / clustersize;
+	/* Round down to multiple of 16. */
 	s_vcn &= ~15;
-	rl=attr->d.r.runlist;
-	for(rnum=vcn=0;rnum<attr->d.r.len && vcn+rl->len<=s_vcn;rnum++,rl++)
-		vcn+=rl->len;
-	if(rnum==attr->d.r.len){
-		/* beyond end of file */
-		/* FIXME: check allocated/initialized */
-		dest->size=0;
+	rl = attr->d.r.runlist;
+	for (rnum = vcn = 0; rnum < attr->d.r.len && vcn + rl->len <= s_vcn;
+								rnum++, rl++)
+		vcn += rl->len;
+	if (rnum == attr->d.r.len) {
+		/* Beyond end of file. */
+		/* FIXME: Check allocated / initialized. */
+		dest->size = 0;
 		return 0;
 	}
-	io.do_read=1;
-	io.fn_put=ntfs_put;
-	io.fn_get=0;
-	cluster=rl->cluster;
-	len=rl->len;
-	copied=0;
-	while(l){
-		chunk=0;
-		if(cluster==MAX_CLUSTER_T){
-			/* sparse cluster */
+	io.do_read = 1;
+	io.fn_put = ntfs_put;
+	io.fn_get = 0;
+	cluster = rl->cluster;
+	len = rl->len;
+	copied = 0;
+	while (l) {
+		chunk = 0;
+		if (cluster == MAX_CLUSTER_T) {
+			/* Sparse cluster. */
 			int l1;
-			if((len-(s_vcn-vcn)) & 15)
-				ntfs_error("unexpected sparse chunk size");
-			l1=chunk = min((vcn+len)*clustersize-offset,l);
-			error = ntfs_read_zero(dest,l1);
-			if(error)
+			if ((len - (s_vcn - vcn)) & 15)
+				ntfs_error("Unexpected sparse chunk size.");
+			l1 = chunk = min((vcn + len) * clustersize - offset, l);
+			error = ntfs_read_zero(dest, l1);
+			if (error)
 				goto out;
-		}else if(dest->do_read){
-			if(!comp){
-				comp=ntfs_malloc(16*clustersize);
-				if(!comp){
-					error=ENOMEM;
+		} else if (dest->do_read) {
+			if (!comp) {
+				comp = ntfs_malloc(16 * clustersize);
+				if (!comp) {
+					error = -ENOMEM;
 					goto out;
 				}
 			}
-			got=0;
-			/* we might need to start in the middle of a run */
-			cl1=cluster+s_vcn-vcn;
-			comp1=comp;
-			do{
-				io.param=comp1;
-				l1=min(len-max(s_vcn-vcn,0),16-got);
-				io.size=l1*clustersize;
-				error=ntfs_getput_clusters(ino->vol,cl1,0,&io);
-				if(error)goto out;
-				if(l1+max(s_vcn-vcn,0)==len){
-					rnum++;rl++;
-					vcn+=len;
-					cluster=cl1=rl->cluster;
-					len=rl->len;
+			got = 0;
+			/* We might need to start in the middle of a run. */
+			cl1 = cluster + s_vcn - vcn;
+			comp1 = comp;
+			do {
+				io.param = comp1;
+				l1 = min(len - max(s_vcn - vcn, 0), 16 - got);
+				io.size = l1 * clustersize;
+				error = ntfs_getput_clusters(ino->vol, cl1, 0,
+					       		     &io);
+				if (error)
+					goto out;
+				if (l1 + max(s_vcn - vcn, 0) == len) {
+					rnum++;
+					rl++;
+					vcn += len;
+					cluster = cl1 = rl->cluster;
+					len = rl->len;
 				}
-				got+=l1;
-				comp1+=l1*clustersize;
-			}while(cluster!=MAX_CLUSTER_T && got<16); /* until empty run */
-			chunk=16*clustersize;
-			if(cluster!=MAX_CLUSTER_T || got==16)
-				/* uncompressible */
-				comp1=comp;
-			else{
-				if(!decomp){
-					decomp=ntfs_malloc(16*clustersize);
-					if(!decomp){
-						error=ENOMEM;
+				got += l1;
+				comp1 += l1 * clustersize;
+			} while (cluster != MAX_CLUSTER_T && got < 16);
+							/* Until empty run. */
+			chunk = 16 * clustersize;
+			if (cluster != MAX_CLUSTER_T || got == 16)
+				/* Uncompressible */
+				comp1 = comp;
+			else {
+				if (!decomp) {
+					decomp = ntfs_malloc(16 * clustersize);
+					if (!decomp) {
+						error = -ENOMEM;
 						goto out;
 					}
 				}
-				/* make sure there are null bytes
-				   after the last block */
-				*(ntfs_u32*)comp1=0;
-				ntfs_decompress(decomp,comp,chunk);
-				comp1=decomp;
+				/* Make sure there are null bytes after the
+				 * last block. */
+				*(ntfs_u32*)comp1 = 0;
+				ntfs_decompress(decomp, comp, chunk);
+				comp1 = decomp;
 			}
-			offs1=offset-s_vcn*clustersize;
-			chunk=min(16*clustersize-offs1,chunk);
-			chunk=min(l,chunk);
-			dest->fn_put(dest,comp1+offs1,chunk);
+			offs1 = offset - s_vcn * clustersize;
+			chunk = min(16 * clustersize - offs1, chunk);
+			chunk = min(l, chunk);
+			dest->fn_put(dest, comp1 + offs1, chunk);
 		}
-		l-=chunk;
-		copied+=chunk;
-		offset+=chunk;
-		s_vcn=offset/clustersize & ~15;
-		if(l && offset>=((vcn+len)*clustersize)){
-			rnum++;rl++;
-			vcn+=len;
-			cluster=rl->cluster;
-			len=rl->len;
+		l -= chunk;
+		copied += chunk;
+		offset += chunk;
+		s_vcn = offset / clustersize & ~15;
+		if (l && offset >= ((vcn + len) * clustersize)) {
+			rnum++;
+			rl++;
+			vcn += len;
+			cluster = rl->cluster;
+			len = rl->len;
 		}
 	}
  out:
-	if(comp)ntfs_free(comp);
-	if(decomp)ntfs_free(decomp);
-	dest->size=copied;
+	if (comp)
+		ntfs_free(comp);
+	if (decomp)
+		ntfs_free(decomp);
+	dest->size = copied;
 	return error;
 }
 
 int ntfs_write_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-	ntfs_io *dest)
+			  ntfs_io *dest)
 {
-	return EOPNOTSUPP;
+	return -EOPNOTSUPP;
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)