Ejemplo n.º 1
0
static int root_map(File_t *This, off_t where, size_t *len, int mode,
					mt_off_t *res)
{
	Fs_t *Fs = This->Fs;

	if(Fs->dir_len * Fs->sector_size < where) {
		*len = 0;
		errno = ENOSPC;
		return -2;
	}

	maximize(*len, Fs->dir_len * Fs->sector_size - where);
        if (*len == 0)
            return 0;
	
	*res = sectorsToBytes((Stream_t*)Fs, Fs->dir_start) + where;
	return 1;
}
Ejemplo n.º 2
0
static int root_map(struct File_t *This, off_t where, size_t *len, int UNUSED(mode), off_t *res)
{
	struct Fs_t *Fs = This->Fs;

	if(Fs->dir_len * Fs->sector_size < (size_t) where)
	{
		*len = 0;
		errno = ENOSPC;
		return -2;
	}

	maximize(*len, Fs->dir_len * Fs->sector_size - where);

	if (*len == 0)
		return 0;

	*res = sectorsToBytes((struct Stream_t*)Fs, Fs->dir_start) + where;

	return 1;
}
Ejemplo n.º 3
0
static int scan(Fs_t *Fs, Stream_t *dev,
		long cluster, unsigned int badClus,
		char *buffer, int write) {
	off_t start;
	off_t ret;
	off_t pos;
	int bad=0;

	if(Fs->fat_decode((Fs_t*)Fs, cluster))
		/* cluster busy, or already marked */
		return 0;
	start = (cluster - 2) * Fs->cluster_size + Fs->clus_start;
	pos = sectorsToBytes((Stream_t*)Fs, start);
	if(write) {
		ret = force_write(dev, buffer, pos, in_len);
		if(ret < in_len )
			bad = 1;
	} else {
		ret = force_read(dev, in_buf, pos, in_len);
		if(ret < in_len )
			bad = 1;
		else if(buffer) {
			int i;
			for(i=0; i<in_len; i++)
				if(in_buf[i] != buffer[i]) {
					bad = 1;
					break;
				}
		}
	}

	if(bad) {
		printf("Bad cluster %ld found\n", cluster);
		fatEncode((Fs_t*)Fs, cluster, badClus);
		return 1;
	}
	return 0;
}
Ejemplo n.º 4
0
static int normal_map(File_t *This, off_t where, size_t *len, int mode,
						   mt_off_t *res)
{
	int offset;
	off_t end;
	int NrClu; /* number of clusters to read */
	unsigned int RelCluNr;
	unsigned int CurCluNr;
	unsigned int NewCluNr;
	unsigned int AbsCluNr;
	int clus_size;
	Fs_t *Fs = This->Fs;

	*res = 0;
	clus_size = Fs->cluster_size * Fs->sector_size;
	offset = where % clus_size;

	if (mode == MT_READ)
		maximize(*len, This->FileSize - where);
	if (*len == 0 )
		return 0;

	if (This->FirstAbsCluNr < 2){
		if( mode == MT_READ || *len == 0){
			*len = 0;
			return 0;
		}
		NewCluNr = get_next_free_cluster(This->Fs, 1);
		if (NewCluNr == 1 ){
			errno = ENOSPC;
			return -2;
		}
		hash_remove(filehash, (void *) This, This->hint);
		This->FirstAbsCluNr = NewCluNr;
		hash_add(filehash, (void *) This, &This->hint);
		fatAllocate(This->Fs, NewCluNr, Fs->end_fat);
	}

	RelCluNr = where / clus_size;
	
	if (RelCluNr >= This->PreviousRelCluNr){
		CurCluNr = This->PreviousRelCluNr;
		AbsCluNr = This->PreviousAbsCluNr;
	} else {
		CurCluNr = 0;
		AbsCluNr = This->FirstAbsCluNr;
	}


	NrClu = (offset + *len - 1) / clus_size;
	while (CurCluNr <= RelCluNr + NrClu){
		if (CurCluNr == RelCluNr){
			/* we have reached the beginning of our zone. Save
			 * coordinates */
			This->PreviousRelCluNr = RelCluNr;
			This->PreviousAbsCluNr = AbsCluNr;
		}
		NewCluNr = fatDecode(This->Fs, AbsCluNr);
		if (NewCluNr == 1 || NewCluNr == 0){
			fprintf(stderr,"Fat problem while decoding %d %x\n", 
				AbsCluNr, NewCluNr);
			exit(1);
		}
		if(CurCluNr == RelCluNr + NrClu)			
			break;
		if (NewCluNr > Fs->last_fat && mode == MT_WRITE){
			/* if at end, and writing, extend it */
			NewCluNr = get_next_free_cluster(This->Fs, AbsCluNr);
			if (NewCluNr == 1 ){ /* no more space */
				errno = ENOSPC;
				return -2;
			}
			fatAppend(This->Fs, AbsCluNr, NewCluNr);
		}

		if (CurCluNr < RelCluNr && NewCluNr > Fs->last_fat){
			*len = 0;
			return 0;
		}

		if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1)
			break;
		CurCluNr++;
		AbsCluNr = NewCluNr;
		if(loopDetect(This, CurCluNr, AbsCluNr)) {
			errno = EIO;
			return -2;
		}
	}

	maximize(*len, (1 + CurCluNr - RelCluNr) * clus_size - offset);
	
	end = where + *len;
	if(batchmode && mode == MT_WRITE && end >= This->FileSize) {
		*len += ROUND_UP(end, clus_size) - end;
	}

	if((*len + offset) / clus_size + This->PreviousAbsCluNr-2 >
		Fs->num_clus) {
		fprintf(stderr, "cluster too big\n");
		exit(1);
	}

	*res = sectorsToBytes((Stream_t*)Fs, 
						  (This->PreviousAbsCluNr-2) * Fs->cluster_size +
						  Fs->clus_start) + offset;
	return 1;
}
Ejemplo n.º 5
0
void mbadblocks(int argc, char **argv, int type)
{
	unsigned int i;
	unsigned int startSector=2;
	unsigned int endSector=0;
	struct MainParam_t mp;
	Fs_t *Fs;
	Stream_t *Dir;
	int ret;
	char *filename = NULL;
	char c;
	unsigned int badClus;
	int sectorMode=0;
	int writeMode=0;

	while ((c = getopt(argc, argv, "i:s:cwS:E:")) != EOF) {
		switch(c) {
		case 'i':
			set_cmd_line_image(optarg, 0);
			break;
		case 'c':
			checkListTwice(filename);
			filename = strdup(optarg);
			break;
		case 's':
			checkListTwice(filename);
			filename = strdup(optarg);
			sectorMode = 1;
			break;
		case 'S':
			startSector = atol(optarg); 
			break;
		case 'E':
			endSector = atol(optarg); 
			break;
		case 'w':
			writeMode = 1;
			break;
		case 'h':
			usage(0);
		default:
			usage(1);
		}
	}

	if (argc != optind+1 ||
	    !argv[optind][0] || argv[optind][1] != ':' || argv[optind][2]) {
		usage(1);
	}

	init_mp(&mp);

	Dir = open_root_dir(argv[optind][0], O_RDWR, NULL);
	if (!Dir) {
		fprintf(stderr,"%s: Cannot initialize drive\n", argv[0]);
		exit(1);
	}

	Fs = (Fs_t *)GetFs(Dir);
	in_len = Fs->cluster_size * Fs->sector_size;
	in_buf = malloc(in_len);
	if(!in_buf) {
		printOom();
		ret = 1;
		goto exit_0;
	}
	if(writeMode) {
		int i;
		pat_buf=malloc(in_len * N_PATTERN);
		if(!pat_buf) {
			printOom();
			ret = 1;
			goto exit_0;
		}
		srandom(time(NULL));
		for(i=0; i < in_len * N_PATTERN; i++) {
			pat_buf[i] = random();
		}
	}
	for(i=0; i < Fs->clus_start; i++ ){
		ret = READS(Fs->Next, in_buf, 
			    sectorsToBytes((Stream_t*)Fs, i), Fs->sector_size);
		if( ret < 0 ){
			perror("early error");
			goto exit_0;
		}
		if(ret < (signed int) Fs->sector_size){
			fprintf(stderr,"end of file in file_read\n");
			ret = 1;
			goto exit_0;
		}
	}
	ret = 0;

	badClus = Fs->last_fat + 1;

	if(startSector < 2)
		startSector = 2;
	if(endSector > Fs->num_clus + 2 || endSector <= 0) 
		endSector = Fs->num_clus + 2;

	if(filename) {
		char line[80];

		FILE *f = fopen(filename, "r");
		if(f == NULL) {
			fprintf(stderr, "Could not open %s (%s)\n",
				filename, strerror(errno));
			ret = 1;
			goto exit_0;
		}
		while(fgets(line, sizeof(line), f)) {
			char *ptr = line + strspn(line, " \t");
			long offset = strtoul(ptr, 0, 0);
			if(sectorMode)
				offset = (offset-Fs->clus_start)/Fs->cluster_size + 2;
			if(offset < 2) {
				fprintf(stderr, "Sector before start\n");
			} else if(offset >= Fs->num_clus) {
				fprintf(stderr, "Sector beyond end\n");
			} else {
				mark(Fs, offset, badClus);
				ret = 1;
			}
		}
	} else {
		Stream_t *dev;
		dev = Fs->Next;
		if(dev->Next)
			dev = dev->Next;

		in_len = Fs->cluster_size * Fs->sector_size;
		if(writeMode) {
			/* Write pattern */
			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, 
					    pat_buf + in_len * (i % N_PATTERN),
					    1);
			}

			/* Flush cache, so that we are sure we read the data
			   back from disk, rather than from the cache */
			if(!got_signal)
				DISCARD(dev);

			/* Read data back, and compare to pattern */
			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, 
					    pat_buf + in_len * (i % N_PATTERN),
					    0);
			}

		} else {

			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, NULL, 0);
			}
		}
	}
 exit_0:
	FREE(&Dir);
	exit(ret);
}