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

📄 namei.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		    NAME_NOT_FOUND) {			reiserfs_warning(dir->i_sb,					 "vs-7032: reiserfs_add_entry: "					 "entry with this key (%K) already exists",					 &entry_key);			if (buffer != small_buf)				kfree(buffer);			pathrelse(&path);			return -EBUSY;		}	}	/* perform the insertion of the entry that we have prepared */	retval =	    reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer,				     paste_size);	if (buffer != small_buf)		kfree(buffer);	if (retval) {		reiserfs_check_path(&path);		return retval;	}	dir->i_size += paste_size;	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;	if (!S_ISDIR(inode->i_mode) && visible)		// reiserfs_mkdir or reiserfs_rename will do that by itself		reiserfs_update_sd(th, dir);	reiserfs_check_path(&path);	return 0;}/* quota utility function, call if you've had to abort after calling** new_inode_init, and have not called reiserfs_new_inode yet.** This should only be called on inodes that do not have stat data** inserted into the tree yet.*/static int drop_new_inode(struct inode *inode){	DQUOT_DROP(inode);	make_bad_inode(inode);	inode->i_flags |= S_NOQUOTA;	iput(inode);	return 0;}/* utility function that does setup for reiserfs_new_inode.  ** DQUOT_INIT needs lots of credits so it's better to have it** outside of a transaction, so we had to pull some bits of** reiserfs_new_inode out into this func.*/static int new_inode_init(struct inode *inode, struct inode *dir, int mode){	/* the quota init calls have to know who to charge the quota to, so	 ** we have to set uid and gid here	 */	inode->i_uid = current->fsuid;	inode->i_mode = mode;	/* Make inode invalid - just in case we are going to drop it before	 * the initialization happens */	INODE_PKEY(inode)->k_objectid = 0;	if (dir->i_mode & S_ISGID) {		inode->i_gid = dir->i_gid;		if (S_ISDIR(mode))			inode->i_mode |= S_ISGID;	} else {		inode->i_gid = current->fsgid;	}	DQUOT_INIT(inode);	return 0;}static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,			   struct nameidata *nd){	int retval;	struct inode *inode;	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */	int jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 2 +	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));	struct reiserfs_transaction_handle th;	int locked;	if (!(inode = new_inode(dir->i_sb))) {		return -ENOMEM;	}	new_inode_init(inode, dir, mode);	locked = reiserfs_cache_default_acl(dir);	reiserfs_write_lock(dir->i_sb);	if (locked)		reiserfs_write_lock_xattrs(dir->i_sb);	retval = journal_begin(&th, dir->i_sb, jbegin_count);	if (retval) {		drop_new_inode(inode);		goto out_failed;	}	retval =	    reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,			       inode);	if (retval)		goto out_failed;	if (locked) {		reiserfs_write_unlock_xattrs(dir->i_sb);		locked = 0;	}	inode->i_op = &reiserfs_file_inode_operations;	inode->i_fop = &reiserfs_file_operations;	inode->i_mapping->a_ops = &reiserfs_address_space_operations;	retval =	    reiserfs_add_entry(&th, dir, dentry->d_name.name,			       dentry->d_name.len, inode, 1 /*visible */ );	if (retval) {		int err;		inode->i_nlink--;		reiserfs_update_sd(&th, inode);		err = journal_end(&th, dir->i_sb, jbegin_count);		if (err)			retval = err;		iput(inode);		goto out_failed;	}	reiserfs_update_inode_transaction(inode);	reiserfs_update_inode_transaction(dir);	d_instantiate(dentry, inode);	retval = journal_end(&th, dir->i_sb, jbegin_count);      out_failed:	if (locked)		reiserfs_write_unlock_xattrs(dir->i_sb);	reiserfs_write_unlock(dir->i_sb);	return retval;}static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,			  dev_t rdev){	int retval;	struct inode *inode;	struct reiserfs_transaction_handle th;	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */	int jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 3 +	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));	int locked;	if (!new_valid_dev(rdev))		return -EINVAL;	if (!(inode = new_inode(dir->i_sb))) {		return -ENOMEM;	}	new_inode_init(inode, dir, mode);	locked = reiserfs_cache_default_acl(dir);	reiserfs_write_lock(dir->i_sb);	if (locked)		reiserfs_write_lock_xattrs(dir->i_sb);	retval = journal_begin(&th, dir->i_sb, jbegin_count);	if (retval) {		drop_new_inode(inode);		goto out_failed;	}	retval =	    reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,			       inode);	if (retval) {		goto out_failed;	}	if (locked) {		reiserfs_write_unlock_xattrs(dir->i_sb);		locked = 0;	}	inode->i_op = &reiserfs_special_inode_operations;	init_special_inode(inode, inode->i_mode, rdev);	//FIXME: needed for block and char devices only	reiserfs_update_sd(&th, inode);	reiserfs_update_inode_transaction(inode);	reiserfs_update_inode_transaction(dir);	retval =	    reiserfs_add_entry(&th, dir, dentry->d_name.name,			       dentry->d_name.len, inode, 1 /*visible */ );	if (retval) {		int err;		inode->i_nlink--;		reiserfs_update_sd(&th, inode);		err = journal_end(&th, dir->i_sb, jbegin_count);		if (err)			retval = err;		iput(inode);		goto out_failed;	}	d_instantiate(dentry, inode);	retval = journal_end(&th, dir->i_sb, jbegin_count);      out_failed:	if (locked)		reiserfs_write_unlock_xattrs(dir->i_sb);	reiserfs_write_unlock(dir->i_sb);	return retval;}static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode){	int retval;	struct inode *inode;	struct reiserfs_transaction_handle th;	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */	int jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 3 +	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));	int locked;#ifdef DISPLACE_NEW_PACKING_LOCALITIES	/* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */	REISERFS_I(dir)->new_packing_locality = 1;#endif	mode = S_IFDIR | mode;	if (!(inode = new_inode(dir->i_sb))) {		return -ENOMEM;	}	new_inode_init(inode, dir, mode);	locked = reiserfs_cache_default_acl(dir);	reiserfs_write_lock(dir->i_sb);	if (locked)		reiserfs_write_lock_xattrs(dir->i_sb);	retval = journal_begin(&th, dir->i_sb, jbegin_count);	if (retval) {		drop_new_inode(inode);		goto out_failed;	}	/* inc the link count now, so another writer doesn't overflow it while	 ** we sleep later on.	 */	INC_DIR_INODE_NLINK(dir)	    retval = reiserfs_new_inode(&th, dir, mode, NULL /*symlink */ ,					old_format_only(dir->i_sb) ?					EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,					dentry, inode);	if (retval) {		dir->i_nlink--;		goto out_failed;	}	if (locked) {		reiserfs_write_unlock_xattrs(dir->i_sb);		locked = 0;	}	reiserfs_update_inode_transaction(inode);	reiserfs_update_inode_transaction(dir);	inode->i_op = &reiserfs_dir_inode_operations;	inode->i_fop = &reiserfs_dir_operations;	// note, _this_ add_entry will not update dir's stat data	retval =	    reiserfs_add_entry(&th, dir, dentry->d_name.name,			       dentry->d_name.len, inode, 1 /*visible */ );	if (retval) {		int err;		inode->i_nlink = 0;		DEC_DIR_INODE_NLINK(dir);		reiserfs_update_sd(&th, inode);		err = journal_end(&th, dir->i_sb, jbegin_count);		if (err)			retval = err;		iput(inode);		goto out_failed;	}	// the above add_entry did not update dir's stat data	reiserfs_update_sd(&th, dir);	d_instantiate(dentry, inode);	retval = journal_end(&th, dir->i_sb, jbegin_count);      out_failed:	if (locked)		reiserfs_write_unlock_xattrs(dir->i_sb);	reiserfs_write_unlock(dir->i_sb);	return retval;}static inline int reiserfs_empty_dir(struct inode *inode){	/* we can cheat because an old format dir cannot have	 ** EMPTY_DIR_SIZE, and a new format dir cannot have	 ** EMPTY_DIR_SIZE_V1.  So, if the inode is either size, 	 ** regardless of disk format version, the directory is empty.	 */	if (inode->i_size != EMPTY_DIR_SIZE &&	    inode->i_size != EMPTY_DIR_SIZE_V1) {		return 0;	}	return 1;}static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry){	int retval, err;	struct inode *inode;	struct reiserfs_transaction_handle th;	int jbegin_count;	INITIALIZE_PATH(path);	struct reiserfs_dir_entry de;	/* we will be doing 2 balancings and update 2 stat data, we change quotas	 * of the owner of the directory and of the owner of the parent directory.	 * The quota structure is possibly deleted only on last iput => outside	 * of this transaction */	jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 2 + 2 +	    4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);	reiserfs_write_lock(dir->i_sb);	retval = journal_begin(&th, dir->i_sb, jbegin_count);	if (retval)		goto out_rmdir;	de.de_gen_number_bit_string = NULL;	if ((retval =	     reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,				 &path, &de)) == NAME_NOT_FOUND) {		retval = -ENOENT;		goto end_rmdir;	} else if (retval == IO_ERROR) {		retval = -EIO;		goto end_rmdir;	}	inode = dentry->d_inode;	reiserfs_update_inode_transaction(inode);	reiserfs_update_inode_transaction(dir);	if (de.de_objectid != inode->i_ino) {		// FIXME: compare key of an object and a key found in the		// entry		retval = -EIO;		goto end_rmdir;	}	if (!reiserfs_empty_dir(inode)) {		retval = -ENOTEMPTY;		goto end_rmdir;	}	/* cut entry from dir directory */	retval = reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL,	/* page */					0 /*new file size - not used here */ );	if (retval < 0)		goto end_rmdir;	if (inode->i_nlink != 2 && inode->i_nlink != 1)		reiserfs_warning(inode->i_sb, "%s: empty directory has nlink "				 "!= 2 (%d)", __FUNCTION__, inode->i_nlink);	clear_nlink(inode);	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;	reiserfs_update_sd(&th, inode);	DEC_DIR_INODE_NLINK(dir)	    dir->i_size -= (DEH_SIZE + de.de_entrylen);	reiserfs_update_sd(&th, dir);	/* prevent empty directory from getting lost */	add_save_link(&th, inode, 0 /* not truncate */ );	retval = journal_end(&th, dir->i_sb, jbegin_count);	reiserfs_check_path(&path);      out_rmdir:	reiserfs_write_unlock(dir->i_sb);	return retval;      end_rmdir:	/* we must release path, because we did not call	   reiserfs_cut_from_item, or reiserfs_cut_from_item does not	   release path if operation was not complete */	pathrelse(&path);	err = journal_end(&th, dir->i_sb, jbegin_count);	reiserfs_write_unlock(dir->i_sb);	return err ? err : retval;}static int reiserfs_unlink(struct inode *dir, struct dentry *dentry){	int retval, err;	struct inode *inode;	struct reiserfs_dir_entry de;	INITIALIZE_PATH(path);	struct reiserfs_transaction_handle th;	int jbegin_count;	unsigned long savelink;	inode = dentry->d_inode;	/* in this transaction we can be doing at max two balancings and update	 * two stat datas, we change quotas of the owner of the directory and of	 * the owner of the parent directory. The quota structure is possibly	 * deleted only on iput => outside of this transaction */	jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 2 + 2 +	    4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);	reiserfs_write_lock(dir->i_sb);	retval = journal_begin(&th, dir->i_sb, jbegin_count);	if (retval)		goto out_unlink;	de.de_gen_number_bit_string = NULL;	if ((retval =	     reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,				 &path, &de)) == NAME_NOT_FOUND) {		retval = -ENOENT;		goto end_unlink;	} else if (retval == IO_ERROR) {		retval = -EIO;		goto end_unlink;	}	reiserfs_update_inode_transaction(inode);	reiserfs_update_inode_transaction(dir);	if (de.de_objectid != inode->i_ino) {		// FIXME: compare key of an object and a key found in the		// entry		retval = -EIO;		goto end_unlink;	}	if (!inode->i_nlink) {		reiserfs_warning(inode->i_sb, "%s: deleting nonexistent file "				 "(%s:%lu), %d", __FUNCTION__,				 reiserfs_bdevname(inode->i_sb), inode->i_ino,				 inode->i_nlink);		inode->i_nlink = 1;	}	drop_nlink(inode);	/*	 * we schedule before doing the add_save_link call, save the link	 * count so we don't race	 */	savelink = inode->i_nlink;	retval =	    reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL,				   0);	if (retval < 0) {		inc_nlink(inode);		goto end_unlink;	}	inode->i_ctime = CURRENT_TIME_SEC;	reiserfs_update_sd(&th, inode);	dir->i_size -= (de.de_entrylen + DEH_SIZE);	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;	reiserfs_update_sd(&th, dir);	if (!savelink)		/* prevent file from getting lost */		add_save_link(&th, inode, 0 /* not truncate */ );	retval = journal_end(&th, dir->i_sb, jbegin_count);	reiserfs_check_path(&path);	reiserfs_write_unlock(dir->i_sb);	return retval;      end_unlink:	pathrelse(&path);	err = journal_end(&th, dir->i_sb, jbegin_count);	reiserfs_check_path(&path);	if (err)		retval = err;      out_unlink:	reiserfs_write_unlock(dir->i_sb);	return retval;}static int reiserfs_symlink(struct inode *parent_dir,			    struct dentry *dentry, const char *symname){	int retval;	struct inode *inode;	char *name;	int item_len;	struct reiserfs_transaction_handle th;	int mode = S_IFLNK | S_IRWXUGO;	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */	int jbegin_count =	    JOURNAL_PER_BALANCE_CNT * 3 +	    2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) +		 REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb));	if (!(inode = new_inode(parent_dir->i_sb))) {

⌨️ 快捷键说明

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