Changes by: aia21
Update of /cvs/linux-ntfs/ntfsprogs/libntfs
In directory delta357:/tmp/cvs-serv32694/libntfs
Modified Files:
device.c dir.c unix_io.c win32_io.c
Log Message:
- 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)
Index: device.c
===================================================================
RCS file: /cvs/linux-ntfs/ntfsprogs/libntfs/device.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -p -r1.31 -r1.32
--- device.c 1 Nov 2006 13:30:40 -0000 1.31
+++ device.c 9 Dec 2006 14:01:12 -0000 1.32
@@ -153,6 +153,22 @@ int ntfs_device_free(struct ntfs_device
}
/**
+ * 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
* @pos: position in device to read from
@@ -175,6 +191,7 @@ s64 ntfs_pread(struct ntfs_device *dev,
{
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,
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;
}
@@ -207,6 +237,22 @@ s64 ntfs_pread(struct ntfs_device *dev,
}
/**
+ * 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
* @pos: position in file descriptor to write to
@@ -230,6 +276,7 @@ s64 ntfs_pwrite(struct ntfs_device *dev,
{
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,
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,
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,
*/
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;
}
Index: dir.c
===================================================================
RCS file: /cvs/linux-ntfs/ntfsprogs/libntfs/dir.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -p -r1.80 -r1.81
--- dir.c 6 Dec 2006 18:50:13 -0000 1.80
+++ dir.c 9 Dec 2006 14:01:12 -0000 1.81
@@ -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_volu
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_volu
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_volu
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++;
Index: unix_io.c
===================================================================
RCS file: /cvs/linux-ntfs/ntfsprogs/libntfs/unix_io.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -p -r1.15 -r1.16
--- unix_io.c 25 Nov 2006 17:37:37 -0000 1.15
+++ unix_io.c 9 Dec 2006 14:01:12 -0000 1.16
@@ -229,7 +229,7 @@ static s64 ntfs_device_unix_io_write(str
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(st
return -1;
}
NDevSetDirty(dev);
- return ntfs_pwrite(dev, offset, count, buf);
+ return pwrite(DEV_FD(dev), buf, count, offset);
}
/**
Index: win32_io.c
===================================================================
RCS file: /cvs/linux-ntfs/ntfsprogs/libntfs/win32_io.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -p -r1.48 -r1.49
--- win32_io.c 26 Oct 2006 19:10:05 -0000 1.48
+++ win32_io.c 9 Dec 2006 14:01:13 -0000 1.49
@@ -1449,26 +1449,12 @@ static int ntfs_device_win32_ioctl(struc
}
}
-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
|