Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv2332/libntfs
Modified Files:
attrib.c
Log Message:
Finish ntfs_attr_pread and ntfs_attr_mst_pread.
Index: attrib.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/attrib.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -U2 -r1.37 -r1.38
--- attrib.c 29 Apr 2002 01:53:55 -0000 1.37
+++ attrib.c 29 Apr 2002 12:58:34 -0000 1.38
@@ -32,4 +32,5 @@
#include "mft.h"
#include "debug.h"
+#include "mst.h"
/* FIXME: Need to write the new flags to disk. */
@@ -1570,5 +1571,5 @@
* invalid arguments.
*/
-int ntfs_attr_pread(ntfs_attr *na, const __s64 pos, __s64 count, void *dst)
+__s64 ntfs_attr_pread(ntfs_attr *na, const __s64 pos, __s64 count, void *dst)
{
__s64 br, to_read, total;
@@ -1678,106 +1679,31 @@
* 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 @bk_cnt blocks as being read but
- * that any number (between zero and @bk_cnt) of these blocks is actually
- * subject to a multi sector transfer error. This should be detected by
- * the caller by checking each block with is_baad_recordp(&block).
- */
-#if 0
-int ntfs_attr_mst_pread(ntfs_attr *na, const __s64 pos, const __s64 bk_cnt,
- const int bk_size, void *dst)
+ * NOTE: If an incomplete multi sector transfer is detected the magic is
+ * changed to BAAD but no error is returned, i.e. it is possible that
+ * any of the returned blocks have multi sector transfer errors. This
+ * should be detected by the caller by checking each block with
+ * is_baad_recordp(&block). The reasoning is that we want to fixup as
+ * many blocks as possible and we want to return even bad ones to the
+ * caller so, e.g. in case of ntfsck, the errors can be repaired.
+ */
+__s64 ntfs_attr_mst_pread(ntfs_attr *na, const __s64 pos, const __s64 bk_cnt,
+ const __u32 bk_size, void *dst)
{
- VCN vcn;
- __s64 br, to_read, total;
- ntfs_volume *vol;
- run_list_element *rl;
- int f, ofs;
+ __s64 br;
+ void *end;
- if (!na || !na->ni || !na->ni->vol || !dst || pos < 0 || bk_cnt < 0 ||
- bk_size < 0) {
+ if (bk_cnt < 0 || bk_size % NTFS_SECTOR_SIZE) {
errno = EINVAL;
return -1;
}
- vol = na->ni->vol;
- f = vol->fd;
- if (!f) {
- errno = EBADF;
- return -1;
- }
- if (!count)
- return 0;
- /* The vcn and ofs in the run list of the first byte to read. */
- vcn = pos >> vol->cluster_size_bits;
- ofs = pos & (vol->cluster_size - 1);
-
- /* Find the run list element containing the vcn. */
- rl = ntfs_attr_find_vcn(na, vcn);
- if (!rl) {
- /*
- * If the vcn is not present it is an out of bounds read which
- * means a read beyond end of file, thus just return 0.
- */
- if (errno == ENOENT)
- return 0;
- return -1;
- }
-
- /*
- * Gather the requested data into the linear destination buffer. Note,
- * a partial final vcn is taken care of by the @count capping of read
- * length.
- */
- for (total = 0; count; rl++, ofs = 0) {
- /* If we have reached the end of the run list return. */
- if (!rl->length)
- return total;
- if (rl->lcn < (LCN)0) {
- if (rl->lcn != (LCN)LCN_HOLE) {
- /*
- * If we have already read anything, return how
- * much. Same if the read is beyond the end.
- */
- if (total || rl->lcn == (LCN)LCN_ENOENT)
- return total;
- errno = EIO;
- return -1;
- }
- /* It is a hole, just zero the matching @dst range. */
- to_read = min(count, (rl->length <<
- vol->cluster_size_bits) - ofs);
- memset(dst, 0, to_read);
- /* Update progress counters. */
- total += to_read;
- count -= to_read;
- dst += to_read;
- continue;
- }
- /* It is a real lcn, read it into @dst. */
- to_read = min(count, (rl->length << vol->cluster_size_bits) -
- ofs);
-retry:
- br = ntfs_pread(f, (rl->lcn << vol->cluster_size_bits) + ofs,
- to_read, dst);
- /* If everything ok, update progress counters and continue. */
- if (br > 0) {
- total += br;
- count -= br;
- dst += br;
- continue;
- }
- /* If the syscall was interrupted, try again. */
- if (br == (__s64)-1 && errno == EINTR)
- goto retry;
- /* If EOF or error, return number of bytes read. */
- if (!br || total)
- return total;
- /* Nothing read, return error. */
+ br = ntfs_attr_pread(na, pos, bk_cnt * bk_size, dst);
+ if (!br || br == (__s64)-1)
return br;
- }
- /* Finally, return the number of bytes read. */
- return total;
+ br /= bk_size;
+ for (end = dst + br * bk_size; dst < end; dst += bk_size)
+ ntfs_post_read_mst_fixup((NTFS_RECORD*)dst, bk_size);
+ /* Finally, return the number of blocks read. */
+ return br;
}
-#endif
/*
|