Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv27230/libntfs
Modified Files:
Makefile.in attrib.c mft.c
Log Message:
Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion.
Index: Makefile.in
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/Makefile.in,v
retrieving revision 1.17
retrieving revision 1.18
diff -U2 -r1.17 -r1.18
--- Makefile.in 22 Apr 2002 10:34:31 -0000 1.17
+++ Makefile.in 24 Apr 2002 23:47:42 -0000 1.18
@@ -97,20 +97,11 @@
LTVERSION = 4:0:0
-@DEBUG_TRUE@AM_CFLAGS = @DEBUG_TRUE@-D_FILE_OFFSET_BITS=64 -g -DDEBUG -Wall
-@DEBUG_FALSE@AM_CFLAGS = @DEBUG_FALSE@-D_FILE_OFFSET_BITS=64
+@DEBUG_TRUE@AM_CFLAGS = -D_FILE_OFFSET_BITS=64 -g -DDEBUG -Wall
+@DEBUG_FALSE@AM_CFLAGS = -D_FILE_OFFSET_BITS=64
linux_ntfsincludedir = -I$(top_srcdir)/include
lib_LTLIBRARIES = libntfs.la
libntfs_la_LDFLAGS = -version-info $(LTVERSION)
-libntfs_la_SOURCES = \
- attrib.c \
- bootsect.c \
- debug.c \
- disk_io.c \
- inode.c \
- mft.c \
- mst.c \
- unistr.c \
- volume.c
+libntfs_la_SOURCES = attrib.c bootsect.c debug.c disk_io.c inode.c mft.c mst.c unistr.c volume.c
Index: attrib.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/attrib.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -U2 -r1.34 -r1.35
--- attrib.c 24 Apr 2002 19:02:07 -0000 1.34
+++ attrib.c 24 Apr 2002 23:47:42 -0000 1.35
@@ -1032,5 +1032,6 @@
if (drl[ds].vcn == marker_vcn) {
Dprintf("Old marker = %Li, replacing with "
- "LCN_ENOENT.\n", drl[ds].lcn);
+ "LCN_ENOENT.\n",
+ (long long)drl[ds].lcn);
drl[ds].lcn = (LCN)LCN_ENOENT;
goto finished;
@@ -1332,74 +1333,48 @@
}
-
-// FIXME/TODO: Eeek! (AIA) Have to implement attribute open / close for this!
-#if 0
/**
- * ntfs_map_run_list - map (a part of) a run list of an ntfs inode
- * @ni: ntfs inode for which to map (part of) a run list
+ * ntfs_attr_map_run_list - map (a part of) a run list of an ntfs attribute
+ * @na: ntfs attribute for which to map (part of) a run list
* @vcn: map run list part containing this vcn
*
- * Map the part of a run list containing the @vcn of an the ntfs inode @ni.
+ * Map the part of a run list containing the @vcn of an the ntfs attribute @na.
*
* Return 0 on success and -1 on error with errno set to the error code.
*/
-int ntfs_map_run_list(ntfs_inode *ni, VCN vcn)
+int ntfs_attr_map_run_list(ntfs_attr *na, VCN vcn)
{
- attr_search_context *ctx;
- MFT_RECORD *mrec;
- const uchar_t *name;
- __u32 name_len;
- ATTR_TYPES at;
+ ntfs_attr_search_ctx *ctx;
+ int err;
Dprintf("Mapping run list part containing vcn 0x%Lx.\n",
(long long)vcn);
- ctx = ntfs_get_attr_search_ctx(ni, NULL);
+ ctx = ntfs_get_attr_search_ctx(na->ni, NULL);
if (!ctx)
return -1;
- /*
- * FIXME: Need attribute as parameter!
- * The attribute type is determined from the inode type.
- */
- at = AT_DATA;
- name = NULL;
- name_len = 0;
-
/* Find the attribute in the mft record. */
- if (ntfs_lookup_attr(at, name, name_len, CASE_SENSITIVE, vcn, NULL, 0,
- ctx)) {
- int eo = errno;
- ntfs_put_attr_search_ctx(ctx);
- errno = eo;
- return -1;
- }
-
- // FIXME: This is crap here. Maybe forget about this stuff and just
- // change this function into ntfs_vcn_to_lcn(ni, ntfs_attr, rl, vcn)
- // or something like that?
- /* Make sure someone else didn't do the work. */
- if (vcn_to_lcn(ni->run_list, vcn) <= LCN_RL_NOT_MAPPED) {
+ if (!ntfs_lookup_attr(na->type, na->name, na->name_len, CASE_SENSITIVE,
+ vcn, NULL, 0, ctx)) {
run_list_element *rl;
/* Decode the run list. */
- rl = ntfs_decompress_mapping_pairs(ni->vol, ctx->attr,
- ni->run_list);
- if (!rl) {
- int eo = errno;
+ rl = ntfs_decompress_mapping_pairs(na->ni->vol, ctx->attr,
+ na->rl);
+ if (rl) {
+ na->rl = rl;
+
ntfs_put_attr_search_ctx(ctx);
- errno = eo;
- return -1;
+ return 0;
}
- ni->run_list = rl;
}
+ err = errno;
ntfs_put_attr_search_ctx(ctx);
- return 0;
+ errno = err;
+ return -1;
}
-#endif
-
/**
- * ntfs_vcn_to_lcn - convert a vcn into a lcn given a run list
+ * ntfs_rl_vcn_to_lcn - convert a vcn into a lcn given a run list
* @rl: run list to use for conversion
* @vcn: vcn to convert
@@ -1419,5 +1394,5 @@
* -4 = LCN_EINVAL Input parameter error.
*/
-LCN ntfs_vcn_to_lcn(const run_list_element *rl, const VCN vcn)
+LCN ntfs_rl_vcn_to_lcn(const run_list_element *rl, const VCN vcn)
{
int i;
@@ -1454,4 +1429,52 @@
}
+/**
+ * ntfs_attr_vcn_to_lcn - convert a vcn into a lcn given an ntfs attribute
+ * @na: ntfs attribute whose run list to use for conversion
+ * @vcn: vcn to convert
+ *
+ * Convert the virtual cluster number @vcn of an attribute into a logical
+ * cluster number (lcn) of a device using the run list @na->rl to map vcns to
+ * their corresponding lcns.
+ *
+ * If the @vcn is not mapped yet, attempt to map the attribute extent
+ * containing the @vcn and retry the vcn to lcn conversion.
+ *
+ * Since lcns must be >= 0, we use negative return values with special meaning:
+ *
+ * Return value Meaning / Description
+ * ==========================================
+ * -1 = LCN_HOLE Hole / not allocated on disk.
+ * -3 = LCN_ENOENT There is no such vcn in the attribute.
+ * -4 = LCN_EINVAL Input parameter error.
+ * -5 = LCN_EIO Corrupt fs, disk i/o error, or not enough memory.
+ */
+LCN ntfs_attr_vcn_to_lcn(ntfs_attr *na, const VCN vcn)
+{
+ LCN lcn;
+ BOOL is_retry = FALSE;
+
+ if (!na || !NAttrNonResident(na) || vcn < 0)
+ return (LCN)LCN_EINVAL;
+retry:
+ /* Convert vcn to lcn. If that fails map the run list and retry once. */
+ lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
+ if (lcn >= 0)
+ return lcn;
+ if (!is_retry && !ntfs_attr_map_run_list(na, vcn)) {
+ is_retry = TRUE;
+ goto retry;
+ }
+ /*
+ * If the attempt to map the run list failed, or we are getting
+ * LCN_RL_NOT_MAPPED despite having mapped the attribute extent
+ * successfully, something is really badly wrong...
+ */
+ if (!is_retry || lcn == (LCN)LCN_RL_NOT_MAPPED)
+ return (LCN)LCN_EIO;
+ /* lcn contains the appropriate error code. */
+ return lcn;
+}
+
/*
* Internal function:
@@ -1696,5 +1719,5 @@
ni = ctx->ntfs_ino;
base_ni = ctx->base_ntfs_ino;
- Dprintf("Entering for inode %Lu, type 0x%x.\n",
+ Dprintf("Entering for inode %Lu, attribute type 0x%x.\n",
(unsigned long long)ni->mft_no, type);
if (!base_ni) {
Index: mft.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/mft.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -U2 -r1.23 -r1.24
--- mft.c 22 Apr 2002 10:34:31 -0000 1.23
+++ mft.c 24 Apr 2002 23:47:42 -0000 1.24
@@ -69,5 +69,5 @@
}
/* Starting cluster of the first mft record to read. */
- lcn = ntfs_vcn_to_lcn(vol->mft_rl, m << vol->mft_record_size_bits
+ lcn = ntfs_rl_vcn_to_lcn(vol->mft_rl, m << vol->mft_record_size_bits
>> vol->cluster_size_bits);
/*
@@ -132,5 +132,5 @@
}
/* Starting cluster of the first mft record to write. */
- lcn = ntfs_vcn_to_lcn(vol->mft_rl, m << vol->mft_record_size_bits
+ lcn = ntfs_rl_vcn_to_lcn(vol->mft_rl, m << vol->mft_record_size_bits
>> vol->cluster_size_bits);
/*
|