示例#1
0
Integer FATR eaf_write_(Integer *fd, double *offset, const void *buf, 
           Integer *bytes)
{
    if (!valid_offset(*offset)) return EAF_ERR_NONINTEGER_OFFSET;
    return (Integer) EAF_Write((int) *fd, (eaf_off_t) *offset, buf, 
                   (size_t) *bytes);
}
示例#2
0
static int find_size(int fd)
{
    unsigned int high, low;

    low = 0;
    for (high = 1; high > 0 && valid_offset(fd, high); high *= 2)
        low = high;
    while (low < high - 1) {
        const int mid = (low + high) / 2;

        if (valid_offset(fd, mid))
            low = mid;
        else
            high = mid;
    }
    return (low + 1);
}
示例#3
0
static int
count_blocks (int fd) {
	int high, low;

	low = 0;
	for (high = 1; valid_offset (fd, high); high *= 2)
		low = high;
	while (low < high - 1)
	{
		const int mid = (low + high) / 2;

		if (valid_offset (fd, mid))
			low = mid;
		else
			high = mid;
	}
	valid_offset (fd, 0);
	return (low + 1);
}
示例#4
0
Integer FATR eaf_aread_(Integer *fd, double *offset, void *buf, 
            Integer *bytes, Integer *req_id)
{
    int req, status;

    if (!valid_offset(*offset)) return EAF_ERR_NONINTEGER_OFFSET;
    status = EAF_Aread((int) *fd, (eaf_off_t) *offset, buf, 
               (size_t) *bytes, &req);
    *req_id = (Integer) req;
    return (Integer) status;
}
示例#5
0
/*
 * Returns the number of bytes in a partition
 */
blkid_loff_t blkid_get_dev_size(int fd)
{
	int valid_blkgetsize64 = 1;
#ifdef __linux__
	struct 		utsname ut;
#endif
	unsigned long long size64;
	unsigned long size;
	blkid_loff_t high, low;
#ifdef FDGETPRM
	struct floppy_struct this_floppy;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
	int part = -1;
	struct disklabel lab;
	struct partition *pp;
	char ch;
	struct stat st;
#endif /* HAVE_SYS_DISKLABEL_H */

#ifdef DKIOCGETBLOCKCOUNT	/* For Apple Darwin */
	if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
		if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
		    && (size64 << 9 > 0xFFFFFFFF))
			return 0; /* EFBIG */
		return (blkid_loff_t) size64 << 9;
	}
#endif

#ifdef BLKGETSIZE64
#ifdef __linux__
	if ((uname(&ut) == 0) &&
	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&
	     (ut.release[2] < '6') && (ut.release[3] == '.')))
		valid_blkgetsize64 = 0;
#endif
	if (valid_blkgetsize64 &&
	    ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
		if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
		    && ((size64) > 0xFFFFFFFF))
			return 0; /* EFBIG */
		return size64;
	}
#endif

#ifdef BLKGETSIZE
	if (ioctl(fd, BLKGETSIZE, &size) >= 0)
		return (blkid_loff_t)size << 9;
#endif

/* tested on FreeBSD 6.1-RELEASE i386 */
#ifdef DIOCGMEDIASIZE
	if (ioctl(fd, DIOCGMEDIASIZE, &size64) >= 0)
		return (off_t)size64;
#endif /* DIOCGMEDIASIZE */

#ifdef FDGETPRM
	if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
		return (blkid_loff_t)this_floppy.size << 9;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
	/*
	 * This code works for FreeBSD 4.11 i386, except for the full device
	 * (such as /dev/ad0). It doesn't work properly for newer FreeBSD
	 * though. FreeBSD >= 5.0 should be covered by the DIOCGMEDIASIZE
	 * above however.
	 *
	 * Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw,
	 * character) devices, so we need to check for S_ISCHR, too.
	 */
	if ((fstat(fd, &st) >= 0) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
		part = st.st_rdev & 7;
	if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
		pp = &lab.d_partitions[part];
		if (pp->p_size)
			return pp->p_size << 9;
	}
#endif /* HAVE_SYS_DISKLABEL_H */
	{
#ifdef HAVE_FSTAT64
		struct stat64   st;
		if (fstat64(fd, &st) == 0)
#else
		struct stat	st;
		if (fstat(fd, &st) == 0)
#endif
			if (S_ISREG(st.st_mode))
				return st.st_size;
	}


	/*
	 * OK, we couldn't figure it out by using a specialized ioctl,
	 * which is generally the best way.  So do binary search to
	 * find the size of the partition.
	 */
	low = 0;
	for (high = 1024; valid_offset(fd, high); high *= 2)
		low = high;
	while (low < high - 1)
	{
		const blkid_loff_t mid = (low + high) / 2;

		if (valid_offset(fd, mid))
			low = mid;
		else
			high = mid;
	}
	return low + 1;
}
示例#6
0
  // Return the remaining size, in bytes, of an open file stream. On
  // error, return -1.  Handling raw device files is substantially more
  // complicated than image files.  For Linux, an ioctl() is used.  For
  // other operating systems, a "binary search" technique similar to
  // that in e2fsprogs getsize.c is used.
  long long measureOpenFile(FILE * f, struct scalpelState *state) {

    unsigned long long total = 0, original = ftello(f);
    int descriptor = 0;
    struct stat *info;
    unsigned long long numsectors = 0;

    if((fseeko(f, 0, SEEK_END))) {
      if(state->modeVerbose) {
	fprintf(stdout, "fseeko() call failed on image file.\n");
	fprintf(stdout, "Diagnosis: %s\n", strerror(errno));
      }
      return -1;
    }
    total = ftello(f);

    // for block devices (e.g., raw disk devices), calculating size by 
    // seeking the end of the opened stream doesn't work.  For Linux, we use 
    // an ioctl() call.  For others (e.g., OS X), we use binary search.

    // is it a block device?
    descriptor = fileno(f);
    info = (struct stat *)malloc(sizeof(struct stat));
    checkMemoryAllocation(state, info, __LINE__, __FILE__, "info");
    fstat(descriptor, info);
    if(S_ISBLK(info->st_mode)) {

#if defined (__linux)
      if(ioctl(descriptor, BLKGETSIZE, &numsectors) < 0) {
	if(state->modeVerbose) {
	  fprintf(stdout, "Using ioctl() call to measure block device size.\n");
	}
#if defined(__DEBUG)
	perror("BLKGETSIZE failed");
#endif
      }
#else // non-Linux, use binary search

      {
	unsigned long long low, high, mid;

	fprintf(stdout, "Using binary search to measure block device size.\n");
	low = 0;
	for(high = 512; valid_offset(descriptor, high); high *= 2) {
	  low = high;
	}

	while (low < high - 1) {
	  mid = (low + high) / 2;
	  if(valid_offset(descriptor, mid)) {
	    low = mid;
	  }
	  else {
	    high = mid;
	  }
	}
	numsectors = (low + 1) >> 9;
      }
#endif

      // assume device has 512 byte sectors
      total = numsectors * 512;

      free(info);

    }

    // restore file position

    if((fseeko(f, original, SEEK_SET))) {
      if(state->modeVerbose) {
	fprintf(stdout,
		"fseeko() call to restore file position failed on image file.\n");
      }
      return -1;
    }

    return (total - original);
  }
示例#7
0
Integer FATR eaf_read_(Integer *fd, double *offset, void *buf, Integer *bytes)
{
    if (!valid_offset(*offset)) return EAF_ERR_NONINTEGER_OFFSET;
    return (Integer) eaf_read((int) *fd, (eaf_off_t) *offset, buf, 
			      (size_t) *bytes);
}
int main(int argc, char *argv[]) {
    char * bytes_count_str = NULL;
    char * devname;
    reiserfs_filsys_t fs;
    struct reiserfs_super_block * rs;

    int c;
    int error;

    struct reiserfs_super_block *sb_old;

    unsigned long block_count_new;

    print_banner ("resize_reiserfs");

    while ((c = getopt(argc, argv, "fvcqs:")) != EOF) {
        switch (c) {
        case 's' :
            if (!optarg)
                die("%s: Missing argument to -s option", argv[0]);
            bytes_count_str = optarg;
            break;
        case 'f':
            opt_force = 1;
            break;
        case 'v':
            opt_verbose++;
            break;
        case 'n':
            /* no nowrite option at this moment */
            /* opt_nowrite = 1; */
            break;
        case 'c':
            opt_safe = 1;
            break;
        case 'q':
            opt_verbose = 0;
            break;
        default:
            print_usage_and_exit ();
        }
    }

    if (optind == argc )
        print_usage_and_exit();
    devname = argv[optind];

    fs = reiserfs_open(devname, O_RDONLY, &error, 0);
    if (!fs)
        die ("%s: can not open '%s': %s", argv[0], devname, strerror(error));

    if (no_reiserfs_found (fs)) {
        die ("resize_reiserfs: no reiserfs found on the device");
    }
    if (!spread_bitmaps (fs)) {
        die ("resize_reiserfs: cannot resize reiserfs in old (not spread bitmap) format.\n");
    }

    rs = fs->s_rs;

    if(bytes_count_str) {	/* new fs size is specified by user */
        block_count_new = calc_new_fs_size(rs_block_count(rs), fs->s_blocksize, bytes_count_str);
    } else {		/* use whole device */
        block_count_new = count_blocks(devname, fs->s_blocksize, -1);
    }

    if (is_mounted (devname)) {
        reiserfs_close(fs);
        return resize_fs_online(devname, block_count_new);
    }

    if (rs_state(rs) != REISERFS_VALID_FS)
        die ("%s: the file system isn't in valid state\n", argv[0]);

    if(!valid_offset(fs->s_dev, (loff_t) block_count_new * fs->s_blocksize - 1))
        die ("%s: %s too small", argv[0], devname);

    sb_old = 0;		/* Needed to keep idiot compiler from issuing false warning */
    /* save SB for reporting */
    if(opt_verbose) {
        sb_old = getmem(SB_SIZE);
        memcpy(sb_old, SB_DISK_SUPER_BLOCK(fs), SB_SIZE);
    }

    if (block_count_new == SB_BLOCK_COUNT(fs))
        die ("%s: Calculated fs size is the same as the previous one.", argv[0]);

    if (block_count_new > SB_BLOCK_COUNT(fs))
        expand_fs(fs, block_count_new);
    else
        shrink_fs(fs, block_count_new);

    if(opt_verbose) {
        sb_report(rs, sb_old);
        freemem(sb_old);
    }

    set_state (rs, REISERFS_VALID_FS);
    bwrite_cond(SB_BUFFER_WITH_SB(fs));

    if (opt_verbose) {
        printf("\nSyncing..");
        fflush(stdout);
    }
    reiserfs_close (fs);
    if (opt_verbose)
        printf("done\n");

    return 0;
}
示例#9
0
/*
 * Returns the number of blocks in a partition
 */
blkid_loff_t blkid_get_dev_size(int fd)
{
	int valid_blkgetsize64 = 1;
#ifdef __linux__
	struct 		utsname ut;
#endif
	unsigned long long size64;
	unsigned long size;
	blkid_loff_t high, low;
#ifdef FDGETPRM
	struct floppy_struct this_floppy;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
	int part = -1;
	struct disklabel lab;
	struct partition *pp;
	char ch;
	struct stat st;
#endif /* HAVE_SYS_DISKLABEL_H */

#ifdef DKIOCGETBLOCKCOUNT	/* For Apple Darwin */
	if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
		if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
		    && (size64 << 9 > 0xFFFFFFFF))
			return 0; /* EFBIG */
		return (blkid_loff_t) size64 << 9;
	}
#endif

#ifdef BLKGETSIZE64
#ifdef __linux__
	if ((uname(&ut) == 0) &&
	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&
	     (ut.release[2] < '6') && (ut.release[3] == '.')))
		valid_blkgetsize64 = 0;
#endif
	if (valid_blkgetsize64 &&
	    ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
		if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
		    && ((size64) > 0xFFFFFFFF))
			return 0; /* EFBIG */
		return size64;
	}
#endif

#ifdef BLKGETSIZE
	if (ioctl(fd, BLKGETSIZE, &size) >= 0)
		return (blkid_loff_t)size << 9;
#endif

#ifdef FDGETPRM
	if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
		return (blkid_loff_t)this_floppy.size << 9;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
#if 0
	/*
	 * This should work in theory but I haven't tested it.  Anyone
	 * on a BSD system want to test this for me?  In the meantime,
	 * binary search mechanism should work just fine.
	 */
	if ((fstat(fd, &st) >= 0) && S_ISBLK(st.st_mode))
		part = st.st_rdev & 7;
	if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
		pp = &lab.d_partitions[part];
		if (pp->p_size)
			return pp->p_size << 9;
	}
#endif
#endif /* HAVE_SYS_DISKLABEL_H */

	/*
	 * OK, we couldn't figure it out by using a specialized ioctl,
	 * which is generally the best way.  So do binary search to
	 * find the size of the partition.
	 */
	low = 0;
	for (high = 1024; valid_offset(fd, high); high *= 2)
		low = high;
	while (low < high - 1)
	{
		const blkid_loff_t mid = (low + high) / 2;

		if (valid_offset(fd, mid))
			low = mid;
		else
			high = mid;
	}
	return low + 1;
}
示例#10
0
int main(int argc, char *argv[]) {
	char * bytes_count_str = NULL;
	char * devname;
	struct stat statbuf;
	int c;

	int dev;
	struct reiserfs_super_block *sb, *sb_old;
	
	while ((c = getopt(argc, argv, "fvcqs:")) != EOF) {
		switch (c) {
		case 's' :
			  if (!optarg) 
				  die("%s: Missing argument to -s option", argv[0]);		
			  bytes_count_str = optarg;
			  break;
		case 'f':
		    opt_force = 1;
		    break;		 
		case 'v':
			opt_verbose++; 
			break;
		case 'n':
			/* no nowrite option at this moment */
			/* opt_nowrite = 1; */
			break;
		case 'c':
			opt_safe = 1;
			break;
		case 'q':
			opt_verbose = 0;
			break;
		default:
			print_usage_and_exit ();
		}
	}

	if (optind == argc || (!bytes_count_str))
		print_usage_and_exit();
	devname = argv[optind];

	/* open_device will die if it could not open device */
	dev = open (devname, O_RDWR);
	if (dev == -1)
		die ("%s: can not open '%s': %s", argv[0], devname, strerror (errno));

	if (fstat (dev, &statbuf) < 0)
		die ("%s: unable to stat %s", argv[0], devname);
  
	if (!S_ISBLK (statbuf.st_mode) && opt_force )
		die ("%s: '%s (%o)' is not a block device", 
			 argv[0], devname, statbuf.st_mode);

	read_superblock(dev);
	
	sb = (struct reiserfs_super_block *) g_sb_bh->b_data;
	g_block_count_new = calc_new_fs_size(sb->s_block_count,
					     sb->s_blocksize, bytes_count_str);
	if (is_mounted (devname)) {
		close(dev);
		if (!opt_force) 
	    	die ("%s: '%s' contains a mounted file system,\n"
			     "\tspecify -f option to resize the fs online\n", 
				 argv[0], devname);
		resize_fs_online(devname, g_block_count_new);
		return 0;
	}	

	if (sb->s_state != REISERFS_VALID_FS) 
		die ("%s: the file system isn't in valid state\n", argv[0]);
		
	if(!valid_offset(dev, (loff_t) g_block_count_new * sb->s_blocksize - 1))
		die ("%s: %s too small", argv[0], devname);

	sb_old = 0;		/* Needed to keep idiot compiler from issuing false warning */
	/* save SB for reporting */
	if(opt_verbose) {
		sb_old = getmem(sizeof(struct reiserfs_super_block));
		memcpy(sb_old, sb, sizeof(struct reiserfs_super_block));
    }

	if (g_block_count_new == sb->s_block_count) 
		die ("%s: Calculated fs size is the same as the previous one.",
			 argv[0]);
	if (g_block_count_new > sb->s_block_count) 
		expand_fs();
	else
		shrink_fs(g_block_count_new);

	if(opt_verbose) {
		sb_report(sb, sb_old);
		freemem(sb_old);
	}

	check_and_free_mem ();		
	
	if (opt_verbose) {
		printf("\nSyncing..");
		fflush(stdout);
	}
	fsync (dev);
	if (opt_verbose)
		printf("done\n");
	

	close(dev);
	
	return 0;
}
示例#11
0
文件: getsize.c 项目: crossmeta/linux
/*
 * Returns the number of blocks in a partition
 */
errcode_t ext2fs_get_device_size(const char *file, int blocksize,
				 blk_t *retblocks)
{
	int	fd;
#ifdef BLKGETSIZE
	unsigned long	size;
#endif
	ext2_loff_t high, low;
#ifdef FDGETPRM
	struct floppy_struct this_floppy;
#endif
#ifdef HAVE_SYS_DISKLABEL_H
	int part;
	struct disklabel lab;
	struct partition *pp;
	char ch;
#endif /* HAVE_SYS_DISKLABEL_H */

#ifdef HAVE_OPEN64
	fd = open64(file, O_RDONLY);
#else
	fd = open(file, O_RDONLY);
#endif
	if (fd < 0)
		return errno;

#ifdef BLKGETSIZE
	if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
		close(fd);
		*retblocks = size / (blocksize / 512);
		return 0;
	}
#endif
#ifdef FDGETPRM
	if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
		close(fd);
		*retblocks = this_floppy.size / (blocksize / 512);
		return 0;
	}
#endif
#ifdef HAVE_SYS_DISKLABEL_H
	part = strlen(file) - 1;
	if (part >= 0) {
		ch = file[part];
		if (isdigit(ch))
			part = 0;
		else if (ch >= 'a' && ch <= 'h')
			part = ch - 'a';
		else
			part = -1;
	}
	if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
		pp = &lab.d_partitions[part];
		if (pp->p_size) {
			close(fd);
			*retblocks = pp->p_size / (blocksize / 512);
			return 0;
		}
	}
#endif /* HAVE_SYS_DISKLABEL_H */

	/*
	 * OK, we couldn't figure it out by using a specialized ioctl,
	 * which is generally the best way.  So do binary search to
	 * find the size of the partition.
	 */
	low = 0;
	for (high = 1024; valid_offset (fd, high); high *= 2)
		low = high;
	while (low < high - 1)
	{
		const ext2_loff_t mid = (low + high) / 2;

		if (valid_offset (fd, mid))
			low = mid;
		else
			high = mid;
	}
	valid_offset (fd, 0);
	close(fd);
	*retblocks = (low + 1) / blocksize;
	return 0;
}
示例#12
0
 void set_valid(jint value) {
   int_field_put(valid_offset(), value);
 }
示例#13
0
 jint valid() const {
   return int_field(valid_offset());
 }