NTFS: Make ntfs_write_block() not instantiate sparse blocks if they are zero.
authorAnton Altaparmakov <aia21@cantab.net>
Thu, 8 Sep 2005 20:25:48 +0000 (21:25 +0100)
committerAnton Altaparmakov <aia21@cantab.net>
Thu, 8 Sep 2005 20:25:48 +0000 (21:25 +0100)
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
fs/ntfs/ChangeLog
fs/ntfs/aops.c

index ed8d00150931d52e5a849a9b7f3e1f4076698531..b1766642baf84d2575444dfcd406c581fdca82d2 100644 (file)
@@ -77,6 +77,8 @@ ToDo/Notes:
          updating the times in the inode in ntfs_setattr().
        - Fixup handling of sparse, compressed, and encrypted attributes in
          fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
+       - Make ntfs_write_block() not instantiate sparse blocks if they contain
+         only zeroes.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
         many bug fixes, cleanups, and enhancements...
index 78adad7a988d981a22f61b739cc082071ddc8513..f3ad36d8b8c97b220b700914ecab9401c552c151 100644 (file)
@@ -670,6 +670,27 @@ lock_retry_remap:
                }
                /* It is a hole, need to instantiate it. */
                if (lcn == LCN_HOLE) {
+                       u8 *kaddr;
+                       unsigned long *bpos, *bend;
+
+                       /* Check if the buffer is zero. */
+                       kaddr = kmap_atomic(page, KM_USER0);
+                       bpos = (unsigned long *)(kaddr + bh_offset(bh));
+                       bend = (unsigned long *)((u8*)bpos + blocksize);
+                       do {
+                               if (unlikely(*bpos))
+                                       break;
+                       } while (likely(++bpos < bend));
+                       kunmap_atomic(kaddr, KM_USER0);
+                       if (bpos == bend) {
+                               /*
+                                * Buffer is zero and sparse, no need to write
+                                * it.
+                                */
+                               bh->b_blocknr = -1;
+                               clear_buffer_dirty(bh);
+                               continue;
+                       }
                        // TODO: Instantiate the hole.
                        // clear_buffer_new(bh);
                        // unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);