linux系统调用之sys_close(基于linux0.11)

进程PCB中有一个指针数组,文件描述符是数组索引,每个元素指向一个file结构体,file结构体有一个字段指向文件对应的inode。关闭一个文件主要的步骤是
1 根据文件描述符,把指针数组对应项置空。
2 如果指向的file结构也没有其他进程使用了,则file结构体可以重用。但是他指向的inode节点需要回写到硬盘。具体参考iput函数。

// 解除文件描述符->file结构体->inode的关联
int sys_close(unsigned int fd)
{	
	struct file * filp;

	if (fd >= NR_OPEN)
		return -EINVAL;
	// 清除close_on_exec标记,该标记表示fork+exec时关闭该文件
	current->close_on_exec &= ~(1<<fd);
	if (!(filp = current->filp[fd]))
		return -EINVAL;
	// 当前进程的文件描述符指针置空
	current->filp[fd] = NULL;
	if (filp->f_count == 0)
		panic("Close: file count is 0");
	// file结构引用数减一,非0说明还有其他进程或描述符在使用该结构,所以还不能释放file和inode
	if (--filp->f_count)
		return (0);
	// 没有进程使用了则释放该inode或需要回写到硬盘
	iput(filp->f_inode);
	return (0);
}

// 释放inode,如果没有被引用了,则销毁,否则引用数减一即可
void iput(struct m_inode * inode)
{
	if (!inode)
		return;
	// 有进程在使用该inode则阻塞
	wait_on_inode(inode);
	// 没有进程引用该inode
	if (!inode->i_count)
		panic("iput: trying to free free inode");
	// 管道inode
	if (inode->i_pipe) {
		// 唤醒等待队列,因为该管道可能要被销毁了,不然那会使等待者无限等待,这句是不是可以放到if后
		wake_up(&inode->i_wait);
		// 引用数减一,还有进程在引用则先不销毁
		if (--inode->i_count)
			return;
		// 释放管道对应的一页大小
		free_page(inode->i_size);
		// 该inode可以重用,因为inode指向inode_table的元素
		inode->i_count=0;
		inode->i_dirt=0;
		inode->i_pipe=0;
		return;
	}
	// 没有dev说明不是硬盘文件对应的inode,不需要回写硬盘,引用数减一即可
	if (!inode->i_dev) {
		inode->i_count--;
		return;
	}
	if (S_ISBLK(inode->i_mode)) {
		// 块文件,inode->i_zone[0]保存的是设备号,把buffer中属于该dev设备的回写到硬盘
		sync_dev(inode->i_zone[0]);
		wait_on_inode(inode);
	}
repeat:
	// 还有进程引用该inode节点,引用数减一后返回
	if (inode->i_count>1) {
		inode->i_count--;
		return;
	}
	// 该inode没有进程引用了,inode对应的文件也没有被其他目录项引用了,删除该inode的内容,并释放该inode
	if (!inode->i_nlinks) {
		truncate(inode);
		free_inode(inode);
		return;
	}
	// 需要回写硬盘,则回写
	if (inode->i_dirt) {
		write_inode(inode);	/* we can sleep - so do again */
		wait_on_inode(inode);
		goto repeat;
	}
	inode->i_count--;
	return;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值