Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF fixes and cleanups from Jan Kara: "The contains some small fixes and improvements in error handling for UDF. Bundled is also one ext3 coding style fix and a fix in quota documentation" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: fix udf_load_pvoldesc() udf: remove double err declaration in udf_file_write_iter() UDF: support NFSv2 export fs: ext3: super: fixed a space coding style issue quota: Update documentation udf: Return error from udf_find_entry() udf: Make udf_get_filename() return error instead of 0 length file name udf: bug on exotic flag in udf_get_filename() udf: improve error management in udf_CS0toNLS() udf: improve error management in udf_CS0toUTF8() udf: unicode: update function name in comments udf: remove unnecessary test in udf_build_ustr_exact() udf: Return -ENOMEM when allocation fails in udf_get_filename()
This commit is contained in:
		
						commit
						a7296b49fb
					
				| @ -32,7 +32,10 @@ The interface uses generic netlink framework (see | ||||
| http://lwn.net/Articles/208755/ and http://people.suug.ch/~tgr/libnl/ for more | ||||
| details about this layer). The name of the quota generic netlink interface | ||||
| is "VFS_DQUOT". Definitions of constants below are in <linux/quota.h>. | ||||
|   Currently, the interface supports only one message type QUOTA_NL_C_WARNING. | ||||
| Since the quota netlink protocol is not namespace aware, quota netlink messages | ||||
| are sent only in initial network namespace. | ||||
| 
 | ||||
| Currently, the interface supports only one message type QUOTA_NL_C_WARNING. | ||||
| This command is used to send a notification about any of the above mentioned | ||||
| events. Each message has six attributes. These are (type of the argument is | ||||
| in parentheses): | ||||
|  | ||||
| @ -1908,7 +1908,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | ||||
| 	sbi->s_mount_state = le16_to_cpu(es->s_state); | ||||
| 	sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb)); | ||||
| 	sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb)); | ||||
| 	for (i=0; i < 4; i++) | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | ||||
| 	sbi->s_def_hash_version = es->s_def_hash_version; | ||||
| 	i = le32_to_cpu(es->s_flags); | ||||
|  | ||||
| @ -168,7 +168,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | ||||
| 		} | ||||
| 
 | ||||
| 		flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); | ||||
| 		if (!flen) | ||||
| 		if (flen < 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		tloc = lelb_to_cpu(cfi.icb.extLocation); | ||||
|  | ||||
| @ -152,8 +152,6 @@ out: | ||||
| 	mutex_unlock(&inode->i_mutex); | ||||
| 
 | ||||
| 	if (retval > 0) { | ||||
| 		ssize_t err; | ||||
| 
 | ||||
| 		mark_inode_dirty(inode); | ||||
| 		err = generic_write_sync(file, iocb->ki_pos - retval, retval); | ||||
| 		if (err < 0) | ||||
|  | ||||
| @ -138,6 +138,25 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * udf_find_entry - find entry in given directory. | ||||
|  * | ||||
|  * @dir:	directory inode to search in | ||||
|  * @child:	qstr of the name | ||||
|  * @fibh:	buffer head / inode with file identifier descriptor we found | ||||
|  * @cfi:	found file identifier descriptor with given name | ||||
|  * | ||||
|  * This function searches in the directory @dir for a file name @child. When | ||||
|  * found, @fibh points to the buffer head(s) (bh is NULL for in ICB | ||||
|  * directories) containing the file identifier descriptor (FID). In that case | ||||
|  * the function returns pointer to the FID in the buffer or inode - but note | ||||
|  * that FID may be split among two buffers (blocks) so accessing it via that | ||||
|  * pointer isn't easily possible. This pointer can be used only as an iterator | ||||
|  * for other directory manipulation functions. For inspection of the FID @cfi | ||||
|  * can be used - the found FID is copied there. | ||||
|  * | ||||
|  * Returns pointer to FID, NULL when nothing found, or error code. | ||||
|  */ | ||||
| static struct fileIdentDesc *udf_find_entry(struct inode *dir, | ||||
| 					    const struct qstr *child, | ||||
| 					    struct udf_fileident_bh *fibh, | ||||
| @ -167,8 +186,11 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | ||||
| 	fibh->soffset = fibh->eoffset = f_pos & (sb->s_blocksize - 1); | ||||
| 	if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||||
| 		if (inode_bmap(dir, f_pos >> sb->s_blocksize_bits, &epos, | ||||
| 		    &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) | ||||
| 		    &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { | ||||
| 			fi = ERR_PTR(-EIO); | ||||
| 			goto out_err; | ||||
| 		} | ||||
| 
 | ||||
| 		block = udf_get_lb_pblock(sb, &eloc, offset); | ||||
| 		if ((++offset << sb->s_blocksize_bits) < elen) { | ||||
| 			if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | ||||
| @ -179,19 +201,25 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | ||||
| 			offset = 0; | ||||
| 
 | ||||
| 		fibh->sbh = fibh->ebh = udf_tread(sb, block); | ||||
| 		if (!fibh->sbh) | ||||
| 		if (!fibh->sbh) { | ||||
| 			fi = ERR_PTR(-EIO); | ||||
| 			goto out_err; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||||
| 	if (!fname) | ||||
| 	if (!fname) { | ||||
| 		fi = ERR_PTR(-ENOMEM); | ||||
| 		goto out_err; | ||||
| 	} | ||||
| 
 | ||||
| 	while (f_pos < size) { | ||||
| 		fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, | ||||
| 					&elen, &offset); | ||||
| 		if (!fi) | ||||
| 		if (!fi) { | ||||
| 			fi = ERR_PTR(-EIO); | ||||
| 			goto out_err; | ||||
| 		} | ||||
| 
 | ||||
| 		liu = le16_to_cpu(cfi->lengthOfImpUse); | ||||
| 		lfi = cfi->lengthFileIdent; | ||||
| @ -234,12 +262,17 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | ||||
| 			continue; | ||||
| 
 | ||||
| 		flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); | ||||
| 		if (flen && udf_match(flen, fname, child->len, child->name)) | ||||
| 		if (flen < 0) { | ||||
| 			fi = ERR_PTR(flen); | ||||
| 			goto out_err; | ||||
| 		} | ||||
| 
 | ||||
| 		if (udf_match(flen, fname, child->len, child->name)) | ||||
| 			goto out_ok; | ||||
| 	} | ||||
| 
 | ||||
| out_err: | ||||
| 	fi = NULL; | ||||
| out_err: | ||||
| 	if (fibh->sbh != fibh->ebh) | ||||
| 		brelse(fibh->ebh); | ||||
| 	brelse(fibh->sbh); | ||||
| @ -256,6 +289,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | ||||
| 	struct inode *inode = NULL; | ||||
| 	struct fileIdentDesc cfi; | ||||
| 	struct udf_fileident_bh fibh; | ||||
| 	struct fileIdentDesc *fi; | ||||
| 
 | ||||
| 	if (dentry->d_name.len > UDF_NAME_LEN - 2) | ||||
| 		return ERR_PTR(-ENAMETOOLONG); | ||||
| @ -275,7 +309,11 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | ||||
| 	} else | ||||
| #endif /* UDF_RECOVERY */ | ||||
| 
 | ||||
| 	if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) { | ||||
| 	fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | ||||
| 	if (IS_ERR(fi)) | ||||
| 		return ERR_CAST(fi); | ||||
| 
 | ||||
| 	if (fi) { | ||||
| 		struct kernel_lb_addr loc; | ||||
| 
 | ||||
| 		if (fibh.sbh != fibh.ebh) | ||||
| @ -774,8 +812,11 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | ||||
| 
 | ||||
| 	retval = -ENOENT; | ||||
| 	fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | ||||
| 	if (!fi) | ||||
| 	if (IS_ERR_OR_NULL(fi)) { | ||||
| 		if (fi) | ||||
| 			retval = PTR_ERR(fi); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	retval = -EIO; | ||||
| 	tloc = lelb_to_cpu(cfi.icb.extLocation); | ||||
| @ -817,8 +858,12 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | ||||
| 
 | ||||
| 	retval = -ENOENT; | ||||
| 	fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | ||||
| 	if (!fi) | ||||
| 
 | ||||
| 	if (IS_ERR_OR_NULL(fi)) { | ||||
| 		if (fi) | ||||
| 			retval = PTR_ERR(fi); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	retval = -EIO; | ||||
| 	tloc = lelb_to_cpu(cfi.icb.extLocation); | ||||
| @ -1049,24 +1094,30 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | ||||
| 	struct udf_inode_info *old_iinfo = UDF_I(old_inode); | ||||
| 
 | ||||
| 	ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | ||||
| 	if (ofi) { | ||||
| 		if (ofibh.sbh != ofibh.ebh) | ||||
| 			brelse(ofibh.ebh); | ||||
| 		brelse(ofibh.sbh); | ||||
| 	if (IS_ERR(ofi)) { | ||||
| 		retval = PTR_ERR(ofi); | ||||
| 		goto end_rename; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ofibh.sbh != ofibh.ebh) | ||||
| 		brelse(ofibh.ebh); | ||||
| 
 | ||||
| 	brelse(ofibh.sbh); | ||||
| 	tloc = lelb_to_cpu(ocfi.icb.extLocation); | ||||
| 	if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) | ||||
| 	    != old_inode->i_ino) | ||||
| 		goto end_rename; | ||||
| 
 | ||||
| 	nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi); | ||||
| 	if (nfi) { | ||||
| 		if (!new_inode) { | ||||
| 			if (nfibh.sbh != nfibh.ebh) | ||||
| 				brelse(nfibh.ebh); | ||||
| 			brelse(nfibh.sbh); | ||||
| 			nfi = NULL; | ||||
| 		} | ||||
| 	if (IS_ERR(nfi)) { | ||||
| 		retval = PTR_ERR(nfi); | ||||
| 		goto end_rename; | ||||
| 	} | ||||
| 	if (nfi && !new_inode) { | ||||
| 		if (nfibh.sbh != nfibh.ebh) | ||||
| 			brelse(nfibh.ebh); | ||||
| 		brelse(nfibh.sbh); | ||||
| 		nfi = NULL; | ||||
| 	} | ||||
| 	if (S_ISDIR(old_inode->i_mode)) { | ||||
| 		int offset = udf_ext0_offset(old_inode); | ||||
| @ -1221,7 +1272,7 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, | ||||
| static struct dentry *udf_fh_to_dentry(struct super_block *sb, | ||||
| 				       struct fid *fid, int fh_len, int fh_type) | ||||
| { | ||||
| 	if ((fh_len != 3 && fh_len != 5) || | ||||
| 	if (fh_len < 3 || | ||||
| 	    (fh_type != FILEID_UDF_WITH_PARENT && | ||||
| 	     fh_type != FILEID_UDF_WITHOUT_PARENT)) | ||||
| 		return NULL; | ||||
| @ -1233,7 +1284,7 @@ static struct dentry *udf_fh_to_dentry(struct super_block *sb, | ||||
| static struct dentry *udf_fh_to_parent(struct super_block *sb, | ||||
| 				       struct fid *fid, int fh_len, int fh_type) | ||||
| { | ||||
| 	if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT) | ||||
| 	if (fh_len < 5 || fh_type != FILEID_UDF_WITH_PARENT) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	return udf_nfs_get_inode(sb, fid->udf.parent_block, | ||||
|  | ||||
| @ -927,17 +927,23 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | ||||
| #endif | ||||
| 	} | ||||
| 
 | ||||
| 	if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) | ||||
| 		if (udf_CS0toUTF8(outstr, instr)) { | ||||
| 			strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, | ||||
| 				outstr->u_len > 31 ? 31 : outstr->u_len); | ||||
| 			udf_debug("volIdent[] = '%s'\n", | ||||
| 				  UDF_SB(sb)->s_volume_ident); | ||||
| 		} | ||||
| 	if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) { | ||||
| 		ret = udf_CS0toUTF8(outstr, instr); | ||||
| 		if (ret < 0) | ||||
| 			goto out_bh; | ||||
| 
 | ||||
| 	if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) | ||||
| 		if (udf_CS0toUTF8(outstr, instr)) | ||||
| 			udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); | ||||
| 		strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, | ||||
| 			outstr->u_len > 31 ? 31 : outstr->u_len); | ||||
| 		udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) { | ||||
| 		ret = udf_CS0toUTF8(outstr, instr); | ||||
| 		if (ret < 0) | ||||
| 			goto out_bh; | ||||
| 
 | ||||
| 		udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); | ||||
| 	} | ||||
| 
 | ||||
| 	ret = 0; | ||||
| out_bh: | ||||
|  | ||||
| @ -82,6 +82,9 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from, | ||||
| 			comp_len = udf_get_filename(sb, pc->componentIdent, | ||||
| 						    pc->lengthComponentIdent, | ||||
| 						    p, tolen); | ||||
| 			if (comp_len < 0) | ||||
| 				return comp_len; | ||||
| 
 | ||||
| 			p += comp_len; | ||||
| 			tolen -= comp_len; | ||||
| 			if (tolen == 0) | ||||
|  | ||||
| @ -68,21 +68,16 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) | ||||
| /*
 | ||||
|  * udf_build_ustr_exact | ||||
|  */ | ||||
| static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | ||||
| static void udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | ||||
| { | ||||
| 	if ((!dest) || (!ptr) || (!exactsize)) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	memset(dest, 0, sizeof(struct ustr)); | ||||
| 	dest->u_cmpID = ptr[0]; | ||||
| 	dest->u_len = exactsize - 1; | ||||
| 	memcpy(dest->u_name, ptr + 1, exactsize - 1); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * udf_ocu_to_utf8 | ||||
|  * udf_CS0toUTF8 | ||||
|  * | ||||
|  * PURPOSE | ||||
|  *	Convert OSTA Compressed Unicode to the UTF-8 equivalent. | ||||
| @ -94,7 +89,7 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | ||||
|  * 				both of type "struct ustr *" | ||||
|  * | ||||
|  * POST-CONDITIONS | ||||
|  *	<return>		Zero on success. | ||||
|  *	<return>		>= 0 on success. | ||||
|  * | ||||
|  * HISTORY | ||||
|  *	November 12, 1997 - Andrew E. Mileski | ||||
| @ -117,7 +112,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) | ||||
| 		memset(utf_o, 0, sizeof(struct ustr)); | ||||
| 		pr_err("unknown compression code (%d) stri=%s\n", | ||||
| 		       cmp_id, ocu_i->u_name); | ||||
| 		return 0; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ocu = ocu_i->u_name; | ||||
| @ -154,7 +149,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) | ||||
| 
 | ||||
| /*
 | ||||
|  * | ||||
|  * udf_utf8_to_ocu | ||||
|  * udf_UTF8toCS0 | ||||
|  * | ||||
|  * PURPOSE | ||||
|  *	Convert UTF-8 to the OSTA Compressed Unicode equivalent. | ||||
| @ -270,7 +265,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, | ||||
| 		memset(utf_o, 0, sizeof(struct ustr)); | ||||
| 		pr_err("unknown compression code (%d) stri=%s\n", | ||||
| 		       cmp_id, ocu_i->u_name); | ||||
| 		return 0; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ocu = ocu_i->u_name; | ||||
| @ -338,43 +333,51 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, | ||||
| 		     uint8_t *dname, int dlen) | ||||
| { | ||||
| 	struct ustr *filename, *unifilename; | ||||
| 	int len = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!slen) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	filename = kmalloc(sizeof(struct ustr), GFP_NOFS); | ||||
| 	if (!filename) | ||||
| 		return 0; | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); | ||||
| 	if (!unifilename) | ||||
| 	if (!unifilename) { | ||||
| 		ret = -ENOMEM; | ||||
| 		goto out1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (udf_build_ustr_exact(unifilename, sname, slen)) | ||||
| 		goto out2; | ||||
| 
 | ||||
| 	udf_build_ustr_exact(unifilename, sname, slen); | ||||
| 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { | ||||
| 		if (!udf_CS0toUTF8(filename, unifilename)) { | ||||
| 		ret = udf_CS0toUTF8(filename, unifilename); | ||||
| 		if (ret < 0) { | ||||
| 			udf_debug("Failed in udf_get_filename: sname = %s\n", | ||||
| 				  sname); | ||||
| 			goto out2; | ||||
| 		} | ||||
| 	} else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { | ||||
| 		if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, | ||||
| 				  unifilename)) { | ||||
| 		ret = udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, | ||||
| 				   unifilename); | ||||
| 		if (ret < 0) { | ||||
| 			udf_debug("Failed in udf_get_filename: sname = %s\n", | ||||
| 				  sname); | ||||
| 			goto out2; | ||||
| 		} | ||||
| 	} else | ||||
| 		goto out2; | ||||
| 		BUG(); | ||||
| 
 | ||||
| 	len = udf_translate_to_linux(dname, dlen, | ||||
| 	ret = udf_translate_to_linux(dname, dlen, | ||||
| 				     filename->u_name, filename->u_len, | ||||
| 				     unifilename->u_name, unifilename->u_len); | ||||
| 	/* Zero length filename isn't valid... */ | ||||
| 	if (ret == 0) | ||||
| 		ret = -EINVAL; | ||||
| out2: | ||||
| 	kfree(unifilename); | ||||
| out1: | ||||
| 	kfree(filename); | ||||
| 	return len; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int udf_put_filename(struct super_block *sb, const uint8_t *sname, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user