- Implement ntfs_pread() and ntfs_pwrite() in terms of device
operations pread() and pwrite() respectively and fall back to using seek() + read()/write() if no pread()/pwrite() device operation is supplied or the OS does not support the pread()/pwrite() system call. Adapt unix_io pread()/pwrite() device operations to use pread()/ pwrite() system call and adapt win32_io device operations to not supply pread()/pwrite(). (Csaba Henk, Anton)edge.strict_endians
parent
8640540b53
commit
f73d77d568
1
CREDITS
1
CREDITS
|
@ -17,6 +17,7 @@ Matthew J. Fanto <mattjf at uncompiled.com>
|
|||
Yuval Fledel <yuvalfl at gmail.com>
|
||||
Marcin Gibuła <m.gibula at conecto.pl>
|
||||
Christophe Grenier <grenier at cgsecurity.org>
|
||||
Csaba Henk <csaba.henk at creo.hu>
|
||||
Ian Jackson <ian at davenant.greenend.org.uk>
|
||||
Carmelo Kintana <kintana at berkeley.edu>
|
||||
Jan Kratochvil <project-captive at jankratochvil.net>
|
||||
|
|
|
@ -99,6 +99,13 @@ xx/xx/2006 - x.xx.x - .
|
|||
- ntfsmount: fix rename if destination already exists. (Yura)
|
||||
- ntfsfix: do not set VOLUME_MOUNTED_ON_NT4 flag as it causes Vista to
|
||||
not boot any more.
|
||||
- Implement ntfs_pread() and ntfs_pwrite() in terms of device
|
||||
operations pread() and pwrite() respectively and fall back to using
|
||||
seek() + read()/write() if no pread()/pwrite() device operation is
|
||||
supplied or the OS does not support the pread()/pwrite() system call.
|
||||
Adapt unix_io pread()/pwrite() device operations to use pread()/
|
||||
pwrite() system call and adapt win32_io device operations to not
|
||||
supply pread()/pwrite(). (Csaba Henk, Anton)
|
||||
|
||||
21/06/2006 - 1.13.1 - Various fixes.
|
||||
|
||||
|
|
|
@ -152,6 +152,22 @@ int ntfs_device_free(struct ntfs_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fake_pread - read operation disguised as pread
|
||||
* @dev: device to read from
|
||||
* @b: output data buffer
|
||||
* @count: number of bytes to read
|
||||
* @pos: position in device to read from
|
||||
*
|
||||
* Auxiliary function, used when we emulate pread by seek() + a sequence of
|
||||
* read()s.
|
||||
*/
|
||||
static s64 fake_pread(struct ntfs_device *dev, void *b, s64 count,
|
||||
s64 pos __attribute__((unused)))
|
||||
{
|
||||
return dev->d_ops->read(dev, b, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_pread - positioned read from disk
|
||||
* @dev: device to read from
|
||||
|
@ -175,6 +191,7 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
|
|||
{
|
||||
s64 br, total;
|
||||
struct ntfs_device_operations *dops;
|
||||
s64 (*_pread)(struct ntfs_device *, void *, s64, s64);
|
||||
|
||||
ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
|
||||
if (!b || count < 0 || pos < 0) {
|
||||
|
@ -184,21 +201,34 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
|
|||
if (!count)
|
||||
return 0;
|
||||
dops = dev->d_ops;
|
||||
/* Locate to position. */
|
||||
if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
ntfs_log_perror("ntfs_pread: device seek to 0x%llx returned error",
|
||||
pos);
|
||||
_pread = dops->pread;
|
||||
if (!_pread)
|
||||
_pread = fake_pread;
|
||||
seek:
|
||||
/* Locate to position if pread is to be emulated by seek() + read(). */
|
||||
if (_pread == fake_pread &&
|
||||
dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
ntfs_log_perror("ntfs_pread: device seek to 0x%llx returned "
|
||||
"error", pos);
|
||||
return -1;
|
||||
}
|
||||
/* Read the data. */
|
||||
for (total = 0; count; count -= br, total += br) {
|
||||
br = dops->read(dev, (char*)b + total, count);
|
||||
br = _pread(dev, (char*)b + total, count, pos + total);
|
||||
/* If everything ok, continue. */
|
||||
if (br > 0)
|
||||
continue;
|
||||
/* If EOF or error return number of bytes read. */
|
||||
if (!br || total)
|
||||
return total;
|
||||
/*
|
||||
* If pread is not supported by the OS, fall back to emulating
|
||||
* it by seek() + read().
|
||||
*/
|
||||
if (errno == ENOSYS && _pread != fake_pread) {
|
||||
_pread = fake_pread;
|
||||
goto seek;
|
||||
}
|
||||
/* Nothing read and error, return error status. */
|
||||
return br;
|
||||
}
|
||||
|
@ -206,6 +236,22 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
|
|||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* fake_pwrite - write operation disguised as pwrite
|
||||
* @dev: device to write to
|
||||
* @b: input data buffer
|
||||
* @count: number of bytes to write
|
||||
* @pos: position in device to write to
|
||||
*
|
||||
* Auxiliary function, used when we emulate pwrite by seek() + a sequence of
|
||||
* write()s.
|
||||
*/
|
||||
static s64 fake_pwrite(struct ntfs_device *dev, const void *b, s64 count,
|
||||
s64 pos __attribute__((unused)))
|
||||
{
|
||||
return dev->d_ops->write(dev, b, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_pwrite - positioned write to disk
|
||||
* @dev: device to write to
|
||||
|
@ -230,6 +276,7 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
{
|
||||
s64 written, total;
|
||||
struct ntfs_device_operations *dops;
|
||||
s64 (*_pwrite)(struct ntfs_device *, const void *, s64, s64);
|
||||
|
||||
ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
|
||||
if (!b || count < 0 || pos < 0) {
|
||||
|
@ -243,8 +290,15 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
return -1;
|
||||
}
|
||||
dops = dev->d_ops;
|
||||
/* Locate to position. */
|
||||
if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
_pwrite = dops->pwrite;
|
||||
if (!_pwrite)
|
||||
_pwrite = fake_pwrite;
|
||||
seek:
|
||||
/*
|
||||
* Locate to position if pwrite is to be emulated by seek() + write().
|
||||
*/
|
||||
if (_pwrite == fake_pwrite &&
|
||||
dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
|
||||
ntfs_log_perror("ntfs_pwrite: seek to 0x%llx returned error",
|
||||
pos);
|
||||
return -1;
|
||||
|
@ -252,7 +306,8 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
NDevSetDirty(dev);
|
||||
/* Write the data. */
|
||||
for (total = 0; count; count -= written, total += written) {
|
||||
written = dops->write(dev, (const char*)b + total, count);
|
||||
written = _pwrite(dev, (const char*)b + total, count,
|
||||
pos + total);
|
||||
/* If everything ok, continue. */
|
||||
if (written > 0)
|
||||
continue;
|
||||
|
@ -261,6 +316,14 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
|
|||
*/
|
||||
if (!written || total)
|
||||
break;
|
||||
/*
|
||||
* If pwrite is not supported by the OS, fall back to emulating
|
||||
* it by seek() + write().
|
||||
*/
|
||||
if (errno == ENOSYS && _pwrite != fake_pwrite) {
|
||||
_pwrite = fake_pwrite;
|
||||
goto seek;
|
||||
}
|
||||
/* Nothing written and error, return error status. */
|
||||
return written;
|
||||
}
|
||||
|
|
|
@ -486,25 +486,23 @@ close_err_out:
|
|||
u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
|
||||
const char *pathname)
|
||||
{
|
||||
u64 inum, result = (u64)-1;
|
||||
u64 inum, result;
|
||||
int len, err = 0;
|
||||
char *p, *q;
|
||||
ntfs_inode *ni = NULL;
|
||||
ntfschar *unicode = NULL;
|
||||
char *ascii = NULL;
|
||||
|
||||
inum = result = (u64)-1;
|
||||
if (!vol || !pathname) {
|
||||
err = EINVAL;
|
||||
goto close;
|
||||
}
|
||||
|
||||
ntfs_log_trace("Path: '%s'\n", pathname);
|
||||
|
||||
if (parent) {
|
||||
ni = parent;
|
||||
} else
|
||||
inum = FILE_root;
|
||||
|
||||
unicode = calloc(1, MAX_PATH);
|
||||
ascii = strdup(pathname);
|
||||
if (!unicode || !ascii) {
|
||||
|
@ -512,7 +510,6 @@ u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
|
|||
err = ENOMEM;
|
||||
goto close;
|
||||
}
|
||||
|
||||
p = ascii;
|
||||
/* Remove leading /'s. */
|
||||
while (p && *p == PATH_SEP)
|
||||
|
@ -527,14 +524,12 @@ u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
|
|||
goto close;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the end of the first token. */
|
||||
q = strchr(p, PATH_SEP);
|
||||
if (q != NULL) {
|
||||
*q = 0;
|
||||
q++;
|
||||
}
|
||||
|
||||
len = ntfs_mbstoucs(p, &unicode, MAX_PATH);
|
||||
if (len < 0) {
|
||||
ntfs_log_debug("Couldn't convert name to Unicode: "
|
||||
|
@ -542,20 +537,17 @@ u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
|
|||
err = EILSEQ;
|
||||
goto close;
|
||||
}
|
||||
|
||||
inum = ntfs_inode_lookup_by_name(ni, unicode, len);
|
||||
if (inum == (u64) -1) {
|
||||
if (inum == (u64)-1) {
|
||||
ntfs_log_debug("Couldn't find name '%s' in pathname "
|
||||
"'%s'.\n", p, pathname);
|
||||
err = ENOENT;
|
||||
goto close;
|
||||
}
|
||||
inum = MREF(inum);
|
||||
|
||||
if (ni != parent)
|
||||
ntfs_inode_close(ni);
|
||||
ni = NULL;
|
||||
|
||||
p = q;
|
||||
while (p && *p == PATH_SEP)
|
||||
p++;
|
||||
|
|
|
@ -229,7 +229,7 @@ static s64 ntfs_device_unix_io_write(struct ntfs_device *dev, const void *buf,
|
|||
static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
|
||||
s64 count, s64 offset)
|
||||
{
|
||||
return ntfs_pread(dev, offset, count, buf);
|
||||
return pread(DEV_FD(dev), buf, count, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,7 +251,7 @@ static s64 ntfs_device_unix_io_pwrite(struct ntfs_device *dev, const void *buf,
|
|||
return -1;
|
||||
}
|
||||
NDevSetDirty(dev);
|
||||
return ntfs_pwrite(dev, offset, count, buf);
|
||||
return pwrite(DEV_FD(dev), buf, count, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1449,26 +1449,12 @@ static int ntfs_device_win32_ioctl(struct ntfs_device *dev, int request,
|
|||
}
|
||||
}
|
||||
|
||||
static s64 ntfs_device_win32_pread(struct ntfs_device *dev, void *b,
|
||||
s64 count, s64 offset)
|
||||
{
|
||||
return ntfs_pread(dev, offset, count, b);
|
||||
}
|
||||
|
||||
static s64 ntfs_device_win32_pwrite(struct ntfs_device *dev, const void *b,
|
||||
s64 count, s64 offset)
|
||||
{
|
||||
return ntfs_pwrite(dev, offset, count, b);
|
||||
}
|
||||
|
||||
struct ntfs_device_operations ntfs_device_win32_io_ops = {
|
||||
.open = ntfs_device_win32_open,
|
||||
.close = ntfs_device_win32_close,
|
||||
.seek = ntfs_device_win32_seek,
|
||||
.read = ntfs_device_win32_read,
|
||||
.write = ntfs_device_win32_write,
|
||||
.pread = ntfs_device_win32_pread,
|
||||
.pwrite = ntfs_device_win32_pwrite,
|
||||
.sync = ntfs_device_win32_sync,
|
||||
.stat = ntfs_device_win32_stat,
|
||||
.ioctl = ntfs_device_win32_ioctl
|
||||
|
|
Loading…
Reference in New Issue