diff --git a/include/disk_io.h b/include/disk_io.h index 266b9eb1..749e7c9b 100644 --- a/include/disk_io.h +++ b/include/disk_io.h @@ -1,7 +1,7 @@ /* * disk_io.h - Exports for disk io. Part of the Linux-NTFS project. * - * Copyright (c) 2000-2002 Anton Altaparmakov + * Copyright (c) 2000-2003 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -37,5 +37,7 @@ extern s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, extern s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn, const s64 count, const void *b); +extern s64 ntfs_device_size_get(int f, int block_size); + #endif /* defined _NTFS_DISK_IO_H */ diff --git a/libntfs/disk_io.c b/libntfs/disk_io.c index c6dc7235..63cd7933 100644 --- a/libntfs/disk_io.c +++ b/libntfs/disk_io.c @@ -1,7 +1,7 @@ /* * disk_io.c - Disk io functions. Part of the Linux-NTFS project. * - * Copyright (c) 2000-2002 Anton Altaparmakov + * Copyright (c) 2000-2003 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -19,17 +19,27 @@ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "config.h" + #include #include #include #include #include +#ifdef HAVE_LINUX_FD_H +# include +# include +#endif #include "types.h" #include "disk_io.h" #include "mst.h" #include "debug.h" +#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE) +# define BLKGETSIZE _IO(0x12,96) /* Get device size in 512byte blocks. */ +#endif + /** * ntfs_pread - positioned read from disk * @fd: file descriptor to read from @@ -332,3 +342,73 @@ s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn, return bw >> vol->cluster_size_bits; } +/** + * ntfs_device_offset_valid - test if a device offset is valid + * @f: open file descriptor of device + * @ofs: offset to test for validity + * + * Test if the offset @ofs is an existing location on the device described + * by the open file descriptor @f. + * + * Return 0 if it is valid and -1 if it is not valid. + */ +static inline int ntfs_device_offset_valid(int f, s64 ofs) +{ + char ch; + + if (lseek(f, ofs, SEEK_SET) >= 0 && read(f, &ch, 1) == 1) + return 0; + return -1; +} + +/** + * ntfs_device_size_get - return the size of a device in blocks + * @f: open file descriptor of device + * @block_size: block size in bytes in which to return the result + * + * Return the number of @block_size sized blocks in the device described by the + * open file descriptor @f. + * + * Adapted from e2fsutils-1.19, Copyright (C) 1995 Theodore Ts'o. + */ +s64 ntfs_device_size_get(int f, int block_size) +{ + s64 high, low; +#ifdef BLKGETSIZE + long size; + + if (ioctl(f, BLKGETSIZE, &size) >= 0) { + Dprintf("BLKGETSIZE nr 512 byte blocks = %ld (0x%ld)\n", size, + size); + return (s64)size * 512 / block_size; + } +#endif +#ifdef FDGETPRM + { struct floppy_struct this_floppy; + + if (ioctl(f, FDGETPRM, &this_floppy) >= 0) { + Dprintf("FDGETPRM nr 512 byte blocks = %ld (0x%ld)\n", + this_floppy.size, this_floppy.size); + return (s64)this_floppy.size * 512 / block_size; + } + } +#endif + /* + * We couldn't figure it out by using a specialized ioctl, + * so do binary search to find the size of the device. + */ + low = 0LL; + for (high = 1024LL; ntfs_device_offset_valid(f, high); high <<= 1) + low = high; + while (low < high - 1LL) { + const s64 mid = (low + high) / 2; + + if (ntfs_device_offset_valid(f, mid)) + low = mid; + else + high = mid; + } + lseek(f, 0LL, SEEK_SET); + return (low + 1LL) / block_size; +} + diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index fa8363fa..f723bbef 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -64,12 +64,8 @@ #ifdef HAVE_ERRNO_H # include #endif -#include -#ifdef HAVE_LINUX_FD_H -# include -# include -#endif #include +#include #ifdef HAVE_GETOPT_H # include #else @@ -90,10 +86,6 @@ #endif #include -#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE) -# define BLKGETSIZE _IO(0x12,96) /* Get device size in 512byte blocks. */ -#endif - #if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET) # define BLKSSZGET _IO(0x12,104) /* Get device sector size in bytse. */ #endif @@ -2407,59 +2399,6 @@ void mkntfs_exit(void) #define MAKE_MFT_REF(_ref, _seqno) cpu_to_le64((((u64)(_seqno)) << 48) \ | ((u64)(_ref))) -static inline int valid_offset(int f, long long ofs) -{ - char ch; - - if (lseek(f, ofs, SEEK_SET) >= 0 && read(f, &ch, 1) == 1) - return 1; - return 0; -} - -/* - * Returns the number of bs sized blocks in a partition. Adapted from - * e2fsutils-1.19, Copyright (C) 1995 Theodore Ts'o. - */ -long long get_device_size(int f, int bs) -{ - long long high, low; -#ifdef BLKGETSIZE - long size; - - if (ioctl(f, BLKGETSIZE, &size) >= 0) { - Dprintf("BLKGETSIZE nr 512 byte blocks = %ld (0x%ld)\n", size, - size); - return (long long)size * 512 / bs; - } -#endif -#ifdef FDGETPRM - { struct floppy_struct this_floppy; - - if (ioctl(f, FDGETPRM, &this_floppy) >= 0) { - Dprintf("FDGETPRM nr 512 byte blocks = %ld (0x%ld)\n", - this_floppy.size, this_floppy.size); - return (long long)this_floppy.size * 512 / bs; - } - } -#endif - /* - * We couldn't figure it out by using a specialized ioctl, - * so do binary search to find the size of the partition. - */ - low = 0LL; - for (high = 1024LL; valid_offset(f, high); high <<= 1) - low = high; - while (low < high - 1LL) { - const long long mid = (low + high) / 2; - - if (valid_offset(f, mid)) - low = mid; - else - high = mid; - } - lseek(f, 0LL, SEEK_SET); - return (low + 1LL) / bs; -} int main(int argc, char **argv) { @@ -2612,10 +2551,11 @@ int main(int argc, char **argv) Dprintf("sector size = %i bytes\n", opt.sector_size); /* If user didn't specify the number of sectors, determine it now. */ if (!opt.nr_sectors) { - opt.nr_sectors = get_device_size(vol->fd, opt.sector_size); + opt.nr_sectors = ntfs_device_size_get(vol->fd, opt.sector_size); if (opt.nr_sectors <= 0) - err_exit("get_device_size(%s) failed. Please specify " - "it manually.\n", vol->dev_name); + err_exit("ntfs_device_size_get(%s) failed. Please " + "specify it manually.\n", + vol->dev_name); } Dprintf("number of sectors = %Ld (0x%Lx)\n", opt.nr_sectors, opt.nr_sectors);