Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7296b49 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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()
parents 1e467e68 792352cb
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@ 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>.
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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+0 −2
Original line number Diff line number Diff line
@@ -152,8 +152,6 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	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)
+73 −22
Original line number Diff line number Diff line
@@ -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,25 +1094,31 @@ 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 (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 (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,
+16 −10
Original line number Diff line number Diff line
@@ -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)) {
	if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) {
		ret = udf_CS0toUTF8(outstr, instr);
		if (ret < 0)
			goto out_bh;

		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);
		udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
	}

	if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128))
		if (udf_CS0toUTF8(outstr, instr))
	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:
Loading