亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? rd.c

?? Linux塊設備驅動源碼
?? C
字號:
/* * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta. * * (C) Chad Page, Theodore Ts'o, et. al, 1995. * * This RAM disk is designed to have filesystems created on it and mounted * just like a regular floppy disk. * * It also does something suggested by Linus: use the buffer cache as the * RAM disk data.  This makes it possible to dynamically allocate the RAM disk * buffer - with some consequences I have to deal with as I write this. * * This code is based on the original ramdisk.c, written mostly by * Theodore Ts'o (TYT) in 1991.  The code was largely rewritten by * Chad Page to use the buffer cache to store the RAM disk data in * 1995; Theodore then took over the driver again, and cleaned it up * for inclusion in the mainline kernel. * * The original CRAMDISK code was written by Richard Lyons, and * adapted by Chad Page to use the new RAM disk interface.  Theodore * Ts'o rewrote it so that both the compressed RAM disk loader and the * kernel decompressor uses the same inflate.c codebase.  The RAM disk * loader now also loads into a dynamic (buffer cache based) RAM disk, * not the old static RAM disk.  Support for the old static RAM disk has * been completely removed. * * Loadable module support added by Tom Dyas. * * Further cleanups by Chad Page (page0588@sundance.sjsu.edu): *	Cosmetic changes in #ifdef MODULE, code movement, etc. * 	When the RAM disk module is removed, free the protected buffers * 	Default RAM disk size changed to 2.88 MB * *  Added initrd: Werner Almesberger & Hans Lermen, Feb '96 * * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB) *		- Chad Page * * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98 * * Make block size and block size shift for RAM disks a global macro * and set blk_size for -ENOSPC,     Werner Fink <werner@suse.de>, Apr '99 */#include <linux/config.h>#include <linux/string.h>#include <linux/slab.h>#include <asm/atomic.h>#include <linux/bio.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/devfs_fs_kernel.h>#include <linux/pagemap.h>#include <linux/blkdev.h>#include <linux/genhd.h>#include <linux/buffer_head.h>		/* for invalidate_bdev() */#include <linux/backing-dev.h>#include <linux/blkpg.h>#include <linux/writeback.h>#include <asm/uaccess.h>/* Various static variables go here.  Most are used only in the RAM disk code. */static struct gendisk *rd_disks[CONFIG_BLK_DEV_RAM_COUNT];static struct block_device *rd_bdev[CONFIG_BLK_DEV_RAM_COUNT];/* Protected device data */static struct request_queue *rd_queue[CONFIG_BLK_DEV_RAM_COUNT];/* * Parameters for the boot-loading of the RAM disk.  These are set by * init/main.c (from arguments to the kernel command line) or from the * architecture-specific setup routine (from the stored boot sector * information). */int rd_size = CONFIG_BLK_DEV_RAM_SIZE;		/* Size of the RAM disks *//* * It would be very desirable to have a soft-blocksize (that in the case * of the ramdisk driver is also the hardblocksize ;) of PAGE_SIZE because * doing that we'll achieve a far better MM footprint. Using a rd_blocksize of * BLOCK_SIZE in the worst case we'll make PAGE_SIZE/BLOCK_SIZE buffer-pages * unfreeable. With a rd_blocksize of PAGE_SIZE instead we are sure that only * 1 page will be protected. Depending on the size of the ramdisk you * may want to change the ramdisk blocksize to achieve a better or worse MM * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that * supposes the filesystem in the image uses a BLOCK_SIZE blocksize). */static int rd_blocksize = BLOCK_SIZE;		/* blocksize of the RAM disks *//* * Copyright (C) 2000 Linus Torvalds. *               2000 Transmeta Corp. * aops copied from ramfs. *//* * If a ramdisk page has buffers, some may be uptodate and some may be not. * To bring the page uptodate we zero out the non-uptodate buffers.  The * page must be locked. */static void make_page_uptodate(struct page *page){	if (page_has_buffers(page)) {		struct buffer_head *bh = page_buffers(page);		struct buffer_head *head = bh;		do {			if (!buffer_uptodate(bh)) {				memset(bh->b_data, 0, bh->b_size);				/*				 * akpm: I'm totally undecided about this.  The				 * buffer has just been magically brought "up to				 * date", but nobody should want to be reading				 * it anyway, because it hasn't been used for				 * anything yet.  It is still in a "not read				 * from disk yet" state.				 *				 * But non-uptodate buffers against an uptodate				 * page are against the rules.  So do it anyway.				 */				 set_buffer_uptodate(bh);			}		} while ((bh = bh->b_this_page) != head);	} else {		memset(page_address(page), 0, PAGE_CACHE_SIZE);	}	flush_dcache_page(page);	SetPageUptodate(page);}static int ramdisk_readpage(struct file *file, struct page *page){	if (!PageUptodate(page))		make_page_uptodate(page);	unlock_page(page);	return 0;}static int ramdisk_prepare_write(struct file *file, struct page *page,				unsigned offset, unsigned to){	if (!PageUptodate(page))		make_page_uptodate(page);	return 0;}static int ramdisk_commit_write(struct file *file, struct page *page,				unsigned offset, unsigned to){	set_page_dirty(page);	return 0;}/* * ->writepage to the the blockdev's mapping has to redirty the page so that the * VM doesn't go and steal it.  We return WRITEPAGE_ACTIVATE so that the VM * won't try to (pointlessly) write the page again for a while. * * Really, these pages should not be on the LRU at all. */static int ramdisk_writepage(struct page *page, struct writeback_control *wbc){	if (!PageUptodate(page))		make_page_uptodate(page);	SetPageDirty(page);	if (wbc->for_reclaim)		return WRITEPAGE_ACTIVATE;	unlock_page(page);	return 0;}/* * This is a little speedup thing: short-circuit attempts to write back the * ramdisk blockdev inode to its non-existent backing store. */static int ramdisk_writepages(struct address_space *mapping,				struct writeback_control *wbc){	return 0;}/* * ramdisk blockdev pages have their own ->set_page_dirty() because we don't * want them to contribute to dirty memory accounting. */static int ramdisk_set_page_dirty(struct page *page){	SetPageDirty(page);	return 0;}static struct address_space_operations ramdisk_aops = {	.readpage	= ramdisk_readpage,	.prepare_write	= ramdisk_prepare_write,	.commit_write	= ramdisk_commit_write,	.writepage	= ramdisk_writepage,	.set_page_dirty	= ramdisk_set_page_dirty,	.writepages	= ramdisk_writepages,};static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector,				struct address_space *mapping){	pgoff_t index = sector >> (PAGE_CACHE_SHIFT - 9);	unsigned int vec_offset = vec->bv_offset;	int offset = (sector << 9) & ~PAGE_CACHE_MASK;	int size = vec->bv_len;	int err = 0;	do {		int count;		struct page *page;		char *src;		char *dst;		count = PAGE_CACHE_SIZE - offset;		if (count > size)			count = size;		size -= count;		page = grab_cache_page(mapping, index);		if (!page) {			err = -ENOMEM;			goto out;		}		if (!PageUptodate(page))			make_page_uptodate(page);		index++;		if (rw == READ) {			src = kmap_atomic(page, KM_USER0) + offset;			dst = kmap_atomic(vec->bv_page, KM_USER1) + vec_offset;		} else {			src = kmap_atomic(vec->bv_page, KM_USER0) + vec_offset;			dst = kmap_atomic(page, KM_USER1) + offset;		}		offset = 0;		vec_offset += count;		memcpy(dst, src, count);		kunmap_atomic(src, KM_USER0);		kunmap_atomic(dst, KM_USER1);		if (rw == READ)			flush_dcache_page(vec->bv_page);		else			set_page_dirty(page);		unlock_page(page);		put_page(page);	} while (size); out:	return err;}/* *  Basically, my strategy here is to set up a buffer-head which can't be *  deleted, and make that my Ramdisk.  If the request is outside of the *  allocated size, we must get rid of it... * * 19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Added devfs support * */static int rd_make_request(request_queue_t *q, struct bio *bio){	struct block_device *bdev = bio->bi_bdev;	struct address_space * mapping = bdev->bd_inode->i_mapping;	sector_t sector = bio->bi_sector;	unsigned long len = bio->bi_size >> 9;	int rw = bio_data_dir(bio);	struct bio_vec *bvec;	int ret = 0, i;	if (sector + len > get_capacity(bdev->bd_disk))		goto fail;	if (rw==READA)		rw=READ;	bio_for_each_segment(bvec, bio, i) {		ret |= rd_blkdev_pagecache_IO(rw, bvec, sector, mapping);		sector += bvec->bv_len >> 9;	}	if (ret)		goto fail;	bio_endio(bio, bio->bi_size, 0);	return 0;fail:	bio_io_error(bio, bio->bi_size);	return 0;} static int rd_ioctl(struct inode *inode, struct file *file,			unsigned int cmd, unsigned long arg){	int error;	struct block_device *bdev = inode->i_bdev;	if (cmd != BLKFLSBUF)		return -ENOTTY;	/*	 * special: we want to release the ramdisk memory, it's not like with	 * the other blockdevices where this ioctl only flushes away the buffer	 * cache	 */	error = -EBUSY;	down(&bdev->bd_sem);	if (bdev->bd_openers <= 2) {		truncate_inode_pages(bdev->bd_inode->i_mapping, 0);		error = 0;	}	up(&bdev->bd_sem);	return error;}/* * This is the backing_dev_info for the blockdev inode itself.  It doesn't need * writeback and it does not contribute to dirty memory accounting. */static struct backing_dev_info rd_backing_dev_info = {	.ra_pages	= 0,	/* No readahead */	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | BDI_CAP_MAP_COPY,	.unplug_io_fn	= default_unplug_io_fn,};/* * This is the backing_dev_info for the files which live atop the ramdisk * "device".  These files do need writeback and they do contribute to dirty * memory accounting. */static struct backing_dev_info rd_file_backing_dev_info = {	.ra_pages	= 0,	/* No readahead */	.capabilities	= BDI_CAP_MAP_COPY,	/* Does contribute to dirty memory */	.unplug_io_fn	= default_unplug_io_fn,};static int rd_open(struct inode *inode, struct file *filp){	unsigned unit = iminor(inode);	if (rd_bdev[unit] == NULL) {		struct block_device *bdev = inode->i_bdev;		struct address_space *mapping;		unsigned bsize;		int gfp_mask;		inode = igrab(bdev->bd_inode);		rd_bdev[unit] = bdev;		bdev->bd_openers++;		bsize = bdev_hardsect_size(bdev);		bdev->bd_block_size = bsize;		inode->i_blkbits = blksize_bits(bsize);		inode->i_size = get_capacity(bdev->bd_disk)<<9;		mapping = inode->i_mapping;		mapping->a_ops = &ramdisk_aops;		mapping->backing_dev_info = &rd_backing_dev_info;		bdev->bd_inode_backing_dev_info = &rd_file_backing_dev_info;		/*		 * Deep badness.  rd_blkdev_pagecache_IO() needs to allocate		 * pagecache pages within a request_fn.  We cannot recur back		 * into the filesytem which is mounted atop the ramdisk, because		 * that would deadlock on fs locks.  And we really don't want		 * to reenter rd_blkdev_pagecache_IO when we're already within		 * that function.		 *		 * So we turn off __GFP_FS and __GFP_IO.		 *		 * And to give this thing a hope of working, turn on __GFP_HIGH.		 * Hopefully, there's enough regular memory allocation going on		 * for the page allocator emergency pools to keep the ramdisk		 * driver happy.		 */		gfp_mask = mapping_gfp_mask(mapping);		gfp_mask &= ~(__GFP_FS|__GFP_IO);		gfp_mask |= __GFP_HIGH;		mapping_set_gfp_mask(mapping, gfp_mask);	}	return 0;}static struct block_device_operations rd_bd_op = {	.owner =	THIS_MODULE,	.open =		rd_open,	.ioctl =	rd_ioctl,};/* * Before freeing the module, invalidate all of the protected buffers! */static void __exit rd_cleanup(void){	int i;	for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {		struct block_device *bdev = rd_bdev[i];		rd_bdev[i] = NULL;		if (bdev) {			invalidate_bdev(bdev, 1);			blkdev_put(bdev);		}		del_gendisk(rd_disks[i]);		put_disk(rd_disks[i]);		blk_cleanup_queue(rd_queue[i]);	}	devfs_remove("rd");	unregister_blkdev(RAMDISK_MAJOR, "ramdisk");}/* * This is the registration and initialization section of the RAM disk driver */static int __init rd_init(void){	int i;	int err = -ENOMEM;	if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||			(rd_blocksize & (rd_blocksize-1))) {		printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",		       rd_blocksize);		rd_blocksize = BLOCK_SIZE;	}	for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {		rd_disks[i] = alloc_disk(1);		if (!rd_disks[i])			goto out;	}	if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) {		err = -EIO;		goto out;	}	devfs_mk_dir("rd");	for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {		struct gendisk *disk = rd_disks[i];		rd_queue[i] = blk_alloc_queue(GFP_KERNEL);		if (!rd_queue[i])			goto out_queue;		blk_queue_make_request(rd_queue[i], &rd_make_request);		blk_queue_hardsect_size(rd_queue[i], rd_blocksize);		/* rd_size is given in kB */		disk->major = RAMDISK_MAJOR;		disk->first_minor = i;		disk->fops = &rd_bd_op;		disk->queue = rd_queue[i];		disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;		sprintf(disk->disk_name, "ram%d", i);		sprintf(disk->devfs_name, "rd/%d", i);		set_capacity(disk, rd_size * 2);		add_disk(rd_disks[i]);	}	/* rd_size is given in kB */	printk("RAMDISK driver initialized: "		"%d RAM disks of %dK size %d blocksize\n",		CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize);	return 0;out_queue:	unregister_blkdev(RAMDISK_MAJOR, "ramdisk");out:	while (i--) {		put_disk(rd_disks[i]);		blk_cleanup_queue(rd_queue[i]);	}	return err;}module_init(rd_init);module_exit(rd_cleanup);/* options - nonmodular */#ifndef MODULEstatic int __init ramdisk_size(char *str){	rd_size = simple_strtol(str,NULL,0);	return 1;}static int __init ramdisk_size2(char *str)	/* kludge */{	return ramdisk_size(str);}static int __init ramdisk_blocksize(char *str){	rd_blocksize = simple_strtol(str,NULL,0);	return 1;}__setup("ramdisk=", ramdisk_size);__setup("ramdisk_size=", ramdisk_size2);__setup("ramdisk_blocksize=", ramdisk_blocksize);#endif/* options - modular */module_param(rd_size, int, 0);MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");module_param(rd_blocksize, int, 0);MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes.");MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR);MODULE_LICENSE("GPL");

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美电影精品一区二区| 粉嫩av一区二区三区| 欧美日韩国产片| 亚洲第一福利一区| 7777精品伊人久久久大香线蕉| 亚洲一二三四区不卡| 欧美午夜电影在线播放| 视频一区国产视频| 日韩欧美一区二区久久婷婷| 狠狠色丁香婷婷综合| 久久久五月婷婷| 99久久99久久精品免费观看| 亚洲精品国产无天堂网2021| 欧美日韩一区三区四区| 免费成人美女在线观看| 国产欧美日韩亚州综合| 91久久一区二区| 国产精品一区一区| 国产日产欧美精品一区二区三区| 成人av电影在线| 亚洲va欧美va人人爽| 欧美成人女星排名| 成人一区二区三区视频 | 国产美女主播视频一区| 中文在线一区二区| 欧美性大战久久久| 精品午夜久久福利影院| 中文字幕永久在线不卡| 欧美三级电影网站| 国产九色sp调教91| 一区二区欧美国产| 久久综合久久综合亚洲| 色天天综合色天天久久| 美腿丝袜亚洲色图| 亚洲日本在线看| 日韩免费观看高清完整版| 99在线精品观看| 久久超碰97人人做人人爱| 一色屋精品亚洲香蕉网站| 欧美一区二区网站| 99国产精品99久久久久久| 日韩1区2区日韩1区2区| 综合中文字幕亚洲| 欧美成人精精品一区二区频| 激情综合网最新| 亚洲一卡二卡三卡四卡五卡| 亚洲在线观看免费视频| 2021久久国产精品不只是精品| 93久久精品日日躁夜夜躁欧美| 精品亚洲免费视频| 亚洲国产日韩综合久久精品| 国产亚洲综合色| 欧美一区二区三区在| 欧美在线视频不卡| 91免费视频大全| 国产成人免费av在线| 久久精品理论片| 肉肉av福利一精品导航| 一区二区欧美在线观看| 亚洲视频一二区| 国产精品久久国产精麻豆99网站| 精品免费视频一区二区| 欧美亚洲综合网| 97久久精品人人做人人爽| 国产精品中文字幕一区二区三区| 日韩av中文字幕一区二区三区| 亚洲精品大片www| 欧美国产成人在线| 国产视频一区二区在线| 日韩久久久久久| 欧美精品久久一区| 欧美挠脚心视频网站| 在线视频你懂得一区| 色综合色综合色综合色综合色综合| 成人一区二区视频| 成人激情校园春色| 波多野结衣中文字幕一区二区三区| 国产米奇在线777精品观看| 久久 天天综合| 精品中文字幕一区二区小辣椒| 日本午夜精品视频在线观看| 午夜av区久久| 日韩和欧美的一区| 蜜桃久久精品一区二区| 美女视频第一区二区三区免费观看网站| 五月激情六月综合| 青青草精品视频| 久99久精品视频免费观看| 国产一区二区三区最好精华液| 精品无人码麻豆乱码1区2区| 精品综合免费视频观看| 国产成人免费高清| 96av麻豆蜜桃一区二区| 一本大道久久a久久精品综合| 91精品91久久久中77777| 欧美视频三区在线播放| 欧美一区二区在线免费观看| 欧美成人官网二区| 国产拍欧美日韩视频二区| 亚洲国产精品激情在线观看| 亚洲靠逼com| 日韩中文字幕av电影| 国产在线国偷精品产拍免费yy| 国产a精品视频| 欧美自拍偷拍一区| 精品国产麻豆免费人成网站| 亚洲国产精品成人综合色在线婷婷| 日韩理论片中文av| 午夜电影网一区| 国产精品一二三四五| 91欧美一区二区| 日韩欧美卡一卡二| 中文字幕欧美一| 美女精品自拍一二三四| 北条麻妃国产九九精品视频| 欧美久久一区二区| 国产欧美日韩视频在线观看| 亚洲成av人综合在线观看| 国产资源精品在线观看| 色久综合一二码| 精品久久久久久久久久久久久久久| 国产精品国产精品国产专区不片 | 26uuu久久综合| 中文字幕一区二区在线观看| 日韩av一区二区三区| www.欧美色图| 日韩精品中文字幕一区二区三区| 综合久久给合久久狠狠狠97色 | 精品亚洲porn| 欧美三级韩国三级日本一级| 国产精品色眯眯| 免费欧美日韩国产三级电影| 91免费看`日韩一区二区| 欧美xxxxxxxx| 亚洲va欧美va人人爽| 不卡av在线网| 精品电影一区二区三区| 亚洲国产精品久久人人爱| av成人免费在线观看| 精品国产91乱码一区二区三区| 亚洲成人在线观看视频| 99视频热这里只有精品免费| 日韩美女天天操| 水蜜桃久久夜色精品一区的特点| 白白色 亚洲乱淫| 久久精品一区二区三区不卡牛牛 | 日韩欧美aaaaaa| 亚洲影院免费观看| 91在线观看免费视频| 欧美激情一区二区在线| 久久国产精品一区二区| 欧美日韩国产精品自在自线| 亚洲一区影音先锋| 在线视频国内自拍亚洲视频| 亚洲天堂2016| hitomi一区二区三区精品| 国产清纯在线一区二区www| 精品一二三四区| 精品久久久久一区| 另类小说综合欧美亚洲| 91精品国产91久久久久久最新毛片| 亚洲一区在线观看免费 | 国产91精品一区二区麻豆网站| 日韩一区二区三区四区五区六区| 亚洲成人精品在线观看| 欧美日韩情趣电影| 亚洲高清视频的网址| 欧美日韩一本到| 午夜免费久久看| 91精品婷婷国产综合久久性色 | 91精品国产一区二区三区香蕉 | 秋霞午夜av一区二区三区| 欧美男女性生活在线直播观看| 亚洲国产精品久久艾草纯爱| 精品视频一区二区三区免费| 亚洲成人激情综合网| 欧美二区在线观看| 日韩**一区毛片| 欧美精品一区二区三区久久久| 激情都市一区二区| 国产调教视频一区| 91一区二区三区在线播放| 一区二区三区免费网站| 欧美高清视频在线高清观看mv色露露十八| 香蕉av福利精品导航| 日韩精品最新网址| 国产精品一区二区黑丝| 亚洲欧美综合在线精品| 欧美性猛片xxxx免费看久爱| 日韩精品欧美精品| 久久日韩粉嫩一区二区三区| 高清beeg欧美| 亚洲一区二区三区视频在线播放| 欧美日韩激情在线| 久色婷婷小香蕉久久| 欧美国产精品中文字幕| 欧美日韩一卡二卡三卡| 精东粉嫩av免费一区二区三区| 国产精品女主播av| 欧美日韩视频在线观看一区二区三区|