Exemplo n.º 1
0
static void
flash_release(struct inode *inode, struct file *filp)
{
#ifdef CONFIG_BLK_DEV_FLASH
	sync_dev(inode->i_rdev);
#endif
	return;
}
Exemplo n.º 2
0
static void
mcd_release(struct inode * inode, struct file * file)
{   MOD_DEC_USE_COUNT;
    if (!--mcd_open_count) {
        mcd_invalidate_buffers();
        sync_dev(inode->i_rdev);
        invalidate_buffers(inode -> i_rdev);
    }
}
Exemplo n.º 3
0
/*
 * Ok, this is getblk, and it isn't very clear, again to hinder
 * race-conditions. Most of the code is seldom used, (ie repeating),
 * so it should be much more efficient than it looks.
 */
struct buffer_head * getblk(int dev,int block)
{
	struct buffer_head * tmp;

repeat:
	if ((tmp=get_hash_table(dev,block)))
		return tmp;
	tmp = free_list;
	do {
		if (!tmp->b_count) {
			wait_on_buffer(tmp);	/* we still have to wait */
			if (!tmp->b_count)	/* on it, it might be dirty */
				break;
		}
		tmp = tmp->b_next_free;
	} while (tmp != free_list || (tmp=NULL));
	/* Kids, don't try THIS at home ^^^^^. Magic */
	if (!tmp) {
		printk("Sleeping on free buffer ..");
		sleep_on(&buffer_wait);
		printk("ok\n");
		goto repeat;
	}
	tmp->b_count++;
	remove_from_queues(tmp);
/*
 * Now, when we know nobody can get to this node (as it's removed from the
 * free list), we write it out. We can sleep here without fear of race-
 * conditions.
 */
	if (tmp->b_dirt)
		sync_dev(tmp->b_dev);
/* update buffer contents */
	tmp->b_dev=dev;
	tmp->b_blocknr=block;
	tmp->b_dirt=0;
	tmp->b_uptodate=0;
/* NOTE!! While we possibly slept in sync_dev(), somebody else might have
 * added "this" block already, so check for that. Thank God for goto's.
 */
	if (find_buffer(dev,block)) {
		tmp->b_dev=0;		/* ok, someone else has beaten us */
		tmp->b_blocknr=0;	/* to it - free this block and */
		tmp->b_count=0;		/* try again */
		insert_into_queues(tmp);
		goto repeat;
	}
/* and then insert into correct position */
	insert_into_queues(tmp);
	return tmp;
}
Exemplo n.º 4
0
struct buffer_head * getblk(int dev,int block)
{
	struct buffer_head * bh, * tmp;
	int buffers;

repeat:
	if (bh = get_hash_table(dev,block))
		return bh;
	buffers = NR_BUFFERS;
	tmp = free_list;
	do {
		tmp = tmp->b_next_free;
		if (tmp->b_count)
			continue;
		if (!bh || BADNESS(tmp)<BADNESS(bh)) {
			bh = tmp;
			if (!BADNESS(tmp))
				break;
		}
		if (tmp->b_dirt)
			ll_rw_block(WRITEA,tmp);
/* and repeat until we find something good */
	} while (buffers--);
	if (!bh) {
		sleep_on(&buffer_wait);
		goto repeat;
	}
	wait_on_buffer(bh);
	if (bh->b_count)
		goto repeat;
	while (bh->b_dirt) {
		sync_dev(bh->b_dev);
		wait_on_buffer(bh);
		if (bh->b_count)
			goto repeat;
	}
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
	if (find_buffer(dev,block))
		goto repeat;
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
	bh->b_count=1;
	bh->b_dirt=0;
	bh->b_uptodate=0;
	remove_from_queues(bh);
	bh->b_dev=dev;
	bh->b_blocknr=block;
	insert_into_queues(bh);
	return bh;
}
Exemplo n.º 5
0
static void sd_release(struct inode * inode, struct file * file)
{
        int target;
	sync_dev(inode->i_rdev);

	target =  DEVICE_NR(MINOR(inode->i_rdev));

	rscsi_disks[target].device->access_count--;

	if(rscsi_disks[target].device->removable) {
	  if(!rscsi_disks[target].device->access_count)
	    sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
	};
}
Exemplo n.º 6
0
//// 取高速缓冲中指定的缓冲区。
// 检查所指定的缓冲区是否已经在高速缓冲中,如果不在,就需要在高速缓冲中建立一个对应的新项。
// 返回相应缓冲区头指针。
struct buffer_head *
getblk( int dev, int block )
{
	struct buffer_head *tmp, *bh;

repeat:
// 搜索hash 表,如果指定块已经在高速缓冲中,则返回对应缓冲区头指针,退出。
	if( bh = get_hash_table( dev, block ) )
	{
		return bh;
	}
// 扫描空闲数据块链表,寻找空闲缓冲区。
// 首先让tmp 指向空闲链表的第一个空闲缓冲区头。
	tmp = free_list;
	do
	{
// 如果该缓冲区正被使用(引用计数不等于0),则继续扫描下一项。
		if( tmp->b_count )
		{
			continue;
		}
// 如果缓冲头指针bh 为空,或者tmp 所指缓冲头的标志(修改、锁定)权重小于bh 头标志的权重,
// 则让bh 指向该tmp 缓冲区头。如果该tmp 缓冲区头表明缓冲区既没有修改也没有锁定标志置位,
// 则说明已为指定设备上的块取得对应的高速缓冲区,则退出循环。
		if( !bh || BADNESS( tmp ) < BADNESS( bh ) )
		{
			bh = tmp;
			if( !BADNESS( tmp ) )
			{
				break;
			}
		}
/* and repeat until we find something good *//* 重复操作直到找到适合的缓冲区 */
	}
	while( ( tmp = tmp->b_next_free ) != free_list );
// 如果所有缓冲区都正被使用(所有缓冲区的头部引用计数都>0),则睡眠,等待有空闲的缓冲区可用。
	if( !bh )
	{
		sleep_on( &buffer_wait );
		goto repeat;
	}
// 等待该缓冲区解锁(如果已被上锁的话)。
	wait_on_buffer( bh );
// 如果该缓冲区又被其它任务使用的话,只好重复上述过程。
	if( bh->b_count )
	{
		goto repeat;
	}
// 如果该缓冲区已被修改,则将数据写盘,并再次等待缓冲区解锁。如果该缓冲区又被其它任务使用
// 的话,只好再重复上述过程。
	while( bh->b_dirt )
	{
		sync_dev( bh->b_dev );
		wait_on_buffer( bh );
		if( bh->b_count )
		{
			goto repeat;
		}
	}
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
/* 注意!!当进程为了等待该缓冲块而睡眠时,其它进程可能已经将该缓冲块 */
	** /
// 在高速缓冲hash 表中检查指定设备和块的缓冲区是否已经被加入进去。如果是的话,就再次重复
// 上述过程。
	if( find_buffer( dev, block ) )
	{
		goto repeat;
	}
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
/* OK,最终我们知道该缓冲区是指定参数的唯一一块,*/
/* 而且还没有被使用(b_count=0),未被上锁(b_lock=0),并且是干净的(未被修改的)*/
// 于是让我们占用此缓冲区。置引用计数为1,复位修改标志和有效(更新)标志。
	bh->b_count	   = 1;
	bh->b_dirt	   = 0;
	bh->b_uptodate = 0;
// 从hash 队列和空闲块链表中移出该缓冲区头,让该缓冲区用于指定设备和其上的指定块。
	remove_from_queues( bh );
	bh->b_dev	   = dev;
	bh->b_blocknr  = block;
// 然后根据此新的设备号和块号重新插入空闲链表和hash 队列新位置处。并最终返回缓冲头指针。
	insert_into_queues( bh );
	return bh;
}
Exemplo n.º 7
0
//检查指定(设备号和块号)的缓冲区是否已经在高速缓冲中。如果指定块已经在高速缓冲中,则返回
//对应缓冲区头指针退出;如果不在,就需要在高速缓冲中设置一个对应设备号和块号的新项。返回相应
//缓冲区头指针
struct buffer_head * getblk(int dev,int block)
{
	struct buffer_head * tmp, * bh;

repeat:
	if ( (bh = get_hash_table(dev,block)) )
		return bh;
	tmp = free_list;
	do {
		if (tmp->b_count)
			continue;
		if (!bh || BADNESS(tmp)<BADNESS(bh)) {
			bh = tmp;
			if (!BADNESS(tmp))
				break;
		}
/* and repeat until we find something good */
	} while ((tmp = tmp->b_next_free) != free_list);
	
	//如果循环检查所有缓冲块都正在被使用(所有缓冲块的头部引用计数都>0)中,则睡眠等待有空闲
	//缓冲块可用。当有空闲块可用时本进程会被明确地唤醒。然后我们就跳转到函数开始处重新查找空闲
	//缓冲块
	if (!bh) {
		sleep_on(&buffer_wait);
		goto repeat;
	}
	
	//如果跑到这里,说明已经找到一个空闲的缓冲区块。于是先等待该缓冲区解锁(如果已经被上锁的话)。
	wait_on_buffer(bh);
	if (bh->b_count)
		goto repeat;
	
	//如果该缓冲区已被修改,则将数据写盘,并再次等待缓冲区解锁。
	while (bh->b_dirt) {
		sync_dev(bh->b_dev);
		wait_on_buffer(bh);
		if (bh->b_count)
			goto repeat;
	}
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
	//当进程为了等待该缓冲块而睡眠时,其他进程可能已经将该缓冲块进入高速缓冲中,因此我们也要对此进行检查
	if (find_buffer(dev,block))
		goto repeat;
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
	
	//到了这里,最终我们知道该缓冲块是指定参数的唯一一块,而且目前还没有被占用(b_count=0)
	//也没有被上锁(b_lock=0),而且是干净的(b_dirt=0)
	//于是我们占用此缓冲块。置引用计数为1,复位修改标志和有效标志
	bh->b_count=1;
	bh->b_dirt=0;
	bh->b_uptodate=0;
	//从hash队列和空闲块链表中移出该缓冲区头,让该缓冲区用于指定设备和其上的指定块。然后根据
	//此新的设备号和块号重新插入空闲链表和hash队列新位置处。并最终返回缓冲头指针。
	remove_from_queues(bh);
	bh->b_dev=dev;
	bh->b_blocknr=block;
	insert_into_queues(bh);
	return bh;
}
Exemplo n.º 8
0
asmlinkage int sys_sync(void)
{
	sync_dev(0);
	return 0;
}
Exemplo n.º 9
0
//// 取高速缓冲中指定的缓冲区。
// 检查所指定的缓冲区是否已经在高速缓冲中,如果不在,就需要在高速缓冲中建立一个对应的新项。
// 返回相应缓冲区头指针。
struct buffer_head * getblk(int dev,int block)
{
	struct buffer_head * tmp, * bh;

repeat:
	// 搜索hash 表,如果指定块已经在高速缓冲中,则返回对应缓冲区头指针,退出。
	if (bh = get_hash_table(dev,block))
		return bh;
// 扫描空闲数据块链表,寻找空闲缓冲区。
// 首先让tmp 指向空闲链表的第一个空闲缓冲区头。
	tmp = free_list;
	do {
// 如果该缓冲区正被使用(引用计数不等于0),则继续扫描下一项。
		if (tmp->b_count)
			continue;
// 如果缓冲头指针bh 为空,或者tmp 所指缓冲头的标志(修改、锁定)权重小于bh 头标志的权重,
// 则让bh 指向该tmp 缓冲区头。如果该tmp 缓冲区头表明缓冲区既没有修改也没有锁定标志置位,
// 则说明已为指定设备上的块取得对应的高速缓冲区,则退出循环。
		if (!bh || BADNESS(tmp)<BADNESS(bh)) {
			bh = tmp;
			if (!BADNESS(tmp))
				break;
		}
/* 重复操作直到找到适合的缓冲区 */
	} while ((tmp = tmp->b_next_free) != free_list);
// 如果所有缓冲区都正被使用(所有缓冲区的头部引用计数都>0),
// 则睡眠,等待有空闲的缓冲区可用。
	if (!bh) {
		sleep_on(&buffer_wait);
		goto repeat;
	}
	// 等待该缓冲区解锁(如果已被上锁的话)。
	wait_on_buffer(bh);
	// 如果该缓冲区又被其它任务使用的话,只好重复上述过程。
	if (bh->b_count)
		goto repeat;
// 如果该缓冲区已被修改,则将数据写盘,并再次等待缓冲区解锁。如果该缓冲区又被其它任务使用
// 的话,只好再重复上述过程。
	while (bh->b_dirt) {
		sync_dev(bh->b_dev);
		wait_on_buffer(bh);
		if (bh->b_count)
			goto repeat;
	}
/* 注意!!当进程为了等待该缓冲块而睡眠时,其它进程可能已经将该缓冲块 */
/* 加入进高速缓冲中,所以要对此进行检查。 */
// 在高速缓冲hash 表中检查指定设备和块的缓冲区是否已经被加入进去。如果是的话,就再次重复
// 上述过程。
	if (find_buffer(dev,block))
		goto repeat;
/* OK,最终我们知道该缓冲区是指定参数的唯一一块, */
/* 而且还没有被使用(b_count=0),未被上锁(b_lock=0),并且是干净的(未被修改的) */
// 于是让我们占用此缓冲区。置引用计数为1,复位修改标志和有效(更新)标志。
	bh->b_count=1;
	bh->b_dirt=0;
	bh->b_uptodate=0;
// 从hash 队列和空闲块链表中移出该缓冲区头,让该缓冲区用于指定设备和其上的指定块。
	remove_from_queues(bh);
	bh->b_dev=dev;
	bh->b_blocknr=block;
// 然后根据此新的设备号和块号重新插入空闲链表和hash 队列新位置处。并最终返回缓冲头指针。
	insert_into_queues(bh);
	return bh;
}