quota: check quota reservation on remove_dquot_ref
Dmitry Monakhov [Tue, 1 Jun 2010 07:39:48 +0000 (11:39 +0400)]
Reserved space must being claimed before remove_dquot_ref() for a
given inode. Filesystem is responsible for performing force blocks
allocation in case of dealloc in ->quota_off. Let's add sanity check
for that case. Do it similar to add_dquot_ref().

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Jan Kara <jack@suse.cz>

fs/quota/dquot.c

index 12c233d..a5974c4 100644 (file)
@@ -986,6 +986,7 @@ static void remove_dquot_ref(struct super_block *sb, int type,
                struct list_head *tofree_head)
 {
        struct inode *inode;
+       int reserved = 0;
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
@@ -995,10 +996,20 @@ static void remove_dquot_ref(struct super_block *sb, int type,
                 *  only quota pointers and these have separate locking
                 *  (dqptr_sem).
                 */
-               if (!IS_NOQUOTA(inode))
+               if (!IS_NOQUOTA(inode)) {
+                       if (unlikely(inode_get_rsv_space(inode) > 0))
+                               reserved = 1;
                        remove_inode_dquot_ref(inode, type, tofree_head);
+               }
        }
        spin_unlock(&inode_lock);
+#ifdef CONFIG_QUOTA_DEBUG
+       if (reserved) {
+               printk(KERN_WARNING "VFS (%s): Writes happened after quota"
+                       " was disabled thus quota information is probably "
+                       "inconsistent. Please run quotacheck(8).\n", sb->s_id);
+       }
+#endif
 }
 
 /* Gather all references from inodes and drop them */