patch-2.2.6 linux/fs/ntfs/inode.c
Next file: linux/fs/ntfs/inode.h
Previous file: linux/fs/ntfs/fs.c
Back to the patch index
Back to the overall index
- Lines: 287
- Date:
Mon Apr 12 10:05:58 1999
- Orig file:
v2.2.5/linux/fs/ntfs/inode.c
- Orig date:
Mon Jan 4 15:08:17 1999
diff -u --recursive --new-file v2.2.5/linux/fs/ntfs/inode.c linux/fs/ntfs/inode.c
@@ -5,13 +5,18 @@
* Copyright (C) 1996 Albert D. Cahalan
* Copyright (C) 1996-1997 Régis Duchesne
* Copyright (C) 1998 Joseph Malicki
+ * Copyright (C) 1999 Steve Dodd
*/
#include "ntfstypes.h"
+#include "ntfsendian.h"
#include "struct.h"
#include "inode.h"
#include <linux/errno.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
#include "macros.h"
#include "attr.h"
#include "super.h"
@@ -30,8 +35,8 @@
ntfs_mft_record* records;
} ntfs_disk_inode;
-static void
-fill_mft_header(ntfs_u8*mft,int record_size,int blocksize,
+void
+ntfs_fill_mft_header(ntfs_u8*mft,int record_size,int blocksize,
int sequence_number)
{
int fixup_count = record_size / blocksize + 1;
@@ -98,7 +103,7 @@
if(mdata->allocated<mdata->size+vol->mft_recordsize){
size=ntfs_get_free_cluster_count(vol->bitmap)*vol->clustersize;
block=vol->mft_recordsize;
- size=max(size/1000,block);
+ size=max(size/1000,mdata->size+vol->mft_recordsize);
size=((size+block-1)/block)*block;
/* require this to be a single chunk */
error=ntfs_extend_attr(vol->mft_ino,mdata,&size,
@@ -141,7 +146,7 @@
/* now fill in the MFT header for the new block */
buf=ntfs_calloc(vol->mft_recordsize);
if(!buf)return ENOMEM;
- fill_mft_header(buf,vol->mft_recordsize,vol->blocksize,0);
+ ntfs_fill_mft_header(buf,vol->mft_recordsize,vol->blocksize,0);
ntfs_insert_fixups(buf,vol->blocksize);
io.param=buf;
io.size=vol->mft_recordsize;
@@ -149,6 +154,8 @@
(rcount-1)*vol->mft_recordsize,&io);
if(error)return error;
if(io.size!=vol->mft_recordsize)return EIO;
+ error=ntfs_update_inode(vol->mft_ino);
+ if(error)return error;
return 0;
}
@@ -165,13 +172,16 @@
/* (re-)allocate space if necessary */
if(ino->record_count % 8==0)
{
- int *old=ino->records;
- ino->records=ntfs_malloc((ino->record_count+8)*sizeof(int));
- if(old) {
+ int *new;
+ new = ntfs_malloc((ino->record_count+8)*sizeof(int));
+ if( !new )
+ return;
+ if( ino->records ) {
for(i=0;i<ino->record_count;i++)
- ino->records[i]=old[i];
- ntfs_free(old);
+ new[i] = ino->records[i];
+ ntfs_free( ino->records );
}
+ ino->records = new;
}
ino->records[ino->record_count]=mftno;
ino->record_count++;
@@ -179,8 +189,10 @@
do{
type=NTFS_GETU32(it);
len=NTFS_GETU32(it+4);
- if(type!=-1)
+ if(type!=-1) {
+ /* FIXME: check ntfs_insert_attribute for failure (e.g. no mem)? */
ntfs_insert_attribute(ino,it);
+ }
it+=len;
}while(type!=-1); /* attribute list ends with type -1 */
}
@@ -195,6 +207,8 @@
int last_mft=-1;
int len=*plen;
mft=ntfs_malloc(ino->vol->mft_recordsize);
+ if( !mft )
+ return ENOMEM;
while(len>8)
{
l=NTFS_GETU16(alist+4);
@@ -239,6 +253,8 @@
return;
}
buf=ntfs_malloc(1024);
+ if( !buf )
+ return;
delta=0;
for(offset=0;datasize;datasize-=len)
{
@@ -271,6 +287,8 @@
ino->i_number=inum;
ino->vol=vol;
ino->attr=buf=ntfs_malloc(vol->mft_recordsize);
+ if( !buf )
+ return ENOMEM;
error=ntfs_read_mft_record(vol,inum,ino->attr);
if(error){
ntfs_debug(DEBUG_OTHER, "init inode: %x failed\n",inum);
@@ -441,7 +459,7 @@
int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, int offset,
ntfs_io *dest)
{
- int datasize,rnum;
+ int rnum;
ntfs_cluster_t cluster,s_cluster,vcn,len;
int l,chunk,copied;
int s_vcn;
@@ -449,26 +467,39 @@
int error;
clustersize=ino->vol->clustersize;
- datasize=attr->size;
l=dest->size;
if(l==0)
return 0;
if(dest->do_read)
{
- if(offset>=datasize){
+ /* if read _starts_ beyond end of stream, return nothing */
+ if(offset>=attr->size){
dest->size=0;
return 0;
}
- if(offset+l>=datasize)
- l=dest->size=datasize-offset;
- }else { /* fixed by CSA: if writing beyond end, extend attribute */
- if (offset+l>datasize) {
+
+ /* if read _extends_ beyond end of stream, return as much
+ initialised data as we have */
+ if(offset+l>=attr->size)
+ l=dest->size=attr->size-offset;
+
+ }else {
+ /* fixed by CSA: if writing beyond end, extend attribute */
+
+ /* if write extends beyond _allocated_ size, extend attrib */
+ if (offset+l>attr->allocated) {
error=ntfs_resize_attr(ino,attr,offset+l);
if(error)
return error;
}
- if (offset+l > attr->initialized)
+
+ /* the amount of initialised data has increased; update */
+ /* FIXME: shouldn't we zero-out the section between the old
+ initialised length and the write start? */
+ if (offset+l > attr->initialized) {
attr->initialized = offset+l;
+ attr->size = offset+l;
+ }
}
if(attr->resident)
{
@@ -565,7 +596,6 @@
{
int rnum;
ntfs_attribute *data;
- ntfs_error("bmap %x\n",vcn);
data=ntfs_find_attr(ino,ino->vol->at_data,0);
/* It's hard to give an error code */
if(!data)return -1;
@@ -583,7 +613,6 @@
vcn>data->d.r.runlist[rnum].len;rnum++)
vcn-=data->d.r.runlist[rnum].len;
- ntfs_error("result %x\n",data->d.r.runlist[rnum].cluster+vcn);
return data->d.r.runlist[rnum].cluster+vcn;
}
@@ -655,7 +684,7 @@
*(rec+offset)|=coffs++;
- if(rl[i].cluster==0) /*compressed run*/
+ if(rl[i].cluster==MAX_CLUSTER_T) /*compressed run*/
/*nothing*/;
else if(rclus>-0x80 && rclus<0x7F){
*(rec+offset)|=0x10;
@@ -768,7 +797,8 @@
NTFS_PUTU16(buf+0xA,asize);
ntfs_memcpy(buf+asize,attr->name,2*attr->namelen);
asize+=2*attr->namelen;
- asize=(asize+7) & ~7;
+ /* SRD: you whaaa?
+ asize=(asize+7) & ~7;*/
}
/* asize points at the beginning of the data */
NTFS_PUTU16(buf+0x20,asize);
@@ -841,7 +871,12 @@
if(error)
return error;
}
- next=(next+7) & ~7; /* align to DWORD */
+ /* SRD: umm..
+ next=(next+7) & ~7; */
+ /* is this setting the length? if so maybe we could get
+ away with rounding up so long as we set the length first..
+ ..except, is the length the only way to get to the next attr?
+ */
NTFS_PUTU16(rec+offset+4,next-offset);
offset=next;
#endif
@@ -1038,7 +1073,8 @@
data=ntfs_find_attr(vol->mft_ino,vol->at_data,0);
length=data->size/vol->mft_recordsize;
- for (byte = 3; 8*byte < length; byte++)
+ /* SRD: start at byte 0: bits for system files _are_ already set in bitmap */
+ for (byte = 0; 8*byte < length; byte++)
{
value = buffer[byte];
if(value==0xFF)
@@ -1064,7 +1100,7 @@
mft=ino->attr;
ntfs_bzero(mft, vol->mft_recordsize);
- fill_mft_header(mft,vol->mft_recordsize,vol->blocksize,
+ ntfs_fill_mft_header(mft,vol->mft_recordsize,vol->blocksize,
ino->sequence_number);
return 0;
}
@@ -1108,6 +1144,8 @@
/* work out the size */
size = 0x42 + 2 * length;
data = ntfs_malloc(size);
+ if( !data )
+ return ENOMEM;
ntfs_bzero(data,size);
/* search for a position */
@@ -1191,7 +1229,7 @@
{
ntfs_io io;
int error;
- ntfs_u8 buffer[1];
+ ntfs_u8 buffer[2];
ntfs_volume* vol=dir->vol;
int byte,bit;
@@ -1230,7 +1268,7 @@
*/
/* get the sequence number */
io.param = buffer;
- io.size = 0x10;
+ io.size = 2;
error = ntfs_read_attr(vol->mft_ino, vol->at_data, 0,
result->i_number*vol->mft_recordsize+0x10,&io);
if(error)
@@ -1238,10 +1276,17 @@
result->sequence_number=NTFS_GETU16(buffer)+1;
result->vol=vol;
result->attr=ntfs_malloc(vol->mft_recordsize);
+ if( !result->attr )
+ return ENOMEM;
result->attr_count=0;
result->attrs=0;
result->record_count=1;
result->records=ntfs_malloc(8*sizeof(int));
+ if( !result->records ) {
+ ntfs_free( result->attr );
+ result->attr = 0;
+ return ENOMEM;
+ }
result->records[0]=result->i_number;
error=add_mft_header(result);
if(error)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)