mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	btrfs_mkdir
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
		
							parent
							
								
									dcea79152c
								
							
						
					
					
						commit
						f7922033ef
					
				
					 1 changed files with 65 additions and 119 deletions
				
			
		
							
								
								
									
										184
									
								
								fs/btrfs/super.c
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								fs/btrfs/super.c
									
									
									
									
									
								
							|  | @ -18,124 +18,6 @@ static struct inode_operations btrfs_dir_inode_operations; | |||
| static struct super_operations btrfs_super_ops; | ||||
| static struct file_operations btrfs_dir_file_operations; | ||||
| 
 | ||||
| #if 0 | ||||
| /* some random number */ | ||||
| 
 | ||||
| static struct super_operations ramfs_ops; | ||||
| 
 | ||||
| static struct backing_dev_info ramfs_backing_dev_info = { | ||||
| 	.ra_pages	= 0,	/* No readahead */ | ||||
| 	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | | ||||
| 			  BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | | ||||
| 			  BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, | ||||
| }; | ||||
| 
 | ||||
| struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | ||||
| { | ||||
| 	struct inode * inode = new_inode(sb); | ||||
| 
 | ||||
| 	if (inode) { | ||||
| 		inode->i_mode = mode; | ||||
| 		inode->i_uid = current->fsuid; | ||||
| 		inode->i_gid = current->fsgid; | ||||
| 		inode->i_blocks = 0; | ||||
| 		inode->i_mapping->a_ops = &ramfs_aops; | ||||
| 		inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | ||||
| 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||||
| 		switch (mode & S_IFMT) { | ||||
| 		default: | ||||
| 			init_special_inode(inode, mode, dev); | ||||
| 			break; | ||||
| 		case S_IFREG: | ||||
| 			inode->i_op = &ramfs_file_inode_operations; | ||||
| 			inode->i_fop = &ramfs_file_operations; | ||||
| 			break; | ||||
| 		case S_IFDIR: | ||||
| 			inode->i_op = &ramfs_dir_inode_operations; | ||||
| 			inode->i_fop = &simple_dir_operations; | ||||
| 
 | ||||
| 			/* directory inodes start off with i_nlink == 2 (for "." entry) */ | ||||
| 			inc_nlink(inode); | ||||
| 			break; | ||||
| 		case S_IFLNK: | ||||
| 			inode->i_op = &page_symlink_inode_operations; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return inode; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * File creation. Allocate an inode, and we're done.. | ||||
|  */ | ||||
| /* SMP-safe */ | ||||
| static int | ||||
| ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | ||||
| { | ||||
| 	struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); | ||||
| 	int error = -ENOSPC; | ||||
| 
 | ||||
| 	if (inode) { | ||||
| 		if (dir->i_mode & S_ISGID) { | ||||
| 			inode->i_gid = dir->i_gid; | ||||
| 			if (S_ISDIR(mode)) | ||||
| 				inode->i_mode |= S_ISGID; | ||||
| 		} | ||||
| 		d_instantiate(dentry, inode); | ||||
| 		dget(dentry);	/* Extra count - pin the dentry in core */ | ||||
| 		error = 0; | ||||
| 		dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||||
| 	} | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | ||||
| { | ||||
| 	int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); | ||||
| 	if (!retval) | ||||
| 		inc_nlink(dir); | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) | ||||
| { | ||||
| 	return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); | ||||
| } | ||||
| 
 | ||||
| static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) | ||||
| { | ||||
| 	struct inode *inode; | ||||
| 	int error = -ENOSPC; | ||||
| 
 | ||||
| 	inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); | ||||
| 	if (inode) { | ||||
| 		int l = strlen(symname)+1; | ||||
| 		error = page_symlink(inode, symname, l); | ||||
| 		if (!error) { | ||||
| 			if (dir->i_mode & S_ISGID) | ||||
| 				inode->i_gid = dir->i_gid; | ||||
| 			d_instantiate(dentry, inode); | ||||
| 			dget(dentry); | ||||
| 			dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||||
| 		} else | ||||
| 			iput(inode); | ||||
| 	} | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| static struct inode_operations ramfs_dir_inode_operations = { | ||||
| 	.create		= ramfs_create, | ||||
| 	.lookup		= simple_lookup, | ||||
| 	.link		= simple_link, | ||||
| 	.unlink		= simple_unlink, | ||||
| 	.symlink	= ramfs_symlink, | ||||
| 	.mkdir		= ramfs_mkdir, | ||||
| 	.rmdir		= simple_rmdir, | ||||
| 	.mknod		= ramfs_mknod, | ||||
| 	.rename		= simple_rename, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| static void btrfs_read_locked_inode(struct inode *inode) | ||||
| { | ||||
| 	struct btrfs_path path; | ||||
|  | @ -533,9 +415,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 	inode->i_ino = objectid; | ||||
| 	inode->i_blocks = 0; | ||||
| 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | ||||
| 	/* FIXME do this on link */ | ||||
| 	if (mode & S_IFDIR) | ||||
| 		inode->i_size = 3; | ||||
| 	fill_inode_item(&inode_item, inode); | ||||
| 
 | ||||
| 
 | ||||
| 	key.objectid = objectid; | ||||
| 	key.flags = 0; | ||||
| 	key.offset = 0; | ||||
|  | @ -603,6 +487,67 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans, | ||||
| 				struct inode *inode, struct inode *dir) | ||||
| { | ||||
| 	struct btrfs_root *root = btrfs_sb(inode->i_sb); | ||||
| 	int ret; | ||||
| 	char buf[2]; | ||||
| 	buf[0] = '.'; | ||||
| 	buf[1] = '.'; | ||||
| 
 | ||||
| 	ret = btrfs_insert_dir_item(trans, root, buf, 1, inode->i_ino, | ||||
| 				    inode->i_ino, 1); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 	ret = btrfs_insert_dir_item(trans, root, buf, 2, inode->i_ino, | ||||
| 				    dir->i_ino, 1); | ||||
| error: | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||||
| { | ||||
| 	struct inode *inode; | ||||
| 	struct btrfs_trans_handle *trans; | ||||
| 	struct btrfs_root *root = btrfs_sb(dir->i_sb); | ||||
| 	int err = 0; | ||||
| 	int drop_on_err = 0; | ||||
| 
 | ||||
| 	mutex_lock(&root->fs_info->fs_mutex); | ||||
| 	trans = btrfs_start_transaction(root, 1); | ||||
| 	if (IS_ERR(trans)) { | ||||
| 		err = PTR_ERR(trans); | ||||
| 		goto out_unlock; | ||||
| 	} | ||||
| 	inode = btrfs_new_inode(trans, dir, S_IFDIR | mode); | ||||
| 	if (IS_ERR(inode)) { | ||||
| 		err = PTR_ERR(inode); | ||||
| 		goto out_fail; | ||||
| 	} | ||||
| 	drop_on_err = 1; | ||||
| 	inode->i_op = &btrfs_dir_inode_operations; | ||||
| 	inode->i_fop = &btrfs_dir_file_operations; | ||||
| 
 | ||||
| 	err = btrfs_make_empty_dir(trans, inode, dir); | ||||
| 	if (err) | ||||
| 		goto out_fail; | ||||
| 	err = btrfs_add_link(trans, dentry, inode); | ||||
| 	if (err) | ||||
| 		goto out_fail; | ||||
| 	d_instantiate(dentry, inode); | ||||
| 	mark_inode_dirty(inode); | ||||
| 	drop_on_err = 0; | ||||
| 
 | ||||
| out_fail: | ||||
| 	btrfs_end_transaction(trans, root); | ||||
| out_unlock: | ||||
| 	mutex_unlock(&root->fs_info->fs_mutex); | ||||
| 	if (drop_on_err) | ||||
| 		iput(inode); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int btrfs_sync_fs(struct super_block *sb, int wait) | ||||
| { | ||||
| 	struct btrfs_trans_handle *trans; | ||||
|  | @ -661,6 +606,7 @@ static struct inode_operations btrfs_dir_inode_operations = { | |||
| 	.lookup		= btrfs_lookup, | ||||
| 	.create		= btrfs_create, | ||||
| 	.unlink		= btrfs_unlink, | ||||
| 	.mkdir		= btrfs_mkdir, | ||||
| }; | ||||
| 
 | ||||
| static struct file_operations btrfs_dir_file_operations = { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Chris Mason
						Chris Mason