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

📄 quota-deadlock-on-pagelock-core.patch

📁 lustre 1.6.5 source code
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
 /* Find space for dquot */ static uint find_free_dqentry(struct dquot *dquot, int *err) {-	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;+	struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type; 	uint blk, i; 	struct v2_disk_dqdbheader *dh; 	struct v2_disk_dqblk *ddquot;@@ -309,22 +282,23 @@ static uint find_free_dqentry(struct dqu 	ddquot = GETENTRIES(buf); 	if (info->u.v2_i.dqi_free_entry) { 		blk = info->u.v2_i.dqi_free_entry;-		if ((*err = read_blk(filp, blk, buf)) < 0)+		if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0) 			goto out_buf; 	} 	else {-		blk = get_free_dqblk(filp, dquot->dq_type);+		blk = get_free_dqblk(sb, dquot->dq_type); 		if ((int)blk < 0) { 			*err = blk; 			freedqbuf(buf); 			return 0; 		} 		memset(buf, 0, V2_DQBLKSIZE);-		info->u.v2_i.dqi_free_entry = blk;	/* This is enough as block is already zeroed and entry list is empty... */-		mark_info_dirty(dquot->dq_sb, dquot->dq_type);+		/* This is enough as block is already zeroed and entry list is empty... */+		info->u.v2_i.dqi_free_entry = blk;+		mark_info_dirty(sb, dquot->dq_type); 	} 	if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK)	/* Block will be full? */-		if ((*err = remove_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0) {+		if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) { 			printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk); 			goto out_buf; 		}@@ -339,7 +313,7 @@ static uint find_free_dqentry(struct dqu 		goto out_buf; 	} #endif-	if ((*err = write_blk(filp, blk, buf)) < 0) {+	if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) { 		printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk); 		goto out_buf; 	}@@ -354,7 +328,7 @@ out_buf: /* Insert reference to structure into the trie */ static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth) {-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];+	struct super_block *sb = dquot->dq_sb; 	dqbuf_t buf; 	int ret = 0, newson = 0, newact = 0; 	__le32 *ref;@@ -363,7 +337,7 @@ static int do_insert_tree(struct dquot * 	if (!(buf = getdqbuf())) 		return -ENOMEM; 	if (!*treeblk) {-		ret = get_free_dqblk(filp, dquot->dq_type);+		ret = get_free_dqblk(sb, dquot->dq_type); 		if (ret < 0) 			goto out_buf; 		*treeblk = ret;@@ -371,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; 		}@@ -394,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, dquot->dq_type, buf, *treeblk);+		put_free_dqblk(sb, dquot->dq_type, buf, *treeblk); out_buf: 	freedqbuf(buf); 	return ret;@@ -416,20 +390,15 @@ 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;  	/* dq_off is guarded by dqio_sem */ 	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; 	spin_lock(&dq_data_lock); 	mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id); 	/* Argh... We may need to write structure full of zeroes but that would be@@ -439,10 +408,8 @@ static int v2_write_dquot(struct dquot * 	if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk))) 		ddquot.dqb_itime = cpu_to_le64(1); 	spin_unlock(&dq_data_lock);-	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)@@ -458,7 +425,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 super_block *sb = dquot->dq_sb;+	int type = dquot->dq_type; 	struct v2_disk_dqdbheader *dh; 	dqbuf_t buf = getdqbuf(); 	int ret = 0;@@ -466,34 +434,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, dquot->dq_type, buf, blk)) < 0 ||-		    (ret = put_free_dqblk(filp, dquot->dq_type, 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, dquot->dq_type, 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; 			} 	}@@ -506,7 +479,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 super_block *sb = dquot->dq_sb;+	int type = dquot->dq_type; 	dqbuf_t buf = getdqbuf(); 	int ret = 0; 	uint newblk;@@ -514,7 +488,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; 	}@@ -530,12 +504,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, dquot->dq_type, 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);@@ -555,7 +530,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;@@ -563,27 +537,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;@@ -592,14 +570,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; 	__le32 *ref = (__le32 *)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; 	}@@ -625,16 +602,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 || !sb_dqopt(dquot->dq_sb)->files[type]) { 		printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); 		return -EIO; 	}@@ -642,7 +616,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; 		set_bit(DQ_FAKE_B, &dquot->dq_flags); 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));@@ -650,12 +625,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 {@@ -666,7 +642,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); 		if (!dquot->dq_dqb.dqb_bhardlimit && 			!dquot->dq_dqb.dqb_bsoftlimit &&diff -rup RH_2_6_9_55.orig/include/linux/fs.h RH_2_6_9_55/include/linux/fs.h--- RH_2_6_9_55.orig/include/linux/fs.h+++ RH_2_6_9_55/include/linux/fs.h@@ -1042,6 +1042,9 @@ struct super_operations {	void (*umount_lustre) (struct super_block *);	int (*show_options)(struct seq_file *, struct vfsmount *);++	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);+ 	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); }; /* Inode state bits.  Protected by inode_lock. */diff -rup RH_2_6_9_55.orig/include/linux/quota.h RH_2_6_9_55/include/linux/quota.h--- RH_2_6_9_55.orig/include/linux/quota.h+++ RH_2_6_9_55/include/linux/quota.h@@ -285,7 +285,7 @@ struct quota_info { 	struct semaphore dqio_sem;		/* lock device while I/O in progress */ 	struct semaphore dqonoff_sem;		/* Serialize quotaon & quotaoff */ 	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */-	struct file *files[MAXQUOTAS];		/* fp's to quotafiles */+	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */ 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */ 	struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */ };diff -rup RH_2_6_9_55.orig/include/linux/security.h RH_2_6_9_55/include/linux/security.h--- RH_2_6_9_55.orig/include/linux/security.h+++ RH_2_6_9_55/include/linux/security.h@@ -1033,7 +1033,7 @@ struct security_operations {	int (*sysctl) (ctl_table * table, int op);	int (*capable) (struct task_struct * tsk, int cap);	int (*quotactl) (int cmds, int type, int id, struct super_block * sb);-	int (*quota_on) (struct file * f);+	int (*quota_on) (struct dentry * dentry);	int (*syslog) (int type);	int (*vm_enough_memory) (long pages);@@ -1281,9 +1281,9 @@ static inline int security_quotactl (int 	return security_ops->quotactl (cmds, type, id, sb); } -static inline int security_quota_on (struct file * file)+static inline int security_quota_on (struct dentry * dentry) {-	return security_ops->quota_on (file);+	return security_ops->quota_on (dentry); }  static inline int security_syslog(int type)@@ -1953,7 +1953,7 @@ static inline int security_quotactl (int 	return 0; } -static inline int security_quota_on (struct file * file)+static inline int security_quota_on (struct dentry * dentry) { 	return 0; }diff -rup RH_2_6_9_55.orig/security/dummy.c RH_2_6_9_55/security/dummy.c--- RH_2_6_9_55.orig/security/dummy.c+++ RH_2_6_9_55/security/dummy.c@@ -92,7 +92,7 @@ static int dummy_quotactl (int cmds, int 	return 0; } -static int dummy_quota_on (struct file *f)+static int dummy_quota_on (struct dentry *dentry) { 	return 0; }diff -rup RH_2_6_9_55.orig/security/selinux/hooks.c RH_2_6_9_55/security/selinux/hooks.c--- RH_2_6_9_55.orig/security/selinux/hooks.c+++ RH_2_6_9_55/security/selinux/hooks.c@@ -1485,9 +1485,9 @@ static int selinux_quotactl(int cmds, in 	return rc; } -static int selinux_quota_on(struct file *f)+static int selinux_quota_on(struct dentry *dentry) {-	return file_has_perm(current, f, FILE__QUOTAON);+	return dentry_has_perm(current, NULL, dentry, FILE__QUOTAON); }  static int selinux_syslog(int type)

⌨️ 快捷键说明

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