[PATCH 1/3] RFC quota: add generic quota error handlers.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Quota may becomes inconsistent or corrupted due to number of errors.
If so, we have to print unified error message (unified means that it
may be grepped from dmesg easily) and allow corresponding filesystem
to know about possible quota inconsistency. Later filesystem will
make a decision about forced fsck or quotacheck.

IMHO it is reasonable to consider a possibility to add new field to
on_disk quota header where error_state may be stored to signal
that quota-file's data is probably incorrect.

Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx>
---
 fs/quota/dquot.c      |   49 +++++++++++++++++++++--------
 fs/quota/netlink.c    |    8 ++--
 fs/quota/quota.c      |   35 +++++++++++++++++++++
 fs/quota/quota_tree.c |   80 +++++++++++++++++++++++++------------------------
 fs/quota/quota_v1.c   |    9 ++---
 fs/quota/quota_v2.c   |   12 ++-----
 include/linux/quota.h |   18 ++++++++++-
 7 files changed, 140 insertions(+), 71 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index e0b870f..c8202ea 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -697,9 +697,8 @@ void dqput(struct dquot *dquot)
 		return;
 #ifdef __DQUOT_PARANOIA
 	if (!atomic_read(&dquot->dq_count)) {
-		printk("VFS: dqput: trying to free free dquot\n");
-		printk("VFS: device %s, dquot of %s %d\n",
-			dquot->dq_sb->s_id,
+		quota_error(dquot->dq_sb, "Trying to free free dquot"
+			" of %s %d",
 			quotatypes[dquot->dq_type],
 			dquot->dq_id);
 		BUG();
@@ -727,9 +726,9 @@ we_slept:
 		/* Commit dquot before releasing */
 		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
 		if (ret < 0) {
-			printk(KERN_ERR "VFS: cannot write quota structure on "
-				"device %s (error %d). Quota may get out of "
-				"sync!\n", dquot->dq_sb->s_id, ret);
+			quota_error(dquot->dq_sb, "Cannot write quota "
+				"structure (error %d). Quota may get out of "
+				"sync!", ret);
 			/*
 			 * We clear dirty bit anyway, so that we avoid
 			 * infinite loop here
@@ -904,9 +903,9 @@ static void add_dquot_ref(struct super_block *sb, int type)
 	iput(old_inode);
 
 	if (reserved) {
-		printk(KERN_WARNING "VFS (%s): Writes happened before quota"
-			" was turned on thus quota information is probably "
-			"inconsistent. Please run quotacheck(8).\n", sb->s_id);
+		quota_error(sb, "Writes happened before quota was turned on"
+			" thus quota information is probably inconsistent. "
+			"Please run quotacheck(8).");
 	}
 }
 
@@ -936,7 +935,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
 		if (dqput_blocks(dquot)) {
 #ifdef __DQUOT_PARANOIA
 			if (atomic_read(&dquot->dq_count) != 1)
-				printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
+				quota_warning(dquot->dq_sb, "Adding dquot with dq_count %d to dispose list.", atomic_read(&dquot->dq_count));
 #endif
 			spin_lock(&dq_list_lock);
 			/* As dquot must have currently users it can't be on
@@ -1023,8 +1022,12 @@ static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
  */
 static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number)
 {
-	if (dquot->dq_dqb.dqb_rsvspace < number) {
-		WARN_ON_ONCE(1);
+	if (unlikely(dquot->dq_dqb.dqb_rsvspace < number)) {
+		quota_error(dquot->dq_sb, "Incorrect quota reservation "
+			"for quota id:%d, rsvspace:%lld, claim:%lld, "
+			"thus quota information is probably inconsistent. "
+			"Please run quotacheck(8).",
+			dquot->dq_id, dquot->dq_dqb.dqb_rsvspace, number);
 		number = dquot->dq_dqb.dqb_rsvspace;
 	}
 	dquot->dq_dqb.dqb_curspace += number;
@@ -1034,10 +1037,14 @@ static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number)
 static inline
 void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
 {
-	if (dquot->dq_dqb.dqb_rsvspace >= number)
+	if (likely(dquot->dq_dqb.dqb_rsvspace >= number))
 		dquot->dq_dqb.dqb_rsvspace -= number;
 	else {
-		WARN_ON_ONCE(1);
+		quota_error(dquot->dq_sb, "Incorrect quota reservation "
+			"for quota id:%d, rsvspace:%lld, free:%lld, "
+			"thus quota information is probably inconsistent. "
+			"Please run quotacheck(8).",
+			dquot->dq_id, dquot->dq_dqb.dqb_rsvspace, number);
 		dquot->dq_dqb.dqb_rsvspace = 0;
 	}
 }
@@ -1428,6 +1435,13 @@ EXPORT_SYMBOL(inode_add_rsv_space);
 void inode_claim_rsv_space(struct inode *inode, qsize_t number)
 {
 	spin_lock(&inode->i_lock);
+	if (unlikely(*inode_reserved_space(inode) < number)) {
+		quota_error(inode->i_sb, "Incorrect quota reservation "
+			"for inode:%ld, rsvspace:%lld, claim:%lld,"
+			"hus quota  information is probably inconsistent. "
+			"Please run quotacheck(8).", inode->i_ino,
+			*inode_reserved_space(inode), number);
+	}
 	*inode_reserved_space(inode) -= number;
 	__inode_add_bytes(inode, number);
 	spin_unlock(&inode->i_lock);
@@ -1437,6 +1451,13 @@ EXPORT_SYMBOL(inode_claim_rsv_space);
 void inode_sub_rsv_space(struct inode *inode, qsize_t number)
 {
 	spin_lock(&inode->i_lock);
+	if (unlikely(*inode_reserved_space(inode) < number)) {
+		quota_error(inode->i_sb, "Incorrect quota reservation "
+			"for inode:%ld, rsvspace:%lld, free:%lld,"
+			"hus quota  information is probably inconsistent. "
+			"Please run quotacheck(8).", inode->i_ino,
+			*inode_reserved_space(inode), number);
+	}
 	*inode_reserved_space(inode) -= number;
 	spin_unlock(&inode->i_lock);
 }
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index 2663ed9..0865ae3 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -45,14 +45,14 @@ void quota_send_warning(short type, unsigned int id, dev_t dev,
 	skb = genlmsg_new(msg_size, GFP_NOFS);
 	if (!skb) {
 		printk(KERN_ERR
-		  "VFS: Not enough memory to send quota warning.\n");
+		  "QUOTA: Not enough memory to send quota warning.\n");
 		return;
 	}
 	msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
 			&quota_genl_family, 0, QUOTA_NL_C_WARNING);
 	if (!msg_head) {
 		printk(KERN_ERR
-		  "VFS: Cannot store netlink header in quota warning.\n");
+		  "QUOTA: Cannot store netlink header in quota warning.\n");
 		goto err_out;
 	}
 	ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
@@ -78,7 +78,7 @@ void quota_send_warning(short type, unsigned int id, dev_t dev,
 	genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
 	return;
 attr_err_out:
-	printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
+	printk(KERN_ERR "QUOTA: Not enough space to compose quota message!\n");
 err_out:
 	kfree_skb(skb);
 }
@@ -88,7 +88,7 @@ static int __init quota_init(void)
 {
 	if (genl_register_family(&quota_genl_family) != 0)
 		printk(KERN_ERR
-		       "VFS: Failed to create quota netlink interface.\n");
+		       "QUOTA: Failed to create quota netlink interface.\n");
 	return 0;
 };
 
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 95388f9..ebdce30 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -19,6 +19,41 @@
 #include <linux/types.h>
 #include <linux/writeback.h>
 
+static void quota_handle_error(struct super_block *sb)
+{
+
+	set_bit(_DQUOT_ERROR, &sb_dqopt(sb)->flags);
+	/* XXX: Currently it is no impossible to signall fs about error */
+}
+
+void __quota_error(struct super_block * sb, const char * function,
+		const char * fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	printk(KERN_CRIT "QUOTA: error (device %s): %s: ",sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
+
+	quota_handle_error(sb);
+}
+EXPORT_SYMBOL(__quota_error);
+
+void __quota_warning(struct super_block * sb, const char * func,
+		const char * fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	printk(KERN_WARNING "QUOTA: warning (device %s): %s: ",sb->s_id, func);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
+}
+EXPORT_SYMBOL(__quota_warning);
+
 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
 				     qid_t id)
 {
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
index f81f4bc..da0de94 100644
--- a/fs/quota/quota_tree.c
+++ b/fs/quota/quota_tree.c
@@ -44,7 +44,7 @@ static char *getdqbuf(size_t size)
 	char *buf = kmalloc(size, GFP_NOFS);
 	if (!buf)
 		printk(KERN_WARNING
-		       "VFS: Not enough memory for quota buffers.\n");
+		       "VFS: Not enough memory for quota buffers.");
 	return buf;
 }
 
@@ -152,8 +152,8 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
 	dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
 	/* No matter whether write succeeds block is out of list */
 	if (write_blk(info, blk, buf) < 0)
-		printk(KERN_ERR
-		       "VFS: Can't write block (%u) with free entries.\n",
+		quota_error(info->dqi_sb,
+			"Can't write block (%u) with free entries.",
 		       blk);
 	return 0;
 out_buf:
@@ -244,9 +244,8 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
 	if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) {
 		*err = remove_free_dqentry(info, buf, blk);
 		if (*err < 0) {
-			printk(KERN_ERR "VFS: find_free_dqentry(): Can't "
-			       "remove block (%u) from entry free list.\n",
-			       blk);
+			quota_error(info->dqi_sb, "Can't remove block (%u) "
+				"from entry free list.", blk);
 			goto out_buf;
 		}
 	}
@@ -260,16 +259,15 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
 	}
 #ifdef __QUOTA_QT_PARANOIA
 	if (i == qtree_dqstr_in_blk(info)) {
-		printk(KERN_ERR "VFS: find_free_dqentry(): Data block full "
-				"but it shouldn't.\n");
+		quota_error(info->dqi_sb, "Data block full but it shouldn't.");
 		*err = -EIO;
 		goto out_buf;
 	}
 #endif
 	*err = write_blk(info, blk, buf);
 	if (*err < 0) {
-		printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota "
-				"data block %u.\n", blk);
+		quota_error(info->dqi_sb,"Can't write quota data block %u.",
+			blk);
 		goto out_buf;
 	}
 	dquot->dq_off = (blk << info->dqi_blocksize_bits) +
@@ -303,8 +301,8 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 	} else {
 		ret = read_blk(info, *treeblk, buf);
 		if (ret < 0) {
-			printk(KERN_ERR "VFS: Can't read tree quota block "
-					"%u.\n", *treeblk);
+			quota_error(info->dqi_sb, "Can't read tree quota "
+				"block %u.", *treeblk);
 			goto out_buf;
 		}
 	}
@@ -315,8 +313,8 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 	if (depth == info->dqi_qtree_depth - 1) {
 #ifdef __QUOTA_QT_PARANOIA
 		if (newblk) {
-			printk(KERN_ERR "VFS: Inserting already present quota "
-					"entry (block %u).\n",
+			quota_error(info->dqi_sb,"Inserting already present "
+				"quota entry (block %u).",
 			       le32_to_cpu(ref[get_index(info,
 						dquot->dq_id, depth)]));
 			ret = -EIO;
@@ -365,8 +363,8 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 	if (!dquot->dq_off) {
 		ret = dq_insert_tree(info, dquot);
 		if (ret < 0) {
-			printk(KERN_ERR "VFS: Error %zd occurred while "
-					"creating quota.\n", ret);
+			quota_error(info->dqi_sb, "Error %zd occurred while "
+					"creating quota.", ret);
 			kfree(ddquot);
 			return ret;
 		}
@@ -377,8 +375,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 	ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
 				    dquot->dq_off);
 	if (ret != info->dqi_entry_size) {
-		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
-		       sb->s_id);
+		quota_error(info->dqi_sb,"Dquota write failed");
 		if (ret >= 0)
 			ret = -ENOSPC;
 	} else {
@@ -402,14 +399,15 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 	if (!buf)
 		return -ENOMEM;
 	if (dquot->dq_off >> info->dqi_blocksize_bits != blk) {
-		printk(KERN_ERR "VFS: Quota structure has offset to other "
-		  "block (%u) than it should (%u).\n", blk,
+		quota_error(info->dqi_sb, "Quota structure has offset to other "
+		  "block (%u) than it should (%u).", blk,
 		  (uint)(dquot->dq_off >> info->dqi_blocksize_bits));
 		goto out_buf;
 	}
 	ret = read_blk(info, blk, buf);
 	if (ret < 0) {
-		printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
+		quota_error(info->dqi_sb, "Can't read quota data block %u",
+			blk);
 		goto out_buf;
 	}
 	dh = (struct qt_disk_dqdbheader *)buf;
@@ -419,8 +417,8 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 		if (ret >= 0)
 			ret = put_free_dqblk(info, buf, blk);
 		if (ret < 0) {
-			printk(KERN_ERR "VFS: Can't move quota data block (%u) "
-			  "to free list.\n", blk);
+			quota_error(info->dqi_sb, "Can't move quota data block"
+				" (%u) to free list.", blk);
 			goto out_buf;
 		}
 	} else {
@@ -432,15 +430,16 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 			/* Insert will write block itself */
 			ret = insert_free_dqentry(info, buf, blk);
 			if (ret < 0) {
-				printk(KERN_ERR "VFS: Can't insert quota data "
-				       "block (%u) to free entry list.\n", blk);
+				quota_error(info->dqi_sb, "Can't insert quota "
+					"data block (%u) to free entry list.",
+					blk);
 				goto out_buf;
 			}
 		} else {
 			ret = write_blk(info, blk, buf);
 			if (ret < 0) {
-				printk(KERN_ERR "VFS: Can't write quota data "
-				  "block %u\n", blk);
+				quota_error(info->dqi_sb, "Can't write quota "
+					"data block %u", blk);
 				goto out_buf;
 			}
 		}
@@ -464,7 +463,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 		return -ENOMEM;
 	ret = read_blk(info, *blk, buf);
 	if (ret < 0) {
-		printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
+		quota_error(info->dqi_sb, "Can't read quota data block %u",
+			*blk);
 		goto out_buf;
 	}
 	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
@@ -488,8 +488,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
 		} else {
 			ret = write_blk(info, *blk, buf);
 			if (ret < 0)
-				printk(KERN_ERR "VFS: Can't write quota tree "
-				  "block %u.\n", *blk);
+				quota_error(info->dqi_sb, "Can't write quota "
+					"tree block %u.", *blk);
 		}
 	}
 out_buf:
@@ -521,7 +521,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
 		return -ENOMEM;
 	ret = read_blk(info, blk, buf);
 	if (ret < 0) {
-		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
+		quota_error(info->dqi_sb, "Can't read quota tree block %u.",
+			blk);
 		goto out_buf;
 	}
 	ddquot = buf + sizeof(struct qt_disk_dqdbheader);
@@ -531,8 +532,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
 		ddquot += info->dqi_entry_size;
 	}
 	if (i == qtree_dqstr_in_blk(info)) {
-		printk(KERN_ERR "VFS: Quota for id %u referenced "
-		  "but not present.\n", dquot->dq_id);
+		quota_error(info->dqi_sb, "Quota for id %u referenced "
+		  "but not present.", dquot->dq_id);
 		ret = -EIO;
 		goto out_buf;
 	} else {
@@ -556,7 +557,8 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
 		return -ENOMEM;
 	ret = read_blk(info, blk, buf);
 	if (ret < 0) {
-		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
+		quota_error(info->dqi_sb, "Can't read quota tree block %u.",
+			blk);
 		goto out_buf;
 	}
 	ret = 0;
@@ -590,7 +592,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 #ifdef __QUOTA_QT_PARANOIA
 	/* Invalidated quota? */
 	if (!sb_dqopt(dquot->dq_sb)->files[type]) {
-		printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
+		quota_error(info->dqi_sb, "Quota invalidated while reading!");
 		return -EIO;
 	}
 #endif
@@ -599,8 +601,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 		offset = find_dqentry(info, dquot);
 		if (offset <= 0) {	/* Entry not present? */
 			if (offset < 0)
-				printk(KERN_ERR "VFS: Can't read quota "
-				  "structure for id %u.\n", dquot->dq_id);
+				quota_error(info->dqi_sb, "Can't read quota "
+				  "structure for id %u.", dquot->dq_id);
 			dquot->dq_off = 0;
 			set_bit(DQ_FAKE_B, &dquot->dq_flags);
 			memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
@@ -617,8 +619,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 	if (ret != info->dqi_entry_size) {
 		if (ret >= 0)
 			ret = -EIO;
-		printk(KERN_ERR "VFS: Error while reading quota "
-				"structure for id %u.\n", dquot->dq_id);
+		quota_error(info->dqi_sb, "Error while reading quota "
+				"structure for id %u.", dquot->dq_id);
 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
 		kfree(ddquot);
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c
index 2ae757e..7a6cad0 100644
--- a/fs/quota/quota_v1.c
+++ b/fs/quota/quota_v1.c
@@ -95,8 +95,7 @@ static int v1_commit_dqblk(struct dquot *dquot)
 			(char *)&dqblk, sizeof(struct v1_disk_dqblk),
 			v1_dqoff(dquot->dq_id));
 	if (ret != sizeof(struct v1_disk_dqblk)) {
-		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
-			dquot->dq_sb->s_id);
+		quota_error(dquot->dq_sb, "dquota write failed");
 		if (ret >= 0)
 			ret = -EIO;
 		goto out;
@@ -147,9 +146,9 @@ static int v1_check_quota_file(struct super_block *sb, int type)
 		return 1;	/* Probably not new format */
 	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
 		return 1;	/* Definitely not new format */
-	printk(KERN_INFO
-	       "VFS: %s: Refusing to turn on old quota format on given file."
-	       " It probably contains newer quota format.\n", sb->s_id);
+	quota_warning(sb,
+	       "Refusing to turn on old quota format on given file."
+	       " It probably contains newer quota format.\n",);
         return 0;		/* Seems like a new format file -> refuse it */
 }
 
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index e3da02f..a1246c9 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -63,8 +63,7 @@ static int v2_read_header(struct super_block *sb, int type,
 	size = sb->s_op->quota_read(sb, type, (char *)dqhead,
 				    sizeof(struct v2_disk_dqheader), 0);
 	if (size != sizeof(struct v2_disk_dqheader)) {
-		printk(KERN_WARNING "quota_v2: Failed header read:"
-		       " expected=%zd got=%zd\n",
+		quota_error(sb, "Failed header read: expected=%zd got=%zd",
 			sizeof(struct v2_disk_dqheader), size);
 		return 0;
 	}
@@ -106,14 +105,12 @@ static int v2_read_file_info(struct super_block *sb, int type)
 	size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
 	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
-		printk(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n",
-			sb->s_id);
+		quota_error(sb, "Can't read info structure");
 		return -1;
 	}
 	info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS);
 	if (!info->dqi_priv) {
-		printk(KERN_WARNING
-		       "Not enough memory for quota information structure.\n");
+		quota_error(sb, "Not enough memory for quota information structure.");
 		return -1;
 	}
 	qinfo = info->dqi_priv;
@@ -167,8 +164,7 @@ static int v2_write_file_info(struct super_block *sb, int type)
 	size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
 	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
-		printk(KERN_WARNING "Can't write info structure on device %s.\n",
-			sb->s_id);
+		quota_error(sb, "Can't write info structure");
 		return -1;
 	}
 	return 0;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index b462916..b488e6f 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -351,6 +351,11 @@ enum {
 						 */
 #define DQUOT_NEGATIVE_USAGE	(1 << (DQUOT_STATE_LAST + 1))
 					       /* Allow negative quota usage */
+#define _DQUOT_ERROR		(DQUOT_STATE_LAST + 2)
+#define DQUOT_ERROR		(1 << _DQUOT_ERROR)
+				/* Quota may be inconsistent or corrupted */
+
+
 
 static inline unsigned int dquot_state_flag(unsigned int flags, int type)
 {
@@ -362,6 +367,17 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
 	return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
 }
 
+extern void __quota_error(struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+
+extern void __quota_warning(struct super_block *, const char *,
+			const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+
+#define quota_error(sb, fmt, arg...) __quota_error(sb, __func__, fmt, ##arg)
+#define quota_warning(sb, fm, arg...) __quota_warning(sb, __func__, fm, ##arg)
+
+
 #ifdef CONFIG_QUOTA_NETLINK_INTERFACE
 extern void quota_send_warning(short type, unsigned int id, dev_t dev,
 			       const char warntype);
@@ -374,7 +390,7 @@ static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
 #endif /* CONFIG_QUOTA_NETLINK_INTERFACE */
 
 struct quota_info {
-	unsigned int flags;			/* Flags for diskquotas on this device */
+	unsigned long flags;			/* Flags for diskquotas on this device */
 	struct mutex dqio_mutex;		/* lock device while I/O in progress */
 	struct mutex dqonoff_mutex;		/* Serialize quotaon & quotaoff */
 	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */
-- 
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux