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

📄 2.6.5-quotafix.patch

📁 非常经典的一个分布式系统
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
Index: linux-2.6.5-7.283/include/linux/ext3_jbd.h===================================================================--- linux-2.6.5-7.283.orig/include/linux/ext3_jbd.h+++ linux-2.6.5-7.283/include/linux/ext3_jbd.h@@ -72,6 +72,19 @@ extern int ext3_writepage_trans_blocks(s  #define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8 +#ifdef CONFIG_QUOTA+/* Amount of blocks needed for quota update - we know that the structure was+ * allocated so we need to update only inode+data */+#define EXT3_QUOTA_TRANS_BLOCKS 2+/* Amount of blocks needed for quota insert/delete - we do some block writes+ * but inode, sb and group updates are done only once */+#define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\+				(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3)+#else+#define EXT3_QUOTA_TRANS_BLOCKS 0+#define EXT3_QUOTA_INIT_BLOCKS 0+#endif+ int ext3_mark_iloc_dirty(handle_t *handle,  		     struct inode *inode,@@ -97,6 +110,8 @@ int ext3_mark_inode_dirty(handle_t *hand void ext3_journal_abort_handle(const char *caller, const char *err_fn, 		struct buffer_head *bh, handle_t *handle, int err); +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh);+ static inline int __ext3_journal_get_undo_access(const char *where, handle_t *handle, 				struct buffer_head *bh, int *credits)Index: linux-2.6.5-7.283/include/linux/fs.h===================================================================--- linux-2.6.5-7.283.orig/include/linux/fs.h+++ linux-2.6.5-7.283/include/linux/fs.h@@ -967,6 +967,9 @@ struct super_operations { 	void (*umount_begin) (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. */Index: linux-2.6.5-7.283/include/linux/quota.h===================================================================--- linux-2.6.5-7.283.orig/include/linux/quota.h+++ linux-2.6.5-7.283/include/linux/quota.h@@ -138,6 +138,10 @@ struct if_dqinfo { #include <linux/dqblk_v1.h> #include <linux/dqblk_v2.h> +/* Maximal numbers of writes for quota operation (insert/delete/update)+ * (over all formats) - info block, 4 pointer blocks, data block */+#define DQUOT_MAX_WRITES        6+ /*  * Data for one user/group kept in memory  */@@ -168,22 +172,21 @@ struct mem_dqinfo { 	} u; }; +struct super_block;+ #define DQF_MASK 0xffff		/* Mask for format specific flags */ #define DQF_INFO_DIRTY_B 16 #define DQF_ANY_DQUOT_DIRTY_B 17 #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B)	/* Is info dirty? */ #define DQF_ANY_DQUOT_DIRTY (1 << DQF_ANY_DQUOT_DIRTY_B) /* Is any dquot dirty? */ -extern inline void mark_info_dirty(struct mem_dqinfo *info)-{-	set_bit(DQF_INFO_DIRTY_B, &info->dqi_flags);-}-+extern void mark_info_dirty(struct super_block *sb, int type); #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags) #define info_any_dquot_dirty(info) test_bit(DQF_ANY_DQUOT_DIRTY_B, &(info)->dqi_flags) #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info))  #define sb_dqopt(sb) (&(sb)->s_dquot)+#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type))  struct dqstats { 	int lookups;@@ -204,6 +207,9 @@ extern struct dqstats dqstats; #define DQ_BLKS_B	1 #define DQ_INODES_B	2 #define DQ_FAKE_B	3+#define DQ_READ_B	4	/* dquot was read into memory */+#define DQ_ACTIVE_B     5       /* dquot is active (dquot_release not called) */+#define DQ_WAITFREE_B   6       /* dquot being waited (by invalidate_dquots) */  #define DQ_MOD        (1 << DQ_MOD_B)	/* dquot modified since read */ #define DQ_BLKS       (1 << DQ_BLKS_B)	/* uid/gid has been warned about blk limit */@@ -239,18 +245,22 @@ struct quota_format_ops { 	int (*free_file_info)(struct super_block *sb, int type);	/* Called on quotaoff() */ 	int (*read_dqblk)(struct dquot *dquot);		/* Read structure for one user */ 	int (*commit_dqblk)(struct dquot *dquot);	/* Write (or delete) structure for one user */+	int (*release_dqblk)(struct dquot *dquot);      /* Called when last reference to dquot is being dropped */ };  /* Operations working with dquots */ struct dquot_operations {-	void (*initialize) (struct inode *, int);-	void (*drop) (struct inode *);+	int (*initialize) (struct inode *, int);+	int (*drop) (struct inode *); 	int (*alloc_space) (struct inode *, qsize_t, int); 	int (*alloc_inode) (const struct inode *, unsigned long);-	void (*free_space) (struct inode *, qsize_t);-	void (*free_inode) (const struct inode *, unsigned long);+	int (*free_space) (struct inode *, qsize_t);+	int (*free_inode) (const struct inode *, unsigned long); 	int (*transfer) (struct inode *, struct iattr *); 	int (*write_dquot) (struct dquot *);+	int (*acquire_dquot) (struct dquot *);          /* Quota is going to be created on disk */+	int (*release_dquot) (struct dquot *);          /* Quota is going to be deleted from disk */+	int (*write_info) (struct super_block *, int);  /* Write of quota "superblock" */ };  /* Operations handling requests from userspace */@@ -283,7 +293,8 @@ 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 vfsmount *mnt[MAXQUOTAS];        /* mountpoint entries of filesystems with quota files */ 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */ 	struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */ };Index: linux-2.6.5-7.283/include/linux/quotaops.h===================================================================--- linux-2.6.5-7.283.orig/include/linux/quotaops.h+++ linux-2.6.5-7.283/include/linux/quotaops.h@@ -22,17 +22,22 @@  */ extern void sync_dquots(struct super_block *sb, int type); -extern void dquot_initialize(struct inode *inode, int type);-extern void dquot_drop(struct inode *inode);+extern int dquot_initialize(struct inode *inode, int type);+extern int dquot_drop(struct inode *inode);  extern int  dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number); -extern void dquot_free_space(struct inode *inode, qsize_t number);-extern void dquot_free_inode(const struct inode *inode, unsigned long number);+extern int dquot_free_space(struct inode *inode, qsize_t number);+extern int dquot_free_inode(const struct inode *inode, unsigned long number);  extern int  dquot_transfer(struct inode *inode, struct iattr *iattr); +extern int dquot_commit(struct dquot *dquot);+extern int dquot_commit_info(struct super_block *sb, int type);+extern int dquot_acquire(struct dquot *dquot);+extern int dquot_release(struct dquot *dquot);+ /*  * Operations supported for diskquotas.  */@@ -143,7 +148,7 @@ static __inline__ int DQUOT_OFF(struct s { 	int ret = -ENOSYS; -	if (sb->s_qcop && sb->s_qcop->quota_off)+	if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off) 		ret = sb->s_qcop->quota_off(sb, -1); 	return ret; }Index: linux-2.6.5-7.283/include/linux/security.h===================================================================--- linux-2.6.5-7.283.orig/include/linux/security.h+++ linux-2.6.5-7.283/include/linux/security.h@@ -1020,7 +1020,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); @@ -1292,9 +1292,9 @@ static inline int security_quotactl (int 			 0); } -static inline int security_quota_on (struct file * file)+static inline int security_quota_on (struct dentry * dentry) {-	return COND_SECURITY(quota_on (file), +	return COND_SECURITY(quota_on (dentry),  			 0); } Index: linux-2.6.5-7.283/security/dummy.c===================================================================--- linux-2.6.5-7.283.orig/security/dummy.c+++ linux-2.6.5-7.283/security/dummy.c@@ -90,7 +90,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; }Index: linux-2.6.5-7.283/security/selinux/hooks.c===================================================================--- linux-2.6.5-7.283.orig/security/selinux/hooks.c+++ linux-2.6.5-7.283/security/selinux/hooks.c@@ -1454,9 +1454,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)Index: linux-2.6.5-7.283/fs/dquot.c===================================================================--- linux-2.6.5-7.283.orig/fs/dquot.c+++ linux-2.6.5-7.283/fs/dquot.c@@ -52,6 +52,9 @@  *		New SMP locking.  *		Jan Kara, <jack@suse.cz>, 10/2002  *+ *		Fix lock inversion problems+ *		Jan Kara, <jack@suse.cz>, 2003,2004+ *  * (C) Copyright 1994 - 1997 Marco van Wieringen   */ @@ -75,7 +78,8 @@ #include <linux/proc_fs.h> #include <linux/security.h> #include <linux/kmod.h>-#include <linux/pagemap.h>+#include <linux/namei.h>+#include <linux/buffer_head.h>  #include <asm/uaccess.h> @@ -109,7 +113,7 @@  * dqget(). Write operations on dquots don't hold dq_lock as they copy data  * under dq_data_lock spinlock to internal buffers before writing.  *- * Lock ordering (including journal_lock) is following:+ * Lock ordering (including journal_lock) is the following:  *  dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > dqio_sem  */ spinlock_t dq_list_lock = SPIN_LOCK_UNLOCKED;@@ -175,8 +179,7 @@ static void put_quota_format(struct quot  * on all three lists, depending on its current state.  *  * All dquots are placed to the end of inuse_list when first created, and this- * list is used for the sync and invalidate operations, which must look- * at every dquot.+ * list is used for invalidate operation, which must look at every dquot.  *  * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,  * and this list is searched whenever we need an available dquot.  Dquots are@@ -264,30 +267,105 @@ static void wait_on_dquot(struct dquot * 	up(&dquot->dq_lock); } -static int read_dqblk(struct dquot *dquot)+void mark_info_dirty(struct super_block *sb, int type) {-	int ret;+	set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);+}+EXPORT_SYMBOL(mark_info_dirty);++/*+ *	Read dquot from disk and alloc space for it+ */++int dquot_acquire(struct dquot *dquot)+{+	int ret = 0, ret2 = 0; 	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);  	down(&dquot->dq_lock); 	down(&dqopt->dqio_sem);-	ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);+	if (!test_bit(DQ_READ_B, &dquot->dq_flags))+		ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);+	if (ret < 0)+		goto out_iolock;+	set_bit(DQ_READ_B, &dquot->dq_flags);+	/* Instantiate dquot if needed */+	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {+		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);+		/* Write the info if needed */+		if (info_dirty(&dqopt->info[dquot->dq_type]))+			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);+		if (ret < 0)+			goto out_iolock;+		if (ret2 < 0) {+			ret = ret2;+			goto out_iolock;+		}+	}+	set_bit(DQ_ACTIVE_B, &dquot->dq_flags);+out_iolock: 	up(&dqopt->dqio_sem); 	up(&dquot->dq_lock); 	return ret; } -static int commit_dqblk(struct dquot *dquot)+/*+ *	Write dquot to disk+ */+int dquot_commit(struct dquot *dquot) {-	int ret;+	int ret = 0, ret2 = 0; 	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);  	down(&dqopt->dqio_sem);-	ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);+	spin_lock(&dq_list_lock);+	if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) {+		spin_unlock(&dq_list_lock);+		goto out_sem;+	}+	spin_unlock(&dq_list_lock);+	/* Inactive dquot can be only if there was error during read/init+	 * => we have better not writing it */+	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {+		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);+		if (info_dirty(&dqopt->info[dquot->dq_type]))+			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);+		if (ret >= 0)+			ret = ret2;+	}+out_sem: 	up(&dqopt->dqio_sem); 	return ret; } +/*+ *	Release dquot+ */+int dquot_release(struct dquot *dquot)+{+	int ret = 0, ret2 = 0;+	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);++	down(&dquot->dq_lock);+	/* Check whether we are not racing with some other dqget() */+	if (atomic_read(&dquot->dq_count) > 1)+		goto out_dqlock;+	down(&dqopt->dqio_sem);+	if (dqopt->ops[dquot->dq_type]->release_dqblk) {+		ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);+		/* Write the info */+		if (info_dirty(&dqopt->info[dquot->dq_type]))+			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);+		if (ret >= 0)+			ret = ret2;+	}+	clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);+	up(&dqopt->dqio_sem);+out_dqlock:+	up(&dquot->dq_lock);+	return ret;+}+ /* Invalidate all dquots on the list. Note that this function is called after  * quota is disabled so no new quota might be created. Because we hold  * dqonoff_sem and pointers were already removed from inodes we actually know@@ -343,6 +421,11 @@ restart: 			continue; 		if (!dquot_dirty(dquot)) 			continue;+		/* Dirty and inactive can be only bad dquot... */+		if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {+			test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags);+			continue;+		}			 		atomic_inc(&dquot->dq_count); 		dqstats.lookups++; 		spin_unlock(&dq_list_lock);@@ -353,11 +436,9 @@ restart:

⌨️ 快捷键说明

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