1
0
mirror of https://git.FreeBSD.org/ports.git synced 2025-01-23 09:10:43 +00:00

- Fix mkntfs by providing device io module that always reads/write

blocksize-aligned blocks
- Remove several now unnecessary hacks
- Bump PORTREVISION

Approved by:	MAINTAINER
This commit is contained in:
Max Khon 2006-12-13 17:03:02 +00:00
parent 6781af104d
commit 92167387a1
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=179674
6 changed files with 609 additions and 84 deletions

View File

@ -7,6 +7,7 @@
PORTNAME= ntfsprogs
PORTVERSION= 1.13.1
PORTREVISION= 1
CATEGORIES= sysutils
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
MASTER_SITE_SUBDIR= linux-ntfs
@ -76,5 +77,6 @@ post-patch:
's|$$(libdir)/\(gnome-vfs-2.0/modules\)|${X11BASE}/lib/\1|; \
s|$$(sysconfdir)/\(gnome-vfs-2.0/modules\)|${X11BASE}/etc/\1|' \
${WRKSRC}/libntfs/Makefile.in
@${CP} ${FILESDIR}/unix_io_raw.c ${WRKSRC}/libntfs
.include <bsd.port.post.mk>

View File

@ -1,39 +0,0 @@
--- libntfs/attrib.c.orig Fri Feb 24 10:17:49 2006
+++ libntfs/attrib.c Thu May 4 04:44:07 2006
@@ -763,7 +763,7 @@
*/
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;
@@ -799,6 +799,7 @@
if (pos + count > na->data_size) {
if (pos >= na->data_size)
return 0;
+ ntfs_log_trace("trunacting read pos=%lld, na->data_size=%lld, (old) count=%lld\n", pos, na->data_size, count);
count = na->data_size - pos;
}
/* If it is a resident attribute, get the value from the mft record. */
@@ -887,6 +888,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)
+ ntfs_log_trace("adjusted %lld->%lld\n", old_to_read, to_read);
retry:
ntfs_log_trace("Reading 0x%llx bytes from vcn 0x%llx, lcn 0x%llx, "
"ofs 0x%llx.\n", to_read, rl->vcn, rl->lcn, ofs);
@@ -894,6 +899,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;

View File

@ -1,15 +0,0 @@
--- 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;
}

View File

@ -0,0 +1,14 @@
--- libntfs/device_io.c.orig Wed Dec 6 03:57:01 2006
+++ libntfs/device_io.c Wed Dec 6 03:05:24 2006
@@ -26,7 +26,11 @@
#ifndef __CYGWIN32__
/* Not on Cygwin; use standard Unix style low level device operations. */
+#if defined(__FreeBSD__)
+#include "unix_io_raw.c"
+#else
#include "unix_io.c"
+#endif
#else /* __CYGWIN32__ */

View File

@ -1,30 +0,0 @@
--- libntfs/unix_io.c.orig Sat Feb 4 03:42:15 2006
+++ libntfs/unix_io.c Thu May 4 03:59:59 2006
@@ -110,6 +110,7 @@
flk.l_type = F_WRLCK;
flk.l_whence = SEEK_SET;
flk.l_start = flk.l_len = 0LL;
+#if 0
if (fcntl(DEV_FD(dev), F_SETLK, &flk)) {
err = errno;
ntfs_log_debug("ntfs_device_unix_io_open: Could not lock %s for %s\n",
@@ -119,6 +120,7 @@
"close %s", dev->d_name);
goto err_out;
}
+#endif
/* Determine if device is a block device or not, ignoring errors. */
if (!fstat(DEV_FD(dev), &sbuf) && S_ISBLK(sbuf.st_mode))
NDevSetBlock(dev);
@@ -155,9 +157,11 @@
flk.l_type = F_UNLCK;
flk.l_whence = SEEK_SET;
flk.l_start = flk.l_len = 0LL;
+#if 0
if (fcntl(DEV_FD(dev), F_SETLK, &flk))
ntfs_log_perror("ntfs_device_unix_io_close: Warning: Could not "
"unlock %s", dev->d_name);
+#endif
/* Close the file descriptor and clear our open flag. */
if (close(DEV_FD(dev)))
return -1;

View File

@ -0,0 +1,593 @@
/**
* unix_io.c - Unix style disk io functions. Originated from the Linux-NTFS project.
*
* Copyright (c) 2006 Max Khon
*
* 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
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the NTFS-3G
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_LINUX_FD_H
#include <linux/fd.h>
#endif
#include <sys/disk.h>
#include "types.h"
#include "mst.h"
#include "debug.h"
#include "device.h"
#include "logging.h"
typedef struct {
int fd;
s64 pos;
s32 block_size;
s64 media_size;
} unix_raw_fd;
#define DEV_FD(dev) (((unix_raw_fd *) dev->d_private))
#define RAW_IO_ALIGNED(dev, offset, count) \
(DEV_FD(dev)->block_size == 0 || \
((offset) % DEV_FD(dev)->block_size == 0 && \
(count) % DEV_FD(dev)->block_size == 0))
#define RAW_IO_ALIGN(dev, offset) \
((offset) / DEV_FD(dev)->block_size * DEV_FD(dev)->block_size)
#define RAW_IO_MAX_SIZE (128 * 1024 * 1024)
/* Define to nothing if not present on this system. */
#ifndef O_EXCL
# define O_EXCL 0
#endif
/**
* Get block_size and media_size
*/
static int
raw_io_get_size(struct ntfs_device *dev)
{
int bs;
off_t ms;
struct stat sb;
if (fstat(DEV_FD(dev)->fd, &sb) < 0) {
ntfs_log_perror("Failed to stat '%s'", dev->d_name);
return -1;
}
if (S_ISREG(sb.st_mode)) {
DEV_FD(dev)->media_size = sb.st_size;
ntfs_log_trace("%s: regular file (media_size %lld)\n",
dev->d_name, DEV_FD(dev)->media_size);
return 0;
}
if (ioctl(DEV_FD(dev)->fd, DIOCGSECTORSIZE, &bs) < 0) {
ntfs_log_perror("Failed to ioctl(DIOCGSECTORSIZE) '%s'",
dev->d_name);
return -1;
}
DEV_FD(dev)->block_size = bs;
ntfs_log_trace("%s: block size %d\n", dev->d_name, bs);
if (ioctl(DEV_FD(dev)->fd, DIOCGMEDIASIZE, &ms) < 0) {
ntfs_log_perror("Failed to ioctl(DIOCGMEDIASIZE) '%s'",
dev->d_name);
return -1;
}
DEV_FD(dev)->media_size = ms;
ntfs_log_trace("%s: media size %lld\n", dev->d_name, ms);
return 0;
}
/**
* Aligned read
*/
static ssize_t
raw_io_pread(struct ntfs_device *dev, char *buf, size_t count, s64 offset)
{
return pread(DEV_FD(dev)->fd, buf, count, offset);
}
/**
* Aligned write
*/
static ssize_t
raw_io_pwrite(struct ntfs_device *dev, const char *buf, size_t count, s64 offset)
{
return pwrite(DEV_FD(dev)->fd, buf, count, offset);
}
/**
* ntfs_device_unix_raw_io_open - Open a device and lock it exclusively
* @dev:
* @flags:
*
* Description...
*
* Returns:
*/
static int ntfs_device_unix_raw_io_open(struct ntfs_device *dev, int flags)
{
#if 0
struct flock flk;
#endif
struct stat sbuf;
int err;
if (NDevOpen(dev)) {
errno = EBUSY;
return -1;
}
if (stat(dev->d_name, &sbuf)) {
ntfs_log_perror("Failed to access '%s'", dev->d_name);
return -1;
}
if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
NDevSetBlock(dev);
dev->d_private = malloc(sizeof(unix_raw_fd));
if (!dev->d_private)
return -1;
DEV_FD(dev)->fd = -1;
DEV_FD(dev)->pos = 0;
DEV_FD(dev)->block_size = 0;
DEV_FD(dev)->media_size = 0;
/*
* Open file for exclusive access if mounting r/w.
* Fuseblk takes care about block devices.
*/
if (!NDevBlock(dev) && (flags & O_RDWR) == O_RDWR)
flags |= O_EXCL;
DEV_FD(dev)->fd = open(dev->d_name, flags);
if (DEV_FD(dev)->fd == -1) {
err = errno;
goto err_out;
}
if ((flags & O_RDWR) != O_RDWR)
NDevSetReadOnly(dev);
#if 0
memset(&flk, 0, sizeof(flk));
if (NDevReadOnly(dev))
flk.l_type = F_RDLCK;
else
flk.l_type = F_WRLCK;
flk.l_whence = SEEK_SET;
flk.l_start = flk.l_len = 0LL;
if (fcntl(DEV_FD(dev)->fd, F_SETLK, &flk)) {
err = errno;
ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ?
"read" : "write", dev->d_name);
if (close(DEV_FD(dev)->fd))
ntfs_log_perror("Failed to close '%s'", dev->d_name);
goto err_out;
}
#endif
if (raw_io_get_size(dev) < 0) {
err = errno;
close(DEV_FD(dev)->fd);
goto err_out;
}
NDevSetOpen(dev);
return 0;
err_out:
free(dev->d_private);
dev->d_private = NULL;
errno = err;
return -1;
}
/**
* ntfs_device_unix_raw_io_close - Close the device, releasing the lock
* @dev:
*
* Description...
*
* Returns:
*/
static int ntfs_device_unix_raw_io_close(struct ntfs_device *dev)
{
#if 0
struct flock flk;
#endif
if (!NDevOpen(dev)) {
errno = EBADF;
return -1;
}
if (NDevDirty(dev))
fsync(DEV_FD(dev)->fd);
#if 0
/* Release exclusive (mandatory) lock on the whole device. */
memset(&flk, 0, sizeof(flk));
flk.l_type = F_UNLCK;
flk.l_whence = SEEK_SET;
flk.l_start = flk.l_len = 0LL;
if (fcntl(DEV_FD(dev)->fd, F_SETLK, &flk))
ntfs_log_perror("ntfs_device_unix_raw_io_close: Warning: Could not "
"unlock %s", dev->d_name);
#endif
/* Close the file descriptor and clear our open flag. */
if (close(DEV_FD(dev)->fd))
return -1;
NDevClearOpen(dev);
free(dev->d_private);
dev->d_private = NULL;
return 0;
}
/**
* ntfs_device_unix_raw_io_seek - Seek to a place on the device
* @dev:
* @offset:
* @whence:
*
* Description...
*
* Returns:
*/
static s64 ntfs_device_unix_raw_io_seek(struct ntfs_device *dev, s64 offset,
int whence)
{
s64 abs_pos;
ntfs_log_trace("seek offset = 0x%llx, whence = %d.\n", offset, whence);
switch (whence) {
case SEEK_SET:
abs_pos = offset;
break;
case SEEK_CUR:
abs_pos = DEV_FD(dev)->pos + offset;
break;
case SEEK_END:
abs_pos = DEV_FD(dev)->media_size + offset;
break;
default:
ntfs_log_trace("Wrong mode %d.\n", whence);
errno = EINVAL;
return -1;
}
if (abs_pos < 0 || abs_pos > DEV_FD(dev)->media_size) {
ntfs_log_trace("Seeking outsize seekable area.\n");
errno = EINVAL;
return -1;
}
DEV_FD(dev)->pos = abs_pos;
return abs_pos;
}
/**
* ntfs_device_unix_raw_io_read - Read from the device, from the current location
* @dev:
* @buf:
* @count:
*
* Description...
*
* Returns:
*/
static s64 ntfs_device_unix_raw_io_read(struct ntfs_device *dev, void *buf,
s64 count)
{
s64 start, start_aligned;
s64 end, end_aligned;
size_t count_aligned;
char *buf_aligned;
ssize_t nr;
/* short-circuit for regular files */
start = DEV_FD(dev)->pos;
if (count > RAW_IO_MAX_SIZE)
count = RAW_IO_MAX_SIZE;
if (RAW_IO_ALIGNED(dev, start, count)) {
nr = raw_io_pread(dev, buf, count, start);
if (nr <= 0)
return nr;
DEV_FD(dev)->pos += nr;
return nr;
}
/*
* +- start_aligned +- end_aligned
* | |
* | +- start +- end |
* v v v v
* |----------|----------|----------|
* ^ ^
* +----- count ------+
* ^ ^
* +-------- count_aligned ---------+
*/
start_aligned = RAW_IO_ALIGN(dev, start);
end = start + count;
end_aligned = RAW_IO_ALIGN(dev, end) +
(RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_FD(dev)->block_size);
count_aligned = end_aligned - start_aligned;
ntfs_log_trace(
"%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n",
dev->d_name, count, count_aligned,
start, start_aligned, end, end_aligned);
/* allocate buffer */
buf_aligned = malloc(count_aligned);
if (buf_aligned == NULL) {
ntfs_log_trace("malloc(%d) failed\n", count_aligned);
return -1;
}
/* read aligned data */
nr = raw_io_pread(dev, buf_aligned, count_aligned, start_aligned);
if (nr == 0)
return 0;
if (nr < 0 || nr < start - start_aligned) {
free(buf_aligned);
return -1;
}
/* copy out */
memcpy(buf, buf_aligned + (start - start_aligned), count);
free(buf_aligned);
nr -= start - start_aligned;
if (nr > count)
nr = count;
DEV_FD(dev)->pos += nr;
return nr;
}
/**
* ntfs_device_unix_raw_io_write - Write to the device, at the current location
* @dev:
* @buf:
* @count:
*
* Description...
*
* Returns:
*/
static s64 ntfs_device_unix_raw_io_write(struct ntfs_device *dev, const void *buf,
s64 count)
{
s64 start, start_aligned;
s64 end, end_aligned;
size_t count_aligned;
char *buf_aligned;
ssize_t nw;
if (NDevReadOnly(dev)) {
errno = EROFS;
return -1;
}
NDevSetDirty(dev);
/* short-circuit for regular files */
start = DEV_FD(dev)->pos;
if (count > RAW_IO_MAX_SIZE)
count = RAW_IO_MAX_SIZE;
if (RAW_IO_ALIGNED(dev, start, count)) {
nw = raw_io_pwrite(dev, buf, count, start);
if (nw <= 0)
return nw;
DEV_FD(dev)->pos += nw;
return nw;
}
/*
* +- start_aligned +- end_aligned
* | |
* | +- start +- end |
* v v v v
* |----------|----------|----------|
* ^ ^
* +----- count ------+
* ^ ^
* +-------- count_aligned ---------+
*/
start_aligned = RAW_IO_ALIGN(dev, start);
end = start + count;
end_aligned = RAW_IO_ALIGN(dev, end) +
(RAW_IO_ALIGNED(dev, end, 0) ? 0 : DEV_FD(dev)->block_size);
count_aligned = end_aligned - start_aligned;
ntfs_log_trace(
"%s: count = 0x%llx/0x%x, start = 0x%llx/0x%llx, end = 0x%llx/0x%llx\n",
dev->d_name, count, count_aligned,
start, start_aligned, end, end_aligned);
/* allocate buffer */
buf_aligned = malloc(count_aligned);
if (buf_aligned == NULL) {
ntfs_log_trace("malloc(%d) failed\n", count_aligned);
return -1;
}
/* read aligned lead-in */
if (raw_io_pread(dev, buf_aligned, DEV_FD(dev)->block_size, start_aligned) != DEV_FD(dev)->block_size) {
ntfs_log_trace("read lead-in failed\n");
free(buf_aligned);
return -1;
}
/* read aligned lead-out */
if (end != end_aligned && count_aligned > DEV_FD(dev)->block_size) {
if (raw_io_pread(dev, buf_aligned + count_aligned - DEV_FD(dev)->block_size, DEV_FD(dev)->block_size, end_aligned - DEV_FD(dev)->block_size) != DEV_FD(dev)->block_size) {
ntfs_log_trace("read lead-out failed\n");
free(buf_aligned);
return -1;
}
}
/* copy data to write */
memcpy(buf_aligned + (start - start_aligned), buf, count);
/* write aligned data */
nw = raw_io_pwrite(dev, buf_aligned, count_aligned, start_aligned);
free(buf_aligned);
if (nw < 0 || nw < start - start_aligned)
return -1;
nw -= start - start_aligned;
if (nw > count)
nw = count;
DEV_FD(dev)->pos += nw;
return nw;
}
/**
* ntfs_device_unix_raw_io_pread - Perform a positioned read from the device
* @dev:
* @buf:
* @count:
* @offset:
*
* Description...
*
* Returns:
*/
static s64 ntfs_device_unix_raw_io_pread(struct ntfs_device *dev, void *buf,
s64 count, s64 offset)
{
return ntfs_pread(dev, offset, count, buf);
}
/**
* ntfs_device_unix_raw_io_pwrite - Perform a positioned write to the device
* @dev:
* @buf:
* @count:
* @offset:
*
* Description...
*
* Returns:
*/
static s64 ntfs_device_unix_raw_io_pwrite(struct ntfs_device *dev, const void *buf,
s64 count, s64 offset)
{
if (NDevReadOnly(dev)) {
errno = EROFS;
return -1;
}
NDevSetDirty(dev);
return ntfs_pwrite(dev, offset, count, buf);
}
/**
* ntfs_device_unix_raw_io_sync - Flush any buffered changes to the device
* @dev:
*
* Description...
*
* Returns:
*/
static int ntfs_device_unix_raw_io_sync(struct ntfs_device *dev)
{
if (!NDevReadOnly(dev)) {
int res = fsync(DEV_FD(dev)->fd);
if (!res)
NDevClearDirty(dev);
return res;
}
return 0;
}
/**
* ntfs_device_unix_raw_io_stat - Get information about the device
* @dev:
* @buf:
*
* Description...
*
* Returns:
*/
static int ntfs_device_unix_raw_io_stat(struct ntfs_device *dev, struct stat *buf)
{
return fstat(DEV_FD(dev)->fd, buf);
}
/**
* ntfs_device_unix_raw_io_ioctl - Perform an ioctl on the device
* @dev:
* @request:
* @argp:
*
* Description...
*
* Returns:
*/
static int ntfs_device_unix_raw_io_ioctl(struct ntfs_device *dev, int request,
void *argp)
{
return ioctl(DEV_FD(dev)->fd, request, argp);
}
/**
* Device operations for working with unix style devices and files.
*/
struct ntfs_device_operations ntfs_device_unix_io_ops = {
.open = ntfs_device_unix_raw_io_open,
.close = ntfs_device_unix_raw_io_close,
.seek = ntfs_device_unix_raw_io_seek,
.read = ntfs_device_unix_raw_io_read,
.write = ntfs_device_unix_raw_io_write,
.pread = ntfs_device_unix_raw_io_pread,
.pwrite = ntfs_device_unix_raw_io_pwrite,
.sync = ntfs_device_unix_raw_io_sync,
.stat = ntfs_device_unix_raw_io_stat,
.ioctl = ntfs_device_unix_raw_io_ioctl,
};