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

📄 dir.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
			    rlen, ufs_get_de_namlen(sb, de));		return (error_msg == NULL ? 1 : 0);}struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct buffer_head **p){	int err;	struct buffer_head *bh = ufs_bread (dir, 0, 0, &err);	struct ufs_dir_entry *res = NULL;	if (bh) {		res = (struct ufs_dir_entry *) bh->b_data;		res = (struct ufs_dir_entry *)((char *)res +			fs16_to_cpu(dir->i_sb, res->d_reclen));	}	*p = bh;	return res;}ino_t ufs_inode_by_name(struct inode * dir, struct dentry *dentry){	ino_t res = 0;	struct ufs_dir_entry * de;	struct buffer_head *bh;	de = ufs_find_entry (dentry, &bh);	if (de) {		res = fs32_to_cpu(dir->i_sb, de->d_ino);		brelse(bh);	}	return res;}void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,		struct buffer_head *bh, struct inode *inode){	dir->i_version = ++event;	de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);	mark_buffer_dirty(bh);	if (IS_SYNC(dir)) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer(bh);	}	brelse (bh);}/* *	ufs_add_entry() * * adds a file entry to the specified directory, using the same * semantics as ufs_find_entry(). It returns NULL if it failed. */int ufs_add_link(struct dentry *dentry, struct inode *inode){	struct super_block * sb;	struct ufs_sb_private_info * uspi;	unsigned long offset;	unsigned fragoff;	unsigned short rec_len;	struct buffer_head * bh;	struct ufs_dir_entry * de, * de1;	struct inode *dir = dentry->d_parent->d_inode;	const char *name = dentry->d_name.name;	int namelen = dentry->d_name.len;	int err;	UFSD(("ENTER, name %s, namelen %u\n", name, namelen))		sb = dir->i_sb;	uspi = sb->u.ufs_sb.s_uspi;	if (!namelen)		return -EINVAL;	bh = ufs_bread (dir, 0, 0, &err);	if (!bh)		return err;	rec_len = UFS_DIR_REC_LEN(namelen);	offset = 0;	de = (struct ufs_dir_entry *) bh->b_data;	while (1) {		if ((char *)de >= UFS_SECTOR_SIZE + bh->b_data) {			fragoff = offset & ~uspi->s_fmask;			if (fragoff != 0 && fragoff != UFS_SECTOR_SIZE)				ufs_error (sb, "ufs_add_entry", "internal error"					" fragoff %u", fragoff);			if (!fragoff) {				brelse (bh);				bh = ufs_bread (dir, offset >> sb->s_blocksize_bits, 1, &err);				if (!bh)					return err;			}			if (dir->i_size <= offset) {				if (dir->i_size == 0) {					brelse(bh);					return -ENOENT;				}				de = (struct ufs_dir_entry *) (bh->b_data + fragoff);				de->d_ino = 0;				de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE);				ufs_set_de_namlen(sb, de, 0);				dir->i_size = offset + UFS_SECTOR_SIZE;				mark_inode_dirty(dir);			} else {				de = (struct ufs_dir_entry *) bh->b_data;			}		}		if (!ufs_check_dir_entry ("ufs_add_entry", dir, de, bh, offset)) {			brelse (bh);			return -ENOENT;		}		if (ufs_match(sb, namelen, name, de)) {			brelse (bh);			return -EEXIST;		}		if (de->d_ino == 0 && fs16_to_cpu(sb, de->d_reclen) >= rec_len)			break;					if (fs16_to_cpu(sb, de->d_reclen) >=		     UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)) + rec_len)			break;		offset += fs16_to_cpu(sb, de->d_reclen);		de = (struct ufs_dir_entry *) ((char *) de + fs16_to_cpu(sb, de->d_reclen));	}	if (de->d_ino) {		de1 = (struct ufs_dir_entry *) ((char *) de +			UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)));		de1->d_reclen =			cpu_to_fs16(sb, fs16_to_cpu(sb, de->d_reclen) -				UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)));		de->d_reclen =			cpu_to_fs16(sb, UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)));		de = de1;	}	de->d_ino = 0;	ufs_set_de_namlen(sb, de, namelen);	memcpy (de->d_name, name, namelen + 1);	de->d_ino = cpu_to_fs32(sb, inode->i_ino);	ufs_set_de_type(sb, de, inode->i_mode);	mark_buffer_dirty(bh);	if (IS_SYNC(dir)) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer (bh);	}	brelse (bh);	dir->i_mtime = dir->i_ctime = CURRENT_TIME;	dir->i_version = ++event;	mark_inode_dirty(dir);	UFSD(("EXIT\n"))	return 0;}/* * ufs_delete_entry deletes a directory entry by merging it with the * previous entry. */int ufs_delete_entry (struct inode * inode, struct ufs_dir_entry * dir,	struct buffer_head * bh )	{	struct super_block * sb;	struct ufs_dir_entry * de, * pde;	unsigned i;		UFSD(("ENTER\n"))	sb = inode->i_sb;	i = 0;	pde = NULL;	de = (struct ufs_dir_entry *) bh->b_data;		UFSD(("ino %u, reclen %u, namlen %u, name %s\n",		fs32_to_cpu(sb, de->d_ino),		fs16to_cpu(sb, de->d_reclen),		ufs_get_de_namlen(sb, de), de->d_name))	while (i < bh->b_size) {		if (!ufs_check_dir_entry ("ufs_delete_entry", inode, de, bh, i)) {			brelse(bh);			return -EIO;		}		if (de == dir)  {			if (pde)				fs16_add(sb, &pde->d_reclen,					fs16_to_cpu(sb, dir->d_reclen));			dir->d_ino = 0;			inode->i_version = ++event;			inode->i_ctime = inode->i_mtime = CURRENT_TIME;			mark_inode_dirty(inode);			mark_buffer_dirty(bh);			if (IS_SYNC(inode)) {				ll_rw_block(WRITE, 1, &bh);				wait_on_buffer(bh);			}			brelse(bh);			UFSD(("EXIT\n"))			return 0;		}		i += fs16_to_cpu(sb, de->d_reclen);		if (i == UFS_SECTOR_SIZE) pde = NULL;		else pde = de;		de = (struct ufs_dir_entry *)		    ((char *) de + fs16_to_cpu(sb, de->d_reclen));		if (i == UFS_SECTOR_SIZE && de->d_reclen == 0)			break;	}	UFSD(("EXIT\n"))	brelse(bh);	return -ENOENT;}int ufs_make_empty(struct inode * inode, struct inode *dir){	struct super_block * sb = dir->i_sb;	struct buffer_head * dir_block;	struct ufs_dir_entry * de;	int err;	dir_block = ufs_bread (inode, 0, 1, &err);	if (!dir_block)		return err;	inode->i_blocks = sb->s_blocksize / UFS_SECTOR_SIZE;	de = (struct ufs_dir_entry *) dir_block->b_data;	de->d_ino = cpu_to_fs32(sb, inode->i_ino);	ufs_set_de_type(sb, de, inode->i_mode);	ufs_set_de_namlen(sb, de, 1);	de->d_reclen = cpu_to_fs16(sb, UFS_DIR_REC_LEN(1));	strcpy (de->d_name, ".");	de = (struct ufs_dir_entry *)		((char *)de + fs16_to_cpu(sb, de->d_reclen));	de->d_ino = cpu_to_fs32(sb, dir->i_ino);	ufs_set_de_type(sb, de, dir->i_mode);	de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1));	ufs_set_de_namlen(sb, de, 2);	strcpy (de->d_name, "..");	mark_buffer_dirty(dir_block);	brelse (dir_block);	mark_inode_dirty(inode);	return 0;}/* * routine to check that the specified directory is empty (for rmdir) */int ufs_empty_dir (struct inode * inode){	struct super_block * sb;	unsigned long offset;	struct buffer_head * bh;	struct ufs_dir_entry * de, * de1;	int err;		sb = inode->i_sb;	if (inode->i_size < UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||	    !(bh = ufs_bread (inode, 0, 0, &err))) {	    	ufs_warning (inode->i_sb, "empty_dir",			      "bad directory (dir #%lu) - no data block",			      inode->i_ino);		return 1;	}	de = (struct ufs_dir_entry *) bh->b_data;	de1 = (struct ufs_dir_entry *)		((char *)de + fs16_to_cpu(sb, de->d_reclen));	if (fs32_to_cpu(sb, de->d_ino) != inode->i_ino || de1->d_ino == 0 ||	     strcmp (".", de->d_name) || strcmp ("..", de1->d_name)) {	    	ufs_warning (inode->i_sb, "empty_dir",			      "bad directory (dir #%lu) - no `.' or `..'",			      inode->i_ino);		return 1;	}	offset = fs16_to_cpu(sb, de->d_reclen) + fs16_to_cpu(sb, de1->d_reclen);	de = (struct ufs_dir_entry *)		((char *)de1 + fs16_to_cpu(sb, de1->d_reclen));	while (offset < inode->i_size ) {		if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {			brelse (bh);			bh = ufs_bread (inode, offset >> sb->s_blocksize_bits, 1, &err);	 		if (!bh) {				ufs_error (sb, "empty_dir",					    "directory #%lu contains a hole at offset %lu",					    inode->i_ino, offset);				offset += sb->s_blocksize;				continue;			}			de = (struct ufs_dir_entry *) bh->b_data;		}		if (!ufs_check_dir_entry ("empty_dir", inode, de, bh, offset)) {			brelse (bh);			return 1;		}		if (de->d_ino) {			brelse (bh);			return 0;		}		offset += fs16_to_cpu(sb, de->d_reclen);		de = (struct ufs_dir_entry *)			((char *)de + fs16_to_cpu(sb, de->d_reclen));	}	brelse (bh);	return 1;}struct file_operations ufs_dir_operations = {	read:		generic_read_dir,	readdir:	ufs_readdir,	fsync:		file_fsync,};

⌨️ 快捷键说明

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