⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2.6.5-quotafix.patch

📁 非常经典的一个分布式系统
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
 	int ret = 0, newson = 0, newact = 0; 	u32 *ref;@@ -358,7 +337,7 @@ static int do_insert_tree(struct dquot * 	if (!(buf = getdqbuf())) 		return -ENOMEM; 	if (!*treeblk) {-		ret = get_free_dqblk(filp, info);+		ret = get_free_dqblk(sb, dquot->dq_type); 		if (ret < 0) 			goto out_buf; 		*treeblk = ret;@@ -366,7 +345,7 @@ static int do_insert_tree(struct dquot * 		newact = 1; 	} 	else {-		if ((ret = read_blk(filp, *treeblk, buf)) < 0) {+		if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) { 			printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk); 			goto out_buf; 		}@@ -389,10 +368,10 @@ static int do_insert_tree(struct dquot * 		ret = do_insert_tree(dquot, &newblk, depth+1); 	if (newson && ret >= 0) { 		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);-		ret = write_blk(filp, *treeblk, buf);+		ret = write_blk(sb, dquot->dq_type, *treeblk, buf); 	} 	else if (newact && ret < 0)-		put_free_dqblk(filp, info, buf, *treeblk);+		put_free_dqblk(sb, dquot->dq_type, buf, *treeblk); out_buf: 	freedqbuf(buf); 	return ret;@@ -411,19 +390,14 @@ static inline int dq_insert_tree(struct  static int v2_write_dquot(struct dquot *dquot) { 	int type = dquot->dq_type;-	struct file *filp;-	mm_segment_t fs;-	loff_t offset; 	ssize_t ret; 	struct v2_disk_dqblk ddquot, empty;  	if (!dquot->dq_off) 		if ((ret = dq_insert_tree(dquot)) < 0) {-			printk(KERN_ERR "VFS: Error %Zd occurred while creating quota.\n", ret);+			printk(KERN_ERR "VFS: Error %d occurred while creating quota.\n", ret); 			return ret; 		}-	filp = sb_dqopt(dquot->dq_sb)->files[type];-	offset = dquot->dq_off; 	mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id); 	/* Argh... We may need to write structure full of zeroes but that would be 	 * treated as an empty place by the rest of the code. Format change would@@ -431,10 +405,10 @@ static int v2_write_dquot(struct dquot * 	memset(&empty, 0, sizeof(struct v2_disk_dqblk)); 	if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk))) 		ddquot.dqb_itime = cpu_to_le64(1);-	fs = get_fs();-	set_fs(KERNEL_DS);-	ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset);-	set_fs(fs);+	+	ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,+			(char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);+ 	if (ret != sizeof(struct v2_disk_dqblk)) { 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id); 		if (ret >= 0)@@ -450,8 +424,8 @@ static int v2_write_dquot(struct dquot * /* Free dquot entry in data block */ static int free_dqentry(struct dquot *dquot, uint blk) {-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];-	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type;+	struct super_block *sb = dquot->dq_sb;+	int type = dquot->dq_type; 	struct v2_disk_dqdbheader *dh; 	dqbuf_t buf = getdqbuf(); 	int ret = 0;@@ -459,34 +433,39 @@ static int free_dqentry(struct dquot *dq 	if (!buf) 		return -ENOMEM; 	if (dquot->dq_off >> V2_DQBLKSIZE_BITS != blk) {-		printk(KERN_ERR "VFS: Quota structure has offset to other block (%u) than it should (%u).\n", blk, (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));+		printk(KERN_ERR "VFS: Quota structure has offset to other "+				"block (%u) than it should (%u).\n", blk,+				(uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS)); 		goto out_buf; 	}-	if ((ret = read_blk(filp, blk, buf)) < 0) {+	if ((ret = read_blk(sb, type, blk, buf)) < 0) { 		printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); 		goto out_buf; 	} 	dh = (struct v2_disk_dqdbheader *)buf; 	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1); 	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */-		if ((ret = remove_free_dqentry(filp, info, buf, blk)) < 0 ||-		    (ret = put_free_dqblk(filp, info, buf, blk)) < 0) {-			printk(KERN_ERR "VFS: Can't move quota data block (%u) to free list.\n", blk);+		if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||+				(ret = put_free_dqblk(sb, type, buf, blk)) < 0) {+			printk(KERN_ERR "VFS: Can't move quota data block (%u) "+					"to free list.\n", blk); 			goto out_buf; 		} 	} 	else {-		memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0, sizeof(struct v2_disk_dqblk));+		memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0, +				sizeof(struct v2_disk_dqblk)); 		if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) { 			/* Insert will write block itself */-			if ((ret = insert_free_dqentry(filp, info, buf, blk)) < 0) {+			if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) { 				printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk); 				goto out_buf; 			} 		} 		else-			if ((ret = write_blk(filp, blk, buf)) < 0) {-				printk(KERN_ERR "VFS: Can't write quota data block %u\n", blk);+			if ((ret = write_blk(sb, type, blk, buf)) < 0) {+				printk(KERN_ERR "VFS: Can't write quota data "+						"block %u\n", blk); 				goto out_buf; 			} 	}@@ -499,8 +478,8 @@ out_buf: /* Remove reference to dquot from tree */ static int remove_tree(struct dquot *dquot, uint *blk, int depth) {-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];-	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type;+	struct super_block *sb = dquot->dq_sb;+	int type = dquot->dq_type; 	dqbuf_t buf = getdqbuf(); 	int ret = 0; 	uint newblk;@@ -508,7 +487,7 @@ static int remove_tree(struct dquot *dqu 	 	if (!buf) 		return -ENOMEM;-	if ((ret = read_blk(filp, *blk, buf)) < 0) {+	if ((ret = read_blk(sb, type, *blk, buf)) < 0) { 		printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); 		goto out_buf; 	}@@ -524,12 +503,13 @@ static int remove_tree(struct dquot *dqu 		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0); 		for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++);	/* Block got empty? */ 		if (i == V2_DQBLKSIZE) {-			put_free_dqblk(filp, info, buf, *blk);+			put_free_dqblk(sb, type, buf, *blk); 			*blk = 0; 		} 		else-			if ((ret = write_blk(filp, *blk, buf)) < 0)-				printk(KERN_ERR "VFS: Can't write quota tree block %u.\n", *blk);+			if ((ret = write_blk(sb, type, *blk, buf)) < 0)+				printk(KERN_ERR "VFS: Can't write quota tree "+						"block %u.\n", *blk); 	} out_buf: 	freedqbuf(buf);@@ -549,7 +529,6 @@ static int v2_delete_dquot(struct dquot  /* Find entry in block */ static loff_t find_block_dqentry(struct dquot *dquot, uint blk) {-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; 	dqbuf_t buf = getdqbuf(); 	loff_t ret = 0; 	int i;@@ -557,27 +536,31 @@ static loff_t find_block_dqentry(struct   	if (!buf) 		return -ENOMEM;-	if ((ret = read_blk(filp, blk, buf)) < 0) {+	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) { 		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); 		goto out_buf; 	} 	if (dquot->dq_id)-		for (i = 0; i < V2_DQSTRINBLK && le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);+		for (i = 0; i < V2_DQSTRINBLK &&+				le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++); 	else {	/* ID 0 as a bit more complicated searching... */ 		struct v2_disk_dqblk fakedquot;  		memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk)); 		for (i = 0; i < V2_DQSTRINBLK; i++)-			if (!le32_to_cpu(ddquot[i].dqb_id) && memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))+			if (!le32_to_cpu(ddquot[i].dqb_id) &&+					memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk))) 				break; 	} 	if (i == V2_DQSTRINBLK) {-		printk(KERN_ERR "VFS: Quota for id %u referenced but not present.\n", dquot->dq_id);+		printk(KERN_ERR "VFS: Quota for id %u referenced "+				"but not present.\n", dquot->dq_id); 		ret = -EIO; 		goto out_buf; 	} 	else-		ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);+		ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct+				v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk); out_buf: 	freedqbuf(buf); 	return ret;@@ -586,14 +569,13 @@ out_buf: /* Find entry for given id in the tree */ static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth) {-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; 	dqbuf_t buf = getdqbuf(); 	loff_t ret = 0; 	u32 *ref = (u32 *)buf;  	if (!buf) 		return -ENOMEM;-	if ((ret = read_blk(filp, blk, buf)) < 0) {+	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) { 		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); 		goto out_buf; 	}@@ -619,16 +601,13 @@ static inline loff_t find_dqentry(struct static int v2_read_dquot(struct dquot *dquot) { 	int type = dquot->dq_type;-	struct file *filp;-	mm_segment_t fs; 	loff_t offset; 	struct v2_disk_dqblk ddquot, empty; 	int ret = 0; -	filp = sb_dqopt(dquot->dq_sb)->files[type];- #ifdef __QUOTA_V2_PARANOIA-	if (!filp || !dquot->dq_sb) {	/* Invalidated quota? */+	/* Invalidated quota? */+	if (!dquot->dq_sb || !dquot->dq_sb->s_op->quota_read) { 		printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); 		return -EIO; 	}@@ -636,7 +615,8 @@ static int v2_read_dquot(struct dquot *d 	offset = find_dqentry(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);+			printk(KERN_ERR "VFS: Can't read quota "+			  "structure for id %u.\n", dquot->dq_id); 		dquot->dq_off = 0; 		dquot->dq_flags |= DQ_FAKE; 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));@@ -644,12 +624,13 @@ static int v2_read_dquot(struct dquot *d 	} 	else { 		dquot->dq_off = offset;-		fs = get_fs();-		set_fs(KERNEL_DS);-		if ((ret = filp->f_op->read(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset)) != sizeof(struct v2_disk_dqblk)) {+		if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,+		    (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))+		    != sizeof(struct v2_disk_dqblk)) { 			if (ret >= 0) 				ret = -EIO;-			printk(KERN_ERR "VFS: Error while reading quota structure for id %u.\n", dquot->dq_id);+			printk(KERN_ERR "VFS: Error while reading quota "+			  "structure for id %u.\n", dquot->dq_id); 			memset(&ddquot, 0, sizeof(struct v2_disk_dqblk)); 		} 		else {@@ -660,7 +641,6 @@ static int v2_read_dquot(struct dquot *d 			if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk))) 				ddquot.dqb_itime = 0; 		}-		set_fs(fs); 		disk2memdqb(&dquot->dq_dqb, &ddquot); 	} 	dqstats.reads++;@@ -668,15 +648,13 @@ static int v2_read_dquot(struct dquot *d 	return ret; } -/* Commit changes of dquot to disk - it might also mean deleting it when quota became fake one and user has no blocks... */-static int v2_commit_dquot(struct dquot *dquot)+/* Check whether dquot should not be deleted. We know we are+ *  * the only one operating on dquot (thanks to dq_lock) */+static int v2_release_dquot(struct dquot *dquot) {-	/* We clear the flag everytime so we don't loop when there was an IO error... */-	dquot->dq_flags &= ~DQ_MOD;-	if (dquot->dq_flags & DQ_FAKE && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))+	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) 		return v2_delete_dquot(dquot);-	else-		return v2_write_dquot(dquot);+	return 0; }  static struct quota_format_ops v2_format_ops = {@@ -685,7 +663,8 @@ static struct quota_format_ops v2_format 	.write_file_info	= v2_write_file_info, 	.free_file_info		= NULL, 	.read_dqblk		= v2_read_dquot,-	.commit_dqblk		= v2_commit_dquot,+	.commit_dqblk		= v2_write_dquot,+	.release_dqblk          = v2_release_dquot, };  static struct quota_format_type v2_quota_format = {Index: linux-2.6.5-7.283/fs/quota.c===================================================================--- linux-2.6.5-7.283.orig/fs/quota.c+++ linux-2.6.5-7.283/fs/quota.c@@ -14,6 +14,9 @@ #include <linux/smp_lock.h> #include <linux/security.h> #include <linux/audit.h>+#include <linux/syscalls.h>+#include <linux/buffer_head.h>+  /* Check validity of quotactl */ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)@@ -134,16 +137,54 @@ restart: 	return NULL; } +void quota_sync_sb(struct super_block *sb, int type)+{+	int cnt;+	struct inode *discard[MAXQUOTAS];++	sb->s_qcop->quota_sync(sb, type);+	/* This is not very clever (and fast) but currently I don't know about+	 * any other simple way of getting quota data to disk and we must get+	 * them there for userspace to be visible... */+	if (sb->s_op->sync_fs)+		sb->s_op->sync_fs(sb, 1);+	sync_blockdev(sb->s_bdev);++	/* Now when everything is written we can discard the pagecache so+	 * that userspace sees the changes. We need i_sem and so we could+	 * not do it inside dqonoff_sem. Moreover we need to be carefull+	 * about races with quotaoff() (that is the reason why we have own+	 * reference to inode). */+	down(&sb_dqopt(sb)->dqonoff_sem);+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {+		discard[cnt] = NULL;+		if (type != -1 && cnt != type)+			continue;+		if (!sb_has_quota_enabled(sb, cnt))+			continue;+		discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);+	}+	up(&sb_dqopt(sb)->dqonoff_sem);+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {+		if (discard[cnt]) {+			down(&discard[cnt]->i_sem);+			truncate_inode_pages(&discard[cnt]->i_data, 0);+			up(&discard[cnt]->i_sem);+			iput(discard[cnt]);+		}+	}+}+ void sync_dquots(struct super_block *sb, int type) { 	if (sb) { 		if (sb->s_qcop->quota_sync)-			sb->s_qcop->quota_sync(sb, type);+			quota_sync_sb(sb, type); 	} 	else {-		while ((sb = get_super_to_sync(type))) {+		while ((sb = get_super_to_sync(type)) != NULL) { 			if (sb->s_qcop->quota_sync)-				sb->s_qcop->quota_sync(sb, type);+				quota_sync_sb(sb, type); 			drop_super(sb); 		} 	}Index: linux-2.6.5-7.283/fs/ext3/inode.c===================================================================--- linux-2.6.5-7.283.orig/fs/ext3/inode.c+++ linux-2.6.5-7.283/fs/ext3/inode.c@@ -1015,7 +1015,7 @@ out: 	return ret; } -static int+int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh) { 	int err = journal_dirty_data(handle, bh);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -