📄 super.c
字号:
if( !vol_size ) return EFAULT; cluster0=ntfs_malloc(vol->clustersize); if( !cluster0 ) return ENOMEM; io.fn_put=ntfs_put; io.fn_get=ntfs_get; io.param=cluster0; io.do_read=1; io.size=vol->clustersize; ntfs_getput_clusters(vol,0,0,&io); *vol_size = NTFS_GETU64(cluster0+0x28); ntfs_free(cluster0); return 0;}static int nc[16]={4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0};int ntfs_get_free_cluster_count(ntfs_inode *bitmap){ unsigned char bits[2048]; int offset,error; int clusters=0; ntfs_io io; offset=0; io.fn_put=ntfs_put; io.fn_get=ntfs_get; while(1) { register int i; io.param=bits; io.size=2048; error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0, offset,&io); if(error || io.size==0)break; /* I never thought I would do loop unrolling some day */ for(i=0;i<io.size-8;){ clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; } for(;i<io.size;){ clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF]; } offset+=io.size; } return clusters;}/* Insert the fixups for the record. The number and location of the fixes is obtained from the record header */void ntfs_insert_fixups(unsigned char *rec, int secsize){ int first=NTFS_GETU16(rec+4); int count=NTFS_GETU16(rec+6); int offset=-2; ntfs_u16 fix=NTFS_GETU16(rec+first); fix=fix+1; NTFS_PUTU16(rec+first,fix); count--; while(count--){ first+=2; offset+=secsize; NTFS_PUTU16(rec+first,NTFS_GETU16(rec+offset)); NTFS_PUTU16(rec+offset,fix); };}/* search the bitmap bits of l bytes for *cnt zero bits. Return the bit number in *loc, which is initially set to the number of the first bit. Return the largest block found in *cnt. Return 0 on success, ENOSPC if all bits are used */static int search_bits(unsigned char* bits,ntfs_cluster_t *loc,int *cnt,int l){ unsigned char c=0; int bc=0; int bstart=0,bstop=0,found=0; int start,stop=0,in=0; /* special case searching for a single block */ if(*cnt==1){ while(l && *bits==0xFF){ bits++; *loc+=8; l--; } if(!l)return ENOSPC; for(c=*bits;c & 1;c>>=1) (*loc)++; return 0; } start=*loc; while(l || bc){ if(bc==0){ c=*bits; if(l){ l--;bits++; } bc=8; } if(in){ if((c&1)==0) stop++; else{ /* end of sequence of zeroes */ in=0; if(!found || bstop-bstart<stop-start){ bstop=stop;bstart=start;found=1; if(bstop-bstart>*cnt) break; } start=stop+1; } }else{ if(c&1) start++; else{ /*start of sequence*/ in=1; stop=start+1; } } bc--; c>>=1; } if(in && (!found || bstop-bstart<stop-start)){ bstop=stop;bstart=start;found=1; } if(!found)return ENOSPC; *loc=bstart; if(*cnt>bstop-bstart) *cnt=bstop-bstart; return 0;}int ntfs_set_bitrange(ntfs_inode* bitmap,ntfs_cluster_t loc,int cnt,int bit){ int bsize,locit,error; unsigned char *bits,*it; ntfs_io io; io.fn_put=ntfs_put; io.fn_get=ntfs_get; bsize=(cnt+(loc & 7)+7) >> 3; /* round up to multiple of 8*/ bits=ntfs_malloc(bsize); io.param=bits; io.size=bsize; if(!bits) return ENOMEM; error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io); if(error || io.size!=bsize){ ntfs_free(bits); return error?error:EIO; } /* now set the bits */ it=bits; locit=loc; while(locit%8 && cnt){ /* process first byte */ if(bit) *it |= 1<<(locit%8); else *it &= ~(1<<(locit%8)); cnt--;locit++; if(locit%8==0) it++; } while(cnt>8){ /*process full bytes */ *it= bit ? 0xFF : 0; cnt-=8; locit+=8; it++; } while(cnt){ /*process last byte */ if(bit) *it |= 1<<(locit%8); else *it &= ~(1<<(locit%8)); cnt--;locit++; } /* reset to start */ io.param=bits; io.size=bsize; error=ntfs_write_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io); ntfs_free(bits); if(error)return error; if(io.size!=bsize) return EIO; return 0;} /* allocate count clusters around location. If location is -1, it does not matter where the clusters are. Result is 0 if success, in which case location and count says what they really got */int ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count, int flags){ unsigned char *bits; ntfs_io io; int error=0,found=0; int cnt,bloc=-1,bcnt=0; int start; ntfs_cluster_t loc; bits=ntfs_malloc(2048); if( !bits ) return ENOMEM; io.fn_put=ntfs_put; io.fn_get=ntfs_get; io.param=bits; /* first search within +/- 8192 clusters */ start=*location>>3; start= start>1024 ? start-1024 : 0; io.size=2048; error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,start,&io); if(error)goto fail; loc=start*8; cnt=*count; error=search_bits(bits,&loc,&cnt,io.size); if(error) goto fail; if(*count==cnt){ bloc=loc; bcnt=cnt; goto success; } /* now search from the beginning */ for(start=0;1;start+=2048) { io.param=bits; io.size=2048; error=ntfs_read_attr(bitmap,bitmap->vol->at_data, 0,start,&io); if(error)goto fail; if(io.size==0){ if(found) goto success; else{ error=ENOSPC; goto fail; } } loc=start*8; cnt=*count; error=search_bits(bits,&loc,&cnt,io.size); if(error) goto fail; if(*count==cnt) goto success; if(bcnt<cnt){ bcnt=cnt; bloc=loc; found=1; } } success: ntfs_free(bits); /* check flags */ if((flags & ALLOC_REQUIRE_LOCATION) && *location!=bloc) error=ENOSPC; else if((flags & ALLOC_REQUIRE_SIZE) && *count!=bcnt) error=ENOSPC; else ntfs_set_bitrange(bitmap,bloc,bcnt,1); /* If allocation failed due to the flags, tell the caller what he could have gotten */ *location=bloc; *count=bcnt; return 0; fail: *location=-1; *count=0; ntfs_free(bits); return error;}int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location, int *count, int flags){ int error; error=ntfs_search_bits(vol->bitmap,location,count,flags); return error;}int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location, int count){ int error; error=ntfs_set_bitrange(vol->bitmap,location,count,0); return error;}/* * Local variables: * c-file-style: "linux" * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -