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

Commit 92075f9f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull filesystem fixes from Jan Kara:
 "udf, isofs, and ext3 bug fixes"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext3: Count internal journal as bsddf overhead in ext3_statfs
  isofs: Fix unbounded recursion when processing relocated directories
  udf: avoid unneeded up_write when fail to add entry in ->symlink
parents 3951ad2e e6d8fb34
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -2828,7 +2828,8 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
		 */
		overhead += ngroups * (2 + sbi->s_itb_per_group);

		/* Add the journal blocks as well */
		/* Add the internal journal blocks as well */
		if (sbi->s_journal && !sbi->journal_bdev)
			overhead += sbi->s_journal->j_maxlen;

		sbi->s_overhead_last = overhead;
+8 −7
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static void isofs_put_super(struct super_block *sb)
	return;
}

static int isofs_read_inode(struct inode *);
static int isofs_read_inode(struct inode *, int relocated);
static int isofs_statfs (struct dentry *, struct kstatfs *);

static struct kmem_cache *isofs_inode_cachep;
@@ -1259,7 +1259,7 @@ static int isofs_read_level3_size(struct inode *inode)
	goto out;
}

static int isofs_read_inode(struct inode *inode)
static int isofs_read_inode(struct inode *inode, int relocated)
{
	struct super_block *sb = inode->i_sb;
	struct isofs_sb_info *sbi = ISOFS_SB(sb);
@@ -1404,7 +1404,7 @@ static int isofs_read_inode(struct inode *inode)
	 */

	if (!high_sierra) {
		parse_rock_ridge_inode(de, inode);
		parse_rock_ridge_inode(de, inode, relocated);
		/* if we want uid/gid set, override the rock ridge setting */
		if (sbi->s_uid_set)
			inode->i_uid = sbi->s_uid;
@@ -1483,9 +1483,10 @@ static int isofs_iget5_set(struct inode *ino, void *data)
 * offset that point to the underlying meta-data for the inode.  The
 * code below is otherwise similar to the iget() code in
 * include/linux/fs.h */
struct inode *isofs_iget(struct super_block *sb,
struct inode *__isofs_iget(struct super_block *sb,
			   unsigned long block,
			 unsigned long offset)
			   unsigned long offset,
			   int relocated)
{
	unsigned long hashval;
	struct inode *inode;
@@ -1507,7 +1508,7 @@ struct inode *isofs_iget(struct super_block *sb,
		return ERR_PTR(-ENOMEM);

	if (inode->i_state & I_NEW) {
		ret = isofs_read_inode(inode);
		ret = isofs_read_inode(inode, relocated);
		if (ret < 0) {
			iget_failed(inode);
			inode = ERR_PTR(ret);
+19 −4
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ extern int iso_date(char *, int);

struct inode;		/* To make gcc happy */

extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *);
extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated);
extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *);
extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *);

@@ -118,9 +118,24 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int
extern struct buffer_head *isofs_bread(struct inode *, sector_t);
extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);

extern struct inode *isofs_iget(struct super_block *sb,
struct inode *__isofs_iget(struct super_block *sb,
			   unsigned long block,
                                unsigned long offset);
			   unsigned long offset,
			   int relocated);

static inline struct inode *isofs_iget(struct super_block *sb,
				       unsigned long block,
				       unsigned long offset)
{
	return __isofs_iget(sb, block, offset, 0);
}

static inline struct inode *isofs_iget_reloc(struct super_block *sb,
					     unsigned long block,
					     unsigned long offset)
{
	return __isofs_iget(sb, block, offset, 1);
}

/* Because the inode number is no longer relevant to finding the
 * underlying meta-data for an inode, we are free to choose a more
+28 −11
Original line number Diff line number Diff line
@@ -288,12 +288,16 @@ int get_rock_ridge_filename(struct iso_directory_record *de,
	goto out;
}

#define RR_REGARD_XA 1
#define RR_RELOC_DE 2

static int
parse_rock_ridge_inode_internal(struct iso_directory_record *de,
				struct inode *inode, int regard_xa)
				struct inode *inode, int flags)
{
	int symlink_len = 0;
	int cnt, sig;
	unsigned int reloc_block;
	struct inode *reloc;
	struct rock_ridge *rr;
	int rootflag;
@@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,

	init_rock_state(&rs, inode);
	setup_rock_ridge(de, inode, &rs);
	if (regard_xa) {
	if (flags & RR_REGARD_XA) {
		rs.chr += 14;
		rs.len -= 14;
		if (rs.len < 0)
@@ -485,12 +489,22 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,
					"relocated directory\n");
			goto out;
		case SIG('C', 'L'):
			ISOFS_I(inode)->i_first_extent =
			    isonum_733(rr->u.CL.location);
			reloc =
			    isofs_iget(inode->i_sb,
				       ISOFS_I(inode)->i_first_extent,
				       0);
			if (flags & RR_RELOC_DE) {
				printk(KERN_ERR
				       "ISOFS: Recursive directory relocation "
				       "is not supported\n");
				goto eio;
			}
			reloc_block = isonum_733(rr->u.CL.location);
			if (reloc_block == ISOFS_I(inode)->i_iget5_block &&
			    ISOFS_I(inode)->i_iget5_offset == 0) {
				printk(KERN_ERR
				       "ISOFS: Directory relocation points to "
				       "itself\n");
				goto eio;
			}
			ISOFS_I(inode)->i_first_extent = reloc_block;
			reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0);
			if (IS_ERR(reloc)) {
				ret = PTR_ERR(reloc);
				goto out;
@@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
	return rpnt;
}

int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode,
			   int relocated)
{
	int result = parse_rock_ridge_inode_internal(de, inode, 0);
	int flags = relocated ? RR_RELOC_DE : 0;
	int result = parse_rock_ridge_inode_internal(de, inode, flags);

	/*
	 * if rockridge flag was reset and we didn't look for attributes
@@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
	 */
	if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
	    && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
		result = parse_rock_ridge_inode_internal(de, inode, 14);
		result = parse_rock_ridge_inode_internal(de, inode,
							 flags | RR_REGARD_XA);
	}
	return result;
}
+2 −1
Original line number Diff line number Diff line
@@ -1014,7 +1014,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,

	fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
	if (!fi)
		goto out_no_entry;
		goto out_fail;
	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) {
@@ -1036,6 +1036,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,

out_no_entry:
	up_write(&iinfo->i_data_sem);
out_fail:
	inode_dec_link_count(inode);
	iput(inode);
	goto out;