Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv7617
Modified Files:
disk_io.c
Log Message:
Cleanup and fixes.
Index: disk_io.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/disk_io.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** disk_io.c 2001/03/26 03:39:59 1.4
--- disk_io.c 2001/03/26 04:28:07 1.5
***************
*** 263,325 ****
}
! /*
! * Return 0 on success, <0 on error (return value is the error code).
! * Caller has to free(*mrec) when finished.
*/
! int read_file_record(const ntfs_volume *vol, const MFT_REFERENCE mref,
! MFT_RECORD **mrec, ATTR_RECORD **attr)
{
! int er = 0;
!
! if (!vol || !mrec || !attr) {
! #ifdef DEBUG
! fprintf(stderr, "read_file_record() received NULL pointer!\n");
! #endif
! return -EINVAL;
! }
! if (!(*mrec = malloc(vol->mft_record_size)))
! return -ENOMEM;
! if ((er = get_mft_record(vol, *mrec, mref)) != 1)
! goto failed;
! if (!is_file_record(*mrec->magic))
! goto file_corrupt;
! if (mref.sequence_number != le16_to_cpu(*mrec->sequence_number))
! goto file_corrupt;
! if (!(*mrec->flags & MFT_RECORD_IN_USE))
! goto file_corrupt;
! *attr = (ATTR_RECORD*)((char*)*mrec + le16_to_cpu(*mrec->attrs_offset));
! if (*attr < *mrec || *attr > (char*)*mrec + vol->mft_record_size)
! goto file_corrupt;
! return 0;
! file_corrupt:
! #ifdef DEBUG
! fprintf(stderr, "read_file_record(): file is corrupt.\n");
! #endif
! er = -EIO;
! failed:
! free(*mrec);
! *mrec = *attr = NULL;
! return er < 0 ? er : -EINVAL;
! }
!
! __inline__ int get_mft_record(const ntfs_volume *vol, __u8 *buf,
! const __s64 mft_ref)
! {
! return get_mft_records(vol, buf, mft_ref, 1);
! }
!
! int get_mft_records(const ntfs_volume *vol, __u8 *buf, const __s64 mft_ref,
! const int count)
! {
! __u64 br;
__s64 lcn, ofs;
! if (!vol || !buf || mftref < 0)
return -EINVAL;
if (!vol->fd)
return -EBADF;
! if (vol->number_of_mft_records < mft_ref + count)
return -ESPIPE;
! if (!get_bit(vol->mft_bitmap, mft_ref))
return -ENOENT;
/* Size of mft record != size of cluster thus need to work with
--- 263,294 ----
}
! /**
! * get_mft_records - read records from the mft
! * @vol: volume to read from
! * @buf: output data buffer
! * @mref: starting mft record number
! * @count: number of mft records to read
! *
! * Read @count mft records starting at @mref from volume @vol into buffer
! * @buf. Return @count on success or -ERRNO on error, where ERRNO is the error
! * code. This function will do the error reporting so caller really only needs
! * to check for sucess / failure.
! *
! * NOTE: @buf has to be at least of size @count * vol->mft_record_size.
*/
! int get_mft_records(const ntfs_volume *vol, __u8 *buf,
! const MFT_REFERENCE *mref, const int count)
{
! __u64 br, m;
__s64 lcn, ofs;
! if (!vol || !buf)
return -EINVAL;
if (!vol->fd)
return -EBADF;
! m = mref->mft_reference & MFT_REFERENCE_MASK;
! if (vol->number_of_mft_records < m + count)
return -ESPIPE;
! if (!get_bit(vol->mft_bitmap, m))
return -ENOENT;
/* Size of mft record != size of cluster thus need to work with
***************
*** 327,338 ****
if (vol->mft_records_per_cluster) {
lcn = vcn_to_lcn(vol->mft_runlist,
! mft_ref / vol->mft_records_per_cluster);
/* FIXME: Change "/" above and "%" below to ">>" and "&"
respectively! */
! ofs = mft_ref % vol->mft_records_per_cluster;
ofs <<= vol->mft_record_size_bits;
} else {
lcn = vcn_to_lcn(vol->mft_runlist,
! mft_ref * vol->clusters_per_mft_record);
/* FIXME: Change "*" above to "<<"! */
ofs = 0;
--- 296,307 ----
if (vol->mft_records_per_cluster) {
lcn = vcn_to_lcn(vol->mft_runlist,
! m / vol->mft_records_per_cluster);
/* FIXME: Change "/" above and "%" below to ">>" and "&"
respectively! */
! ofs = m % vol->mft_records_per_cluster;
ofs <<= vol->mft_record_size_bits;
} else {
lcn = vcn_to_lcn(vol->mft_runlist,
! m * vol->clusters_per_mft_record);
/* FIXME: Change "*" above to "<<"! */
ofs = 0;
***************
*** 361,377 ****
return br;
}
! int put_mft_record(ntfs_volume *vol, const __u8 *buf, const __s64 mftrec)
{
! __u64 bw;
__s64 lcn, ofs;
! if (!vol || !buf || mftrec < 0)
return -EINVAL;
if (!vol->fd)
return -EBADF;
! if (vol->number_of_mft_records <= mftrec)
return -ESPIPE;
! if (!get_bit(vol->mft_bitmap, mftrec))
return -ENOENT;
/* Size of mft record != size of cluster thus need to work with offsets
--- 330,427 ----
return br;
}
+
+ /**
+ * get_mft_record - read a record from the mft
+ * @vol: volume to read from
+ * @buf: output data buffer
+ * @mref: starting mft record number
+ * @count: number of mft records to read
+ *
+ * Read mft record specified by @mref from volume @vol into buffer @buf.
+ * Return 1 on success or -ERRNO on error, where ERRNO is the error
+ * code. This function will do the error reporting so caller really only needs
+ * to check for sucess / failure.
+ *
+ * NOTE: @buf has to be at least of size vol->mft_record_size.
+ */
+ __inline__ int get_mft_record(const ntfs_volume *vol, __u8 *buf,
+ const MFT_REFERENCE *mref)
+ {
+ return get_mft_records(vol, buf, mref, 1);
+ }
+
+ /**
+ * read_file_record - read a FILE record from the mft
+ * @vol: volume to read from
+ * @mref: mft reference specifying mft record to read
+ * @mrec: address of pointer in which to return the mft record
+ * @attr: address of pointer in which to return the first attribute
+ *
+ * Read a FILE record from the mft of @vol. @mref specifies the mft record
+ * to read, including the sequence number. When the function returns, @mrec and
+ * @attr will contain pointers to the read mft record and to the first attribute
+ * within the mft record, respectively.
+ *
+ * The read mft record is checked for having the magic FILE, for being in use,
+ * and for having a matching sequence number (if @mref->sequence_number != 0).
+ * If either of these fails, return -EIO.
+ *
+ * Return 0 on success, or -ERRNO on error, where ERRNO is the error code.
+ *
+ * Note: Caller has to free *@mrec when finished.
+ */
+ int read_file_record(const ntfs_volume *vol, const MFT_REFERENCE *mref,
+ MFT_RECORD **mrec, ATTR_RECORD **attr)
+ {
+ MFT_RECORD *m;
+ int er = 0;
+
+ if (!vol || !mrec || !attr) {
+ #ifdef DEBUG
+ fprintf(stderr, "read_file_record() received NULL pointer!\n");
+ #endif
+ return -EINVAL;
+ }
+ if (!(m = malloc(vol->mft_record_size)))
+ return -ENOMEM;
+ if ((er = get_mft_record(vol, m, mref)) != 1)
+ goto failed;
+ if (!is_file_record(m->magic))
+ goto file_corrupt;
+ if (mref->sequence_number &&
+ mref->sequence_number != le16_to_cpu(m->sequence_number))
+ goto file_corrupt;
+ if (!(m->flags & MFT_RECORD_IN_USE))
+ goto file_corrupt;
+ *attr = (ATTR_RECORD*)((char*)m + le16_to_cpu(m->attrs_offset));
+ if (*attr < m || *attr > (char*)m + vol->mft_record_size)
+ goto file_corrupt;
+ *mrec = m;
+ return 0;
+ file_corrupt_attr:
+ *attr = NULL;
+ file_corrupt:
+ #ifdef DEBUG
+ fprintf(stderr, "read_file_record(): file is corrupt.\n");
+ #endif
+ er = -EIO;
+ failed:
+ free(m);
+ return er < 0 ? er : -EINVAL;
+ }
! int put_mft_record(ntfs_volume *vol, const __u8 *buf, const MFT_REFERENC *mref)
{
! __u64 bw, m;
__s64 lcn, ofs;
! if (!vol || !buf)
return -EINVAL;
if (!vol->fd)
return -EBADF;
! m = mref->mft_reference & MFT_REFERENCE_MASK;
! if (vol->number_of_mft_records <= m)
return -ESPIPE;
! if (!get_bit(vol->mft_bitmap, m))
return -ENOENT;
/* Size of mft record != size of cluster thus need to work with offsets
***************
*** 379,390 ****
if (vol->mft_records_per_cluster) {
lcn = vcn_to_lcn(vol->mft_runlist,
! mftrec / vol->mft_records_per_cluster);
/* FIXME: Change "/" above and "%" below to ">>" and "&"
respectively! */
! ofs = mftrec % vol->mft_records_per_cluster;
ofs <<= vol->mft_record_size_bits;
} else {
lcn = vcn_to_lcn(vol->mft_runlist,
! mftrec * vol->clusters_per_mft_record);
/* FIXME: Change "*" above to "<<"! */
ofs = 0;
--- 429,440 ----
if (vol->mft_records_per_cluster) {
lcn = vcn_to_lcn(vol->mft_runlist,
! m / vol->mft_records_per_cluster);
/* FIXME: Change "/" above and "%" below to ">>" and "&"
respectively! */
! ofs = m % vol->mft_records_per_cluster;
ofs <<= vol->mft_record_size_bits;
} else {
lcn = vcn_to_lcn(vol->mft_runlist,
! m * vol->clusters_per_mft_record);
/* FIXME: Change "*" above to "<<"! */
ofs = 0;
|