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); }
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); }
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); }
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; }
/* * 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; }
// 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); }
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; }
/* * 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; }
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; }
/* * 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; }
void set_valid(jint value) { int_field_put(valid_offset(), value); }
jint valid() const { return int_field(valid_offset()); }