ports/84048: sysutils/ntfsprogs: partition device access
requires 512 byte size
John Merryweather Cooper
john_m_cooper at yahoo.com
Mon Jul 25 15:06:40 GMT 2005
Andriy Gapon wrote:
>>Number: 84048
>>Category: ports
>>Synopsis: sysutils/ntfsprogs: partition device access requires 512 byte size
>>Confidential: no
>>Severity: serious
>>Priority: medium
>>Responsible: freebsd-ports-bugs
>>State: open
>>Quarter:
>>Keywords:
>>Date-Required:
>>Class: sw-bug
>>Submitter-Id: current-users
>>Arrival-Date: Mon Jul 25 10:40:07 GMT 2005
>>Closed-Date:
>>Last-Modified:
>>Originator: Andriy Gapon
>>Release: FreeBSD 5.4-RELEASE-p3 i386
>>Organization:
>>Environment:
>>
>>
>System: FreeBSD 5.4-RELEASE-p3 i386
>ntfsprogs-1.9.4_1
>
>
>
>
>
>>Description:
>>
>>
>I unsuccessfully tried to use ntfsresize program from this port. ntfsresize -i
>was failing early in its run, during verification of "device size" i.e.
>read access to the whole partition that hosted ntfs. The error was EINVAL.
>Apparently the problem is that freebsd partition devices (e.g. ad0s2) allow
>read/write operations only for sizes that are multiple of sector size. E.g.:
>$ dd if=/dev/ad0s1e of=/dev/null bs=1 count=1
>dd: /dev/ad0s1e: Invalid argument
>0+0 records in
>0+0 records out
>0 bytes transferred in 0.000099 secs (0 bytes/sec)
>$ dd if=/dev/ad0s1e of=/dev/null bs=512 count=1
>1+0 records in
>1+0 records out
>512 bytes transferred in 0.008678 secs (59000 bytes/sec)
>
>To make ntfsresize work on FreeBSD I had to change all read/write calls to use
>n*512 byte counts.
>
>The patches to ntfsclone.c and device.c are trivial - 1 byte was read to check
>accessibility of a certain offset; 512 bytes are read now instead.
>attrib.c patch works as follows: certain data structure is read from disk, its
>size may be not multiple of 512, so we round up size before reading, but we
>use actual size for bytes read.
>ntfsresize.c: certain data structure needs to be written to disk, there is
>a certian algorithm for calculating its size, the result may be not 512*n,
>so we round it up.
>
>Probably there are other palces in the code that are affected by the same
>restricition.
>
>
>
>>How-To-Repeat:
>>
>>
>
>try to use ntfsresize -i on ntfs partition
>
>
>
>>Fix:
>>
>>
>
>
>
>--- 512.patch begins here ---
>--- libntfs/attrib.c Sat Sep 4 13:16:32 2004
>+++ libntfs/attrib.c Fri Jul 22 01:05:09 2005
>@@ -709,9 +709,9 @@
> */
> s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
> {
>- s64 br, to_read, ofs, total, total2;
>+ s64 br, old_to_read, to_read, ofs, total, total2;
> ntfs_volume *vol;
> runlist_element *rl;
>
> Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, "
> "count 0x%llx.\n", __FUNCTION__,
>@@ -741,6 +744,7 @@
> if (pos + count > na->data_size) {
> if (pos >= na->data_size)
> return 0;
>+ Dprintf("trunacting read pos=%lld, na->data_size=%lld, (old) count=%lld\n", pos, na->data_size, count);
> count = na->data_size - pos;
> }
> vol = na->ni->vol;
>@@ -820,6 +825,10 @@
> /* It is a real lcn, read it into @dst. */
> to_read = min(count, (rl->length << vol->cluster_size_bits) -
> ofs);
>+ old_to_read = to_read;
>+ to_read = (to_read + 511) / 512 * 512;
>+ if(old_to_read != to_read)
>+ Dprintf("adjusted %lld->%lld\n", old_to_read, to_read);
> retry:
> Dprintf("%s(): Reading 0x%llx bytes from vcn 0x%llx, lcn 0x%llx, "
> "ofs 0x%llx.\n", __FUNCTION__, to_read,
>@@ -828,6 +837,8 @@
> ofs, to_read, b);
> /* If everything ok, update progress counters and continue. */
> if (br > 0) {
>+ if(br > old_to_read)
>+ br = old_to_read;
> total += br;
> count -= br;
> b = (u8*)b + br;
>--- libntfs/device.c Sat Sep 4 13:16:32 2004
>+++ libntfs/device.c Mon Jul 11 23:27:55 2005
>@@ -441,10 +441,10 @@
> */
> static inline int ntfs_device_offset_valid(struct ntfs_device *dev, s64 ofs)
> {
>- char ch;
>+ char ch[512];
>
> if (dev->d_ops->seek(dev, ofs, SEEK_SET) >= 0 &&
>- dev->d_ops->read(dev, &ch, 1) == 1)
>+ dev->d_ops->read(dev, &ch, 512) > 0)
> return 0;
> return -1;
> }
>--- ntfsprogs/ntfsclone.c Mon Jul 25 12:31:30 2005
>+++ ntfsprogs/ntfsclone.c Mon Jul 25 12:33:32 2005
>@@ -1080,9 +1080,9 @@
>
> static int device_offset_valid(int fd, s64 ofs)
> {
>- char ch;
>+ char ch[512];
>
>- if (lseek(fd, ofs, SEEK_SET) >= 0 && read(fd, &ch, 1) == 1)
>+ if (lseek(fd, ofs, SEEK_SET) >= 0 && read(fd, &ch, 512) > 0)
> return 0;
> return -1;
> }
>--- ntfsprogs/ntfsresize.c Sat Sep 4 13:16:32 2004
>+++ ntfsprogs/ntfsresize.c Tue Jul 12 01:15:30 2005
>@@ -1783,6 +1783,10 @@
>
> nr_clusters = resize->new_volume_size;
> bm_bsize = nr_clusters_to_bitmap_byte_size(nr_clusters);
>+ if(bm_bsize % 512 != 0) {
>+ Dprintf("adjusted bm_bsize: %lld->%lld\n", bm_bsize, (bm_bsize + 511) / 512 * 512);
>+ bm_bsize = (bm_bsize + 511) / 512 * 512;
>+ }
> nr_bm_clusters = rounded_up_division(bm_bsize, vol->cluster_size);
>
> if (!(tmp = (u8 *)realloc(resize->lcn_bitmap.bm, bm_bsize)))
>--- 512.patch ends here ---
>
>
>
>
>>Release-Note:
>>Audit-Trail:
>>Unformatted:
>>
>>
>_______________________________________________
>freebsd-ports-bugs at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-ports-bugs
>To unsubscribe, send any mail to "freebsd-ports-bugs-unsubscribe at freebsd.org"
>
>
>
While we're at it, if the GNOMEVFS2 option is selected, the build fails
as follows:
"/usr/ports/Mk/bsd.gnome.mk", line 598: Malformed conditional
(${_USE_GNOME_ALL:Mgnomevfs2}=="")
"/usr/ports/Mk/bsd.port.mk", line 5234: if-less endif
make: fatal errors encountered -- cannot continue
*** Error code 1
Looks like some of the code in bsd.gnome.mk got a little side-ways in a
recent commit.
jmc
More information about the freebsd-gnome
mailing list