Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv23265/libntfs
Modified Files:
disk_io.c
Log Message:
Final POSIXification of disk_io functions. (famous last words)
Index: disk_io.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/disk_io.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -U2 -r1.24 -r1.25
--- disk_io.c 1 Jun 2002 00:41:45 -0000 1.24
+++ disk_io.c 4 Jun 2002 12:12:42 -0000 1.25
@@ -48,7 +48,7 @@
* end of file or nothing to read (@count is 0).
*
- * On error and nothing has been read yet, return -1 with errno set
- * appropriately to the return code of either lseek or read, or to EINVAL in
- * case of invalid arguments.
+ * On error and nothing has been read, return -1 with errno set appropriately
+ * to the return code of either lseek, read, or set to EINVAL in case of
+ * invalid arguments.
*/
__s64 ntfs_pread(const int fd, const __s64 pos, __s64 count, const void *b)
@@ -96,14 +96,19 @@
* position @pos.
*
- * On success return bytes written (0 means nothing written).
- * On error return -1 with errno set appropriately to the return code of
- * either lseek, malloc, write or fdatasync. Or errno is EINVAL if the
- * arguments are invalid.
+ * On success, return the number of successfully written bytes. If this number
+ * is lower than @count this means that the write has been interrupted in
+ * flight or that an error was encountered during the write so that the write
+ * is partial. 0 means nothing was written (also return 0 when @count is 0).
+ *
+ * On error and nothing has been written, return -1 with errno set
+ * appropriately to the return code of either lseek, write, fdatasync, or set
+ * to EINVAL in case of invalid arguments.
*/
__s64 ntfs_pwrite(const int fd, const __s64 pos, __s64 count, const void *b)
{
__s64 written, total;
- char retry;
+ Dprintf(__FUNCTION__ "(): Entering for pos 0x%Lx, count 0x%Lx.\n",
+ pos, count);
if (!b || count < 0 || pos < 0) {
errno = EINVAL;
@@ -119,19 +124,21 @@
}
/* Write the data. */
- total = retry = 0;
- do {
- written = write(fd, (char *)b + total, count);
- if (written == -1)
- return written;
- else if (!written)
- ++retry;
- /* We just recycle count as a local variable here. */
- count -= written;
- total += written;
- } while (count && (retry < 3));
+ for (total = 0; count; count -= written, total += written) {
+ written = write(fd, (char*)b + total, count);
+ /* If everything ok, continue. */
+ if (written > 0)
+ continue;
+ /*
+ * If nothing written or error return number of bytes written.
+ */
+ if (!written || total)
+ break;
+ /* Nothing written and error, return error status. */
+ return written;
+ }
/* Sync write to disk. */
if (fdatasync(fd) == -1)
return -1;
- /* Finally return the number of bytes written. */
+ /* Finally, return the number of bytes written. */
return total;
}
@@ -146,20 +153,23 @@
*
* Multi sector transfer (mst) positioned read. This function will read @count
- * @blocks of size @bksize bytes each from file descriptor @fd at position @pos
+ * blocks of size @bksize bytes each from file descriptor @fd at position @pos
* into the buffer @b.
*
* On success, return the number of successfully read blocks. If this number is
- * lower than @count this means that we have reached end of file. 0 means end
- * of file or nothing to read (@count or @bksize is 0). On error, return -1
- * with errno set appropriately to the return code of either lseek or read, or
- * to EINVAL in case the data pointer @b was NULL or the block size (@bksize)
- * was not a multiple of NTFS_SECTOR_SIZE or @bksize was not a power of two.
+ * lower than @count this means that we have reached end of file, that the read
+ * was interrupted, or that an error was encountered during the read so that
+ * the read is partial. 0 means end of file or nothing was read (also return 0
+ * when @count or @bksize are 0).
+ *
+ * On error and nothing was read, return -1 with errno set appropriately to the
+ * return code of either lseek, read, or set to EINVAL in case of invalid
+ * arguments.
*
* NOTE: If an incomplete multi sector transfer has been detected the magic
- * will have been changed to magic_BAAD but no error will be returned.
- * I.e. it is possible that we return count blocks as being read but that
- * any number (between zero and count!) of these blocks is actually
- * subject to a multi sector transfer error. This should be detected by
- * the caller by checking for the magic being "BAAD".
+ * will have been changed to magic_BAAD but no error will be returned. Thus it
+ * is possible that we return count blocks as being read but that any number
+ * (between zero and count!) of these blocks is actually subject to a multi
+ * sector transfer error. This should be detected by the caller by checking for
+ * the magic being "BAAD".
*/
__s64 ntfs_mst_pread(const int fd, const __s64 pos, __s64 count,
@@ -168,6 +178,5 @@
__s64 br, i;
- if (!b || count < 0 || pos < 0 || bksize & (bksize - 1) ||
- bksize % NTFS_SECTOR_SIZE) {
+ if (bksize & (bksize - 1) || bksize % NTFS_SECTOR_SIZE) {
errno = EINVAL;
return -1;
@@ -175,5 +184,5 @@
/* Do the read. */
br = ntfs_pread(fd, pos, count * bksize, b);
- if (br == -1)
+ if (br < 0)
return br;
/*
@@ -200,9 +209,15 @@
*
* Multi sector transfer (mst) positioned write. This function will write
- * @count bytes of data @b to file descriptor @fd at position @pos.
+ * @count blocks of size @bksize bytes each from data buffer @b to file
+ * descriptor @fd at position @pos into the file @fd.
*
- * On success return bytes written (0 means nothing written).
- * On error return -1 with errno set appropriately to the return code of
- * either lseek, malloc, write or fdatasync. Or errno is EINVAL if @b is null.
+ * On success, return the number of successfully written blocks. If this number
+ * is lower than @count this means that the write has been interrutped or that
+ * an error was encountered during the write so that the write is partial. 0
+ * means nothing was written (also return 0 when @count or @bksize are 0).
+ *
+ * On error and nothing has been written, return -1 with errno set
+ * appropriately to the return code of either lseek, write, fdatasync, or set
+ * to EINVAL in case of invalid arguments.
*
* NOTE: We mst protect the data, write it, then mst deprotect it using a quick
@@ -218,10 +233,7 @@
const __u32 bksize, const void *b)
{
- __s64 written, towrite, total, i;
- int err;
- char retry;
+ __s64 written, i;
- if (!b || count < 0 || pos < 0 || bksize & (bksize - 1) ||
- bksize % NTFS_SECTOR_SIZE) {
+ if (bksize & (bksize - 1) || bksize % NTFS_SECTOR_SIZE) {
errno = EINVAL;
return -1;
@@ -229,52 +241,27 @@
if (!count)
return 0;
- /* Seek to position. */
- if (lseek(fd, pos, SEEK_SET) == (off_t)-1) {
- Dprintf("ntfs_mst_pwrite: lseek to 0x%Lx returned error: %s\n",
- pos, strerror(errno));
- return -1;
- }
/* Prepare data for writing. */
for (i = 0; i < count; ++i) {
+ int err;
+
err = ntfs_pre_write_mst_fixup((NTFS_RECORD*)(b + i * bksize),
bksize);
- if (err) {
+ if (err < 0) {
/* Abort write at this position. */
if (!i)
- return -1;
- count = i - 1;
+ return err;
+ count = i;
break;
}
}
/* Write the prepared data. */
- towrite = count * bksize;
- total = retry = 0;
- do {
- written = write(fd, (char *)b + total, towrite);
- if (written == -1) {
- total = -1;
- goto finished;
- } else if (!written)
- ++retry;
- /* We just recycle count as a local variable here. */
- towrite -= written;
- total += written;
- } while (towrite && (retry < 3));
-finished:
+ written = ntfs_pwrite(fd, pos, count * bksize, b);
/* Quickly deprotect the data again. */
for (i = 0; i < count; ++i)
ntfs_post_write_mst_fixup((NTFS_RECORD*)(b + i * bksize));
- /* Sync write to disk. */
- if (fdatasync(fd) == -1)
- total = -1;
- /* Convert bytes written to blocks written. */
- if (total != -1)
- total /= bksize;
- /*
- * Finally return the number of complete blocks written or -1 for
- * error. We ignore errors where a partial block was written at the end
- * because these will be caught later on anyway.
- */
- return total;
+ if (written < 0)
+ return written;
+ /* Finally, return the number of complete blocks written. */
+ return written / bksize;
}
@@ -290,31 +277,22 @@
* with errno set to the error code.
*/
-__s64 ntfs_read_clusters(const ntfs_volume *vol, const __s64 lcn, __s64 count,
- const void *b)
+__s64 ntfs_read_clusters(const ntfs_volume *vol, const __s64 lcn,
+ const __s64 count, const void *b)
{
__s64 br;
- if (!vol || !b || count < 0 || lcn < 0) {
+ if (!vol || lcn < 0 || count < 0) {
errno = EINVAL;
return -1;
}
- if (!vol->fd) {
- errno = EBADF;
- return -1;
- }
- if (vol->nr_clusters < lcn + count) {
+ if (vol->nr_clusters <= lcn + count) {
errno = ESPIPE;
return -1;
}
- count <<= vol->cluster_size_bits;
- br = ntfs_pread(vol->fd, lcn << vol->cluster_size_bits, count, b);
- if (br != count) {
- if (br != -1)
- errno = EIO;
- if (!br)
- Dputs("Error: partition is smaller than it should be!");
- else
- Dperror("Error reading cluster(s)");
- return -1;
+ br = ntfs_pread(vol->fd, lcn << vol->cluster_size_bits,
+ count << vol->cluster_size_bits, b);
+ if (br < 0) {
+ Dperror("Error reading cluster(s)");
+ return br;
}
return br >> vol->cluster_size_bits;
@@ -329,34 +307,25 @@
*
* Write @count ntfs clusters starting at logical cluster number @lcn from
- * buffer @b to volume @vol. Return the nu,ber of clusters written or -1 on
+ * buffer @b to volume @vol. Return the number of clusters written or -1 on
* error, with errno set to the error code.
*/
-__s64 ntfs_write_clusters(const ntfs_volume *vol, const __s64 lcn, __s64 count,
- const void *b)
+__s64 ntfs_write_clusters(const ntfs_volume *vol, const __s64 lcn,
+ const __s64 count, const void *b)
{
__s64 bw;
- if (!vol || !b || count < 0 || lcn < 0) {
+ if (!vol || lcn < 0 || count < 0) {
errno = EINVAL;
return -1;
}
- if (!vol->fd) {
- errno = EBADF;
- return -1;
- }
- if (vol->nr_clusters < lcn + count) {
+ if (vol->nr_clusters <= lcn + count) {
errno = ESPIPE;
return -1;
}
- count <<= vol->cluster_size_bits;
- bw = ntfs_pwrite(vol->fd, lcn << vol->cluster_size_bits, count, b);
- if (bw != count) {
- if (bw != -1)
- errno = EIO;
- if (!bw)
- Dputs("Ran out of input data while writing clusters!");
- else
- Dperror("Error writing cluster(s)");
- return -1;
+ bw = ntfs_pwrite(vol->fd, lcn << vol->cluster_size_bits,
+ count << vol->cluster_size_bits, b);
+ if (bw < 0) {
+ Dperror("Error writing cluster(s)");
+ return bw;
}
return bw >> vol->cluster_size_bits;
|