]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/fat/inode.c
fat: add fat_fallocate operation
[karo-tx-linux.git] / fs / fat / inode.c
index 5b2cb358748da160abaa6267c16c555af3998bff..d08f7ab0ae88e7afa65f17f8cdcbeca8ed730208 100644 (file)
@@ -554,12 +554,34 @@ out:
 
 EXPORT_SYMBOL_GPL(fat_build_inode);
 
+static int __fat_write_inode(struct inode *inode, int wait);
 static void fat_evict_inode(struct inode *inode)
 {
        truncate_inode_pages_final(&inode->i_data);
        if (!inode->i_nlink) {
                inode->i_size = 0;
                fat_truncate_blocks(inode, 0);
+       } else {
+               /* Release unwritten fallocated blocks on inode eviction. */
+               if (MSDOS_I(inode)->i_disksize >
+                   round_up(MSDOS_I(inode)->mmu_private,
+                               inode->i_sb->s_blocksize)) {
+                       int err;
+                       fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
+                       /* Fallocate results in updating the i_start/iogstart
+                        * for the zero byte file. So, make it return to
+                        * original state during evict and commit it to avoid
+                        * any corruption on the next access to the cluster
+                        * chain for the file.
+                        */
+                       err = __fat_write_inode(inode, inode_needs_sync(inode));
+                       if (err) {
+                               fat_msg(inode->i_sb, KERN_WARNING, "Failed to "
+                               "update on disk inode for unused fallocated "
+                               "blocks, inode could be corrupted. Please run "
+                               "fsck");
+                       }
+               }
        }
        invalidate_inode_buffers(inode);
        clear_inode(inode);