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

📄 ext3-mballoc2-2.6-fc5.patch

📁 非常经典的一个分布式系统
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
++	/* drop non-allocated, but dquote'd blocks */+	J_ASSERT(*len >= ac.ac_b_ex.fe_len);+	DQUOT_FREE_BLOCK(inode, *len - ac.ac_b_ex.fe_len);++	*len = ac.ac_b_ex.fe_len;+	J_ASSERT(*len > 0);+	J_ASSERT(block != 0);+	goto out;++out_err:+	/* if we've already allocated something, roll it back */+	if (ac.ac_status == AC_STATUS_FOUND) {+		/* FIXME: free blocks here */+	}++	DQUOT_FREE_BLOCK(inode, *len);+	brelse(bitmap_bh);+	*errp = err;+	block = 0;+out:+	if (ac.ac_buddy_page)+		page_cache_release(ac.ac_buddy_page);+	if (ac.ac_bitmap_page)+		page_cache_release(ac.ac_bitmap_page);++	if (!(flags & EXT3_MB_HINT_RESERVED)) {+		/* block wasn't reserved before and we reserved it+		 * at the beginning of allocation. it doesn't matter+		 * whether we allocated anything or we failed: time+		 * to release reservation. NOTE: because I expect+		 * any multiblock request from delayed allocation+		 * path only, here is single block always */+		ext3_mb_release_blocks(sb, 1);+	}++	if (unlikely(ext3_mb_stats) && ac.ac_g_ex.fe_len > 1) {+		atomic_inc(&sbi->s_bal_reqs);+		atomic_add(*len, &sbi->s_bal_allocated);+		if (*len >= ac.ac_g_ex.fe_len)+			atomic_inc(&sbi->s_bal_success);+		atomic_add(ac.ac_found, &sbi->s_bal_ex_scanned);+		if (ac.ac_g_ex.fe_start == ac.ac_b_ex.fe_start &&+				ac.ac_g_ex.fe_group == ac.ac_b_ex.fe_group)+			atomic_inc(&sbi->s_bal_goals);+		if (ac.ac_found > ext3_mb_max_to_scan)+			atomic_inc(&sbi->s_bal_breaks);+	}++	ext3_mb_store_history(sb, inode->i_ino, &ac);++	return block;+}+EXPORT_SYMBOL(ext3_mb_new_blocks);++#ifdef EXT3_MB_HISTORY+struct ext3_mb_proc_session {+	struct ext3_mb_history *history;+	struct super_block *sb;+	int start;+	int max;+};++static void *ext3_mb_history_skip_empty(struct ext3_mb_proc_session *s,+					struct ext3_mb_history *hs,+					int first)+{+	if (hs == s->history + s->max)+		hs = s->history;+	if (!first && hs == s->history + s->start)+		return NULL;+	while (hs->goal.fe_len == 0) {+		hs++;+		if (hs == s->history + s->max)+			hs = s->history;+		if (hs == s->history + s->start)+			return NULL;+	}+	return hs;+}++static void *ext3_mb_seq_history_start(struct seq_file *seq, loff_t *pos)+{+	struct ext3_mb_proc_session *s = seq->private;+	struct ext3_mb_history *hs;+	int l = *pos;++	if (l == 0)+		return SEQ_START_TOKEN;+	hs = ext3_mb_history_skip_empty(s, s->history + s->start, 1);+	if (!hs)+		return NULL;+	while (--l && (hs = ext3_mb_history_skip_empty(s, ++hs, 0)) != NULL);+	return hs;+}++static void *ext3_mb_seq_history_next(struct seq_file *seq, void *v, loff_t *pos)+{+	struct ext3_mb_proc_session *s = seq->private;+	struct ext3_mb_history *hs = v;++	++*pos;+	if (v == SEQ_START_TOKEN)+		return ext3_mb_history_skip_empty(s, s->history + s->start, 1);+	else+		return ext3_mb_history_skip_empty(s, ++hs, 0);+}++static int ext3_mb_seq_history_show(struct seq_file *seq, void *v)+{+	struct ext3_mb_history *hs = v;+	char buf[20], buf2[20];++	if (v == SEQ_START_TOKEN) {+		seq_printf(seq, "%-5s %-8s %-17s %-17s %-5s %-5s %-2s %-5s %-5s %-6s\n",+			 "pid", "inode", "goal", "result", "found", "grps", "cr",+			 "merge", "tail", "broken");+		return 0;+	}++	sprintf(buf, "%u/%u/%u", hs->goal.fe_group,+		hs->goal.fe_start, hs->goal.fe_len);+	sprintf(buf2, "%u/%u/%u", hs->result.fe_group,+		hs->result.fe_start, hs->result.fe_len);+	seq_printf(seq, "%-5u %-8u %-17s %-17s %-5u %-5u %-2u %-5s %-5u %-6u\n",+			hs->pid, hs->ino, buf, buf2, hs->found, hs->groups,+			hs->cr, hs->merged ? "M" : "", hs->tail,+			hs->buddy ? 1 << hs->buddy : 0);+	return 0;+}++static void ext3_mb_seq_history_stop(struct seq_file *seq, void *v)+{+}++static struct seq_operations ext3_mb_seq_history_ops = {+	.start  = ext3_mb_seq_history_start,+	.next   = ext3_mb_seq_history_next,+	.stop   = ext3_mb_seq_history_stop,+	.show   = ext3_mb_seq_history_show,+};++static int ext3_mb_seq_history_open(struct inode *inode, struct file *file)+{+	struct super_block *sb = PDE(inode)->data;+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	struct ext3_mb_proc_session *s;+	int rc, size;++	s = kmalloc(sizeof(*s), GFP_KERNEL);+	if (s == NULL)+		return -EIO;+	size = sizeof(struct ext3_mb_history) * sbi->s_mb_history_max;+	s->history = kmalloc(size, GFP_KERNEL);+	if (s->history == NULL) {+		kfree(s);+		return -EIO;+	}++	spin_lock(&sbi->s_mb_history_lock);+	memcpy(s->history, sbi->s_mb_history, size);+	s->max = sbi->s_mb_history_max;+	s->start = sbi->s_mb_history_cur % s->max;+	spin_unlock(&sbi->s_mb_history_lock);++	rc = seq_open(file, &ext3_mb_seq_history_ops);+	if (rc == 0) {+		struct seq_file *m = (struct seq_file *)file->private_data;+		m->private = s;+	} else {+		kfree(s->history);+		kfree(s);+	}+	return rc;++}++static int ext3_mb_seq_history_release(struct inode *inode, struct file *file)+{+	struct seq_file *seq = (struct seq_file *)file->private_data;+	struct ext3_mb_proc_session *s = seq->private;+	kfree(s->history);+	kfree(s);+	return seq_release(inode, file);+}++static struct file_operations ext3_mb_seq_history_fops = {+	.owner		= THIS_MODULE,+	.open		= ext3_mb_seq_history_open,+	.read		= seq_read,+	.llseek		= seq_lseek,+	.release	= ext3_mb_seq_history_release,+};++static void *ext3_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)+{+	struct super_block *sb = seq->private;+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	long group;++	if (*pos < 0 || *pos >= sbi->s_groups_count)+		return NULL;++	group = *pos + 1;+	return (void *) group;+}++static void *ext3_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos)+{+	struct super_block *sb = seq->private;+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	long group;++	++*pos;+	if (*pos < 0 || *pos >= sbi->s_groups_count)+		return NULL;+	group = *pos + 1;+	return (void *) group;;+}++static int ext3_mb_seq_groups_show(struct seq_file *seq, void *v)+{+	struct super_block *sb = seq->private;+	long group = (long) v, i;+	struct sg {+		struct ext3_group_info info;+		unsigned short counters[16];+	} sg;++	group--;+	if (group == 0)+		seq_printf(seq, "#%-5s: %-5s %-5s %-5s [ %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s ]\n",+			 "group", "free", "frags", "first", "2^0", "2^1", "2^2",+			 "2^3", "2^4", "2^5", "2^6", "2^7", "2^8", "2^9", "2^10",+			 "2^11", "2^12", "2^13");++	i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) ++		sizeof(struct ext3_group_info);+	ext3_lock_group(sb, group);+	memcpy(&sg, EXT3_GROUP_INFO(sb, group), i);+	ext3_unlock_group(sb, group);++	if (EXT3_MB_GRP_NEED_INIT(&sg.info))+		return 0;++	seq_printf(seq, "#%-5lu: %-5u %-5u %-5u [", group, sg.info.bb_free,+			sg.info.bb_fragments, sg.info.bb_first_free);+	for (i = 0; i <= 13; i++)+		seq_printf(seq, " %-5u", i <= sb->s_blocksize_bits + 1 ?+				sg.info.bb_counters[i] : 0);+	seq_printf(seq, " ]\n");++	return 0;+}++static void ext3_mb_seq_groups_stop(struct seq_file *seq, void *v)+{+}++static struct seq_operations ext3_mb_seq_groups_ops = {+	.start  = ext3_mb_seq_groups_start,+	.next   = ext3_mb_seq_groups_next,+	.stop   = ext3_mb_seq_groups_stop,+	.show   = ext3_mb_seq_groups_show,+};++static int ext3_mb_seq_groups_open(struct inode *inode, struct file *file)+{+	struct super_block *sb = PDE(inode)->data;+	int rc;++	rc = seq_open(file, &ext3_mb_seq_groups_ops);+	if (rc == 0) {+		struct seq_file *m = (struct seq_file *)file->private_data;+		m->private = sb;+	}+	return rc;++}++static struct file_operations ext3_mb_seq_groups_fops = {+	.owner		= THIS_MODULE,+	.open		= ext3_mb_seq_groups_open,+	.read		= seq_read,+	.llseek		= seq_lseek,+	.release	= seq_release,+};++static void ext3_mb_history_release(struct super_block *sb)+{+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	char name[64];++	snprintf(name, sizeof(name) - 1, "%s", bdevname(sb->s_bdev, name));+	remove_proc_entry("mb_groups", sbi->s_mb_proc);+	remove_proc_entry("mb_history", sbi->s_mb_proc);+	remove_proc_entry(name, proc_root_ext3);++	if (sbi->s_mb_history)+		kfree(sbi->s_mb_history);+}++static void ext3_mb_history_init(struct super_block *sb)+{+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	char name[64];+	int i;++	snprintf(name, sizeof(name) - 1, "%s", bdevname(sb->s_bdev, name));+	sbi->s_mb_proc = proc_mkdir(name, proc_root_ext3);+	if (sbi->s_mb_proc != NULL) {+		struct proc_dir_entry *p;+		p = create_proc_entry("mb_history", S_IRUGO, sbi->s_mb_proc);+		if (p) {+			p->proc_fops = &ext3_mb_seq_history_fops;+			p->data = sb;+		}+		p = create_proc_entry("mb_groups", S_IRUGO, sbi->s_mb_proc);+		if (p) {+			p->proc_fops = &ext3_mb_seq_groups_fops;+			p->data = sb;+		}+	}++	sbi->s_mb_history_max = 1000;+	sbi->s_mb_history_cur = 0;+	spin_lock_init(&sbi->s_mb_history_lock);+	i = sbi->s_mb_history_max * sizeof(struct ext3_mb_history);+	sbi->s_mb_history = kmalloc(i, GFP_KERNEL);+       if (likely(sbi->s_mb_history != NULL))+               memset(sbi->s_mb_history, 0, i);+	/* if we can't allocate history, then we simple won't use it */+}++static void+ext3_mb_store_history(struct super_block *sb, unsigned ino,+			struct ext3_allocation_context *ac)+{+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	struct ext3_mb_history h;++	if (unlikely(sbi->s_mb_history == NULL))+		return;++	h.pid = current->pid;+	h.ino = ino;+	h.goal = ac->ac_g_ex;+	h.result = ac->ac_b_ex;+	h.found = ac->ac_found;+	h.cr = ac->ac_criteria;+	h.groups = ac->ac_groups_scanned;+	h.tail = ac->ac_tail;+	h.buddy = ac->ac_buddy;+	h.merged = 0;+	if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&+			ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)+		h.merged = 1;++	spin_lock(&sbi->s_mb_history_lock);+	memcpy(sbi->s_mb_history + sbi->s_mb_history_cur, &h, sizeof(h));+	if (++sbi->s_mb_history_cur >= sbi->s_mb_history_max)+		sbi->s_mb_history_cur = 0;+	spin_unlock(&sbi->s_mb_history_lock);+}++#else+#define ext3_mb_history_release(sb)+#define ext3_mb_history_init(sb)+#endif++int ext3_mb_init_backend(struct super_block *sb)+{+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	int i, j, len, metalen;+	int num_meta_group_infos =+		(sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) >>+			EXT3_DESC_PER_BLOCK_BITS(sb);+	struct ext3_group_info **meta_group_info;++	/* An 8TB filesystem with 64-bit pointers requires a 4096 byte+	 * kmalloc. A 128kb malloc should suffice for a 256TB filesystem.+	 * So a two level scheme suffices for now. */+	sbi->s_group_info = kmalloc(sizeof(*sbi->s_group_info) *+				    num_meta_group_infos, GFP_KERNEL);+	if (sbi->s_group_info == NULL) {+		printk(KERN_ERR "EXT3-fs: can't allocate buddy meta group\n");+		return -ENOMEM;+	}+	sbi->s_buddy_cache = new_inode(sb);+	if (sbi->s_buddy_cache == NULL) {+		printk(KERN_ERR "EXT3-fs: can't get new inode\n");+		goto err_freesgi;+	}++	metalen = sizeof(*meta_group_info) << EXT3_DESC_PER_BLOCK_BITS(sb);+	for (i = 0; i < num_meta_group_infos; i++) {+		if ((i + 1) == num_meta_group_infos)+			metalen = sizeof(*meta_group_info) *+				(sbi->s_groups_count -+					(i << EXT3_DESC_PER_BLOCK_BITS(sb)));+		meta_group_info = kmalloc(metalen, GFP_KERNEL);+		if (meta_group_info == NULL) {+			printk(KERN_ERR "EXT3-fs: can't allocate mem for a "+			       "buddy group\n");+			goto err_freemeta;+		}+		sbi->s_group_info[i] = meta_group_info;+	}++	/*+	 * calculate needed size. if change bb_counters size,+	 * don't forget about ext3_mb_generate_buddy()+	 */+	len = sizeof(struct ext3_group_info);+	len += sizeof(unsigned short) * (sb->s_blocksize_bits + 2);+	for (i = 0; i < sbi->s_groups_count; i++) {+		struct ext3_group_desc * desc;++		meta_group_info =+			sbi->s_group_info[i >> EXT3_DESC_PER_BLOCK_BITS(sb)];+		j = i & (EXT3_DESC_PER_BLOCK(sb) - 1);++		meta_group_info[j] = kmalloc(len, GFP_KERNEL);+		if (meta_group_info[j] == NULL) {+			printk(KERN_ERR "EXT3-fs: can't allocate buddy mem\n");+			i--;+			goto err_freebuddy;+		}+		desc = ext3_get_group_desc(sb, i, NULL);+		if (desc == NULL) {+			printk(KERN_ERR"EXT3-fs: can't read descriptor %u\n",i);+			goto err_freebuddy;+		}+		memset(meta_group_info[j], 0, len);+		set_bit(EXT3_GROUP_INFO_NEED_INIT_BIT,+			&meta_group_info[j]->bb_state);+		meta_group_info[j]->bb_free =+			le16_to_cpu(desc->bg_free_blocks_count);+	}++	return 0;++err_freebuddy:+	while (i >= 0) {+		kfree(EXT3_GROUP_INFO(sb, i));+		i--;+	}+	i = num_meta_group_infos;+err_freemeta:+	while (--i >= 0)+		kfree(sbi->s_group_info[i]);+	iput(sbi->s_buddy_cache);+err_freesgi:+	kfree(sbi->s_group_info);+	return -ENOMEM;+}++int ext3_mb_init(struct super_block *sb, int needs_recovery)+{+	struct ext3_sb_info *sbi = EXT3_SB(sb);+	struct inode *root = sb->s_root->d_inode;+	unsigned i, offset, max;+	struct dentry *dentry;++	if (!test_opt(sb, MBALLOC))+		return 0;++	i = (sb->s_blocksize_bits + 2) * sizeof(unsigned short);++	sbi->s_mb_offsets = kmalloc(i, GFP_KERNEL);+	if (sbi->s_mb_offsets == NULL) {+		clear_opt(sbi->s_mount_opt, MBALLOC);+		return -ENOMEM;+	}+	sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL);+	if (sbi->s_mb_maxs == NULL) {+		clear_opt(sbi->s_mount_opt, MBALLOC);+		kfree(sbi->s_mb_maxs);+		return -ENOMEM;

⌨️ 快捷键说明

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