diff options
Diffstat (limited to 'fs/udf/namei.c')
| -rw-r--r-- | fs/udf/namei.c | 156 | 
1 files changed, 54 insertions, 102 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9737cba1357d..c12e260fd6c4 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -270,9 +270,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,  						NULL, 0),  		};  		inode = udf_iget(dir->i_sb, lb); -		if (!inode) { -			return ERR_PTR(-EACCES); -		} +		if (IS_ERR(inode)) +			return inode;  	} else  #endif /* UDF_RECOVERY */ @@ -285,9 +284,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,  		loc = lelb_to_cpu(cfi.icb.extLocation);  		inode = udf_iget(dir->i_sb, &loc); -		if (!inode) { -			return ERR_PTR(-EACCES); -		} +		if (IS_ERR(inode)) +			return ERR_CAST(inode);  	}  	return d_splice_alias(inode, dentry); @@ -550,32 +548,18 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,  	return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);  } -static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, -		      bool excl) +static int udf_add_nondir(struct dentry *dentry, struct inode *inode)  { +	struct udf_inode_info *iinfo = UDF_I(inode); +	struct inode *dir = dentry->d_parent->d_inode;  	struct udf_fileident_bh fibh; -	struct inode *inode;  	struct fileIdentDesc cfi, *fi;  	int err; -	struct udf_inode_info *iinfo; - -	inode = udf_new_inode(dir, mode, &err); -	if (!inode) { -		return err; -	} - -	iinfo = UDF_I(inode); -	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) -		inode->i_data.a_ops = &udf_adinicb_aops; -	else -		inode->i_data.a_ops = &udf_aops; -	inode->i_op = &udf_file_inode_operations; -	inode->i_fop = &udf_file_operations; -	mark_inode_dirty(inode);  	fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); -	if (!fi) { +	if (unlikely(!fi)) {  		inode_dec_link_count(inode); +		unlock_new_inode(inode);  		iput(inode);  		return err;  	} @@ -589,23 +573,21 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,  	if (fibh.sbh != fibh.ebh)  		brelse(fibh.ebh);  	brelse(fibh.sbh); +	unlock_new_inode(inode);  	d_instantiate(dentry, inode);  	return 0;  } -static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, +		      bool excl)  { -	struct inode *inode; -	struct udf_inode_info *iinfo; -	int err; +	struct inode *inode = udf_new_inode(dir, mode); -	inode = udf_new_inode(dir, mode, &err); -	if (!inode) -		return err; +	if (IS_ERR(inode)) +		return PTR_ERR(inode); -	iinfo = UDF_I(inode); -	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) +	if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)  		inode->i_data.a_ops = &udf_adinicb_aops;  	else  		inode->i_data.a_ops = &udf_aops; @@ -613,7 +595,25 @@ static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)  	inode->i_fop = &udf_file_operations;  	mark_inode_dirty(inode); +	return udf_add_nondir(dentry, inode); +} + +static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +{ +	struct inode *inode = udf_new_inode(dir, mode); + +	if (IS_ERR(inode)) +		return PTR_ERR(inode); + +	if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) +		inode->i_data.a_ops = &udf_adinicb_aops; +	else +		inode->i_data.a_ops = &udf_aops; +	inode->i_op = &udf_file_inode_operations; +	inode->i_fop = &udf_file_operations; +	mark_inode_dirty(inode);  	d_tmpfile(dentry, inode); +	unlock_new_inode(inode);  	return 0;  } @@ -621,44 +621,16 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,  		     dev_t rdev)  {  	struct inode *inode; -	struct udf_fileident_bh fibh; -	struct fileIdentDesc cfi, *fi; -	int err; -	struct udf_inode_info *iinfo;  	if (!old_valid_dev(rdev))  		return -EINVAL; -	err = -EIO; -	inode = udf_new_inode(dir, mode, &err); -	if (!inode) -		goto out; +	inode = udf_new_inode(dir, mode); +	if (IS_ERR(inode)) +		return PTR_ERR(inode); -	iinfo = UDF_I(inode);  	init_special_inode(inode, mode, rdev); -	fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); -	if (!fi) { -		inode_dec_link_count(inode); -		iput(inode); -		return err; -	} -	cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); -	cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); -	*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = -		cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); -	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); -	if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) -		mark_inode_dirty(dir); -	mark_inode_dirty(inode); - -	if (fibh.sbh != fibh.ebh) -		brelse(fibh.ebh); -	brelse(fibh.sbh); -	d_instantiate(dentry, inode); -	err = 0; - -out: -	return err; +	return udf_add_nondir(dentry, inode);  }  static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) @@ -670,10 +642,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)  	struct udf_inode_info *dinfo = UDF_I(dir);  	struct udf_inode_info *iinfo; -	err = -EIO; -	inode = udf_new_inode(dir, S_IFDIR | mode, &err); -	if (!inode) -		goto out; +	inode = udf_new_inode(dir, S_IFDIR | mode); +	if (IS_ERR(inode)) +		return PTR_ERR(inode);  	iinfo = UDF_I(inode);  	inode->i_op = &udf_dir_inode_operations; @@ -681,6 +652,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)  	fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);  	if (!fi) {  		inode_dec_link_count(inode); +		unlock_new_inode(inode);  		iput(inode);  		goto out;  	} @@ -699,6 +671,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)  	if (!fi) {  		clear_nlink(inode);  		mark_inode_dirty(inode); +		unlock_new_inode(inode);  		iput(inode);  		goto out;  	} @@ -710,6 +683,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)  	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);  	inc_nlink(dir);  	mark_inode_dirty(dir); +	unlock_new_inode(inode);  	d_instantiate(dentry, inode);  	if (fibh.sbh != fibh.ebh)  		brelse(fibh.ebh); @@ -876,14 +850,11 @@ out:  static int udf_symlink(struct inode *dir, struct dentry *dentry,  		       const char *symname)  { -	struct inode *inode; +	struct inode *inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO);  	struct pathComponent *pc;  	const char *compstart; -	struct udf_fileident_bh fibh;  	struct extent_position epos = {};  	int eoffset, elen = 0; -	struct fileIdentDesc *fi; -	struct fileIdentDesc cfi;  	uint8_t *ea;  	int err;  	int block; @@ -892,9 +863,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,  	struct udf_inode_info *iinfo;  	struct super_block *sb = dir->i_sb; -	inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); -	if (!inode) -		goto out; +	if (IS_ERR(inode)) +		return PTR_ERR(inode);  	iinfo = UDF_I(inode);  	down_write(&iinfo->i_data_sem); @@ -1012,24 +982,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,  	mark_inode_dirty(inode);  	up_write(&iinfo->i_data_sem); -	fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); -	if (!fi) -		goto out_no_entry; -	cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); -	cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); -	if (UDF_SB(inode->i_sb)->s_lvid_bh) { -		*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = -			cpu_to_le32(lvid_get_unique_id(sb)); -	} -	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); -	if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) -		mark_inode_dirty(dir); -	if (fibh.sbh != fibh.ebh) -		brelse(fibh.ebh); -	brelse(fibh.sbh); -	d_instantiate(dentry, inode); -	err = 0; - +	err = udf_add_nondir(dentry, inode);  out:  	kfree(name);  	return err; @@ -1037,6 +990,7 @@ out:  out_no_entry:  	up_write(&iinfo->i_data_sem);  	inode_dec_link_count(inode); +	unlock_new_inode(inode);  	iput(inode);  	goto out;  } @@ -1221,7 +1175,7 @@ static struct dentry *udf_get_parent(struct dentry *child)  	struct udf_fileident_bh fibh;  	if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) -		goto out_unlock; +		return ERR_PTR(-EACCES);  	if (fibh.sbh != fibh.ebh)  		brelse(fibh.ebh); @@ -1229,12 +1183,10 @@ static struct dentry *udf_get_parent(struct dentry *child)  	tloc = lelb_to_cpu(cfi.icb.extLocation);  	inode = udf_iget(child->d_inode->i_sb, &tloc); -	if (!inode) -		goto out_unlock; +	if (IS_ERR(inode)) +		return ERR_CAST(inode);  	return d_obtain_alias(inode); -out_unlock: -	return ERR_PTR(-EACCES);  } @@ -1251,8 +1203,8 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,  	loc.partitionReferenceNum = partref;  	inode = udf_iget(sb, &loc); -	if (inode == NULL) -		return ERR_PTR(-ENOMEM); +	if (IS_ERR(inode)) +		return ERR_CAST(inode);  	if (generation && inode->i_generation != generation) {  		iput(inode);  |