NTFS: Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
authorAnton Altaparmakov <aia21@cantab.net>
Thu, 8 Sep 2005 19:40:32 +0000 (20:40 +0100)
committerAnton Altaparmakov <aia21@cantab.net>
Thu, 8 Sep 2005 19:40:32 +0000 (20:40 +0100)
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
fs/ntfs/ChangeLog
fs/ntfs/attrib.c
fs/ntfs/attrib.h

index 96224c0207977054ef2ffc7c82ae441949efa616..29841bf82264ba5ddae2140e86e9c71ba3206f9d 100644 (file)
@@ -59,6 +59,7 @@ ToDo/Notes:
          index entry is in the index root, we forgot to set the @ir pointer in
          the index context.  Thanks to Yura Pakhuchiy for finding this bug.
        - Remove bogus setting of PageError in ntfs_read_compressed_block().
+       - Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
         many bug fixes, cleanups, and enhancements...
index cd0f9e740b149c5664b56a5872f1a6203df102c1..79dda398068443fe96084a1c2abe4b3617b80d7f 100644 (file)
@@ -1246,6 +1246,46 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
        return 0;
 }
 
+/**
+ * ntfs_resident_attr_value_resize - resize the value of a resident attribute
+ * @m:         mft record containing attribute record
+ * @a:         attribute record whose value to resize
+ * @new_size:  new size in bytes to which to resize the attribute value of @a
+ *
+ * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
+ * If the value is made bigger, the newly allocated space is cleared.
+ *
+ * Return 0 on success and -errno on error.  The following error codes are
+ * defined:
+ *     -ENOSPC - Not enough space in the mft record @m to perform the resize.
+ *
+ * Note: On error, no modifications have been performed whatsoever.
+ *
+ * Warning: If you make a record smaller without having copied all the data you
+ *         are interested in the data may be overwritten.
+ */
+int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+               const u32 new_size)
+{
+       u32 old_size;
+
+       /* Resize the resident part of the attribute record. */
+       if (ntfs_attr_record_resize(m, a,
+                       le16_to_cpu(a->data.resident.value_offset) + new_size))
+               return -ENOSPC;
+       /*
+        * The resize succeeded!  If we made the attribute value bigger, clear
+        * the area between the old size and @new_size.
+        */
+       old_size = le32_to_cpu(a->data.resident.value_length);
+       if (new_size > old_size)
+               memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
+                               old_size, 0, new_size - old_size);
+       /* Finally update the length of the attribute value. */
+       a->data.resident.value_length = cpu_to_le32(new_size);
+       return 0;
+}
+
 /**
  * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
  * @ni:                ntfs inode describing the attribute to convert
index 0e4ac6d3c0e740f123d952de8970389de5163cbe..0618ed6fd7b35de101192db0a058baffd99158cf 100644 (file)
@@ -99,6 +99,8 @@ extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
                const ATTR_TYPE type);
 
 extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
+extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+               const u32 new_size);
 
 extern int ntfs_attr_make_non_resident(ntfs_inode *ni);