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

Commit 67f66cc6 authored by Phillip Lougher's avatar Phillip Lougher
Browse files

squashfs: add new extended inode types



Add new extended inode types that store the xattr_id field.
Also add the necessary code changes to make xattrs visibile.

Signed-off-by: default avatarPhillip Lougher <phillip@lougher.demon.co.uk>
parent f41d207c
Loading
Loading
Loading
Loading
+84 −7
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/xattr.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -111,6 +112,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
	int err, type, offset = SQUASHFS_INODE_OFFSET(ino);
	union squashfs_inode squashfs_ino;
	struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base;
	int xattr_id = SQUASHFS_INVALID_XATTR;

	TRACE("Entered squashfs_read_inode\n");

@@ -199,8 +201,10 @@ int squashfs_read_inode(struct inode *inode, long long ino)
			frag_offset = 0;
		}

		xattr_id = le32_to_cpu(sqsh_ino->xattr);
		inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
		inode->i_size = le64_to_cpu(sqsh_ino->file_size);
		inode->i_op = &squashfs_inode_ops;
		inode->i_fop = &generic_ro_fops;
		inode->i_mode |= S_IFREG;
		inode->i_blocks = ((inode->i_size -
@@ -251,6 +255,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
		if (err < 0)
			goto failed_read;

		xattr_id = le32_to_cpu(sqsh_ino->xattr);
		inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
		inode->i_size = le32_to_cpu(sqsh_ino->file_size);
		inode->i_op = &squashfs_dir_inode_ops;
@@ -280,21 +285,33 @@ int squashfs_read_inode(struct inode *inode, long long ino)

		inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
		inode->i_size = le32_to_cpu(sqsh_ino->symlink_size);
		inode->i_op = &page_symlink_inode_operations;
		inode->i_op = &squashfs_symlink_inode_ops;
		inode->i_data.a_ops = &squashfs_symlink_aops;
		inode->i_mode |= S_IFLNK;
		squashfs_i(inode)->start = block;
		squashfs_i(inode)->offset = offset;

		if (type == SQUASHFS_LSYMLINK_TYPE) {
			__le32 xattr;

			err = squashfs_read_metadata(sb, NULL, &block,
						&offset, inode->i_size);
			if (err < 0)
				goto failed_read;
			err = squashfs_read_metadata(sb, &xattr, &block,
						&offset, sizeof(xattr));
			if (err < 0)
				goto failed_read;
			xattr_id = le32_to_cpu(xattr);
		}

		TRACE("Symbolic link inode %x:%x, start_block %llx, offset "
				"%x\n", SQUASHFS_INODE_BLK(ino), offset,
				block, offset);
		break;
	}
	case SQUASHFS_BLKDEV_TYPE:
	case SQUASHFS_CHRDEV_TYPE:
	case SQUASHFS_LBLKDEV_TYPE:
	case SQUASHFS_LCHRDEV_TYPE: {
	case SQUASHFS_CHRDEV_TYPE: {
		struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev;
		unsigned int rdev;

@@ -315,10 +332,32 @@ int squashfs_read_inode(struct inode *inode, long long ino)
				SQUASHFS_INODE_BLK(ino), offset, rdev);
		break;
	}
	case SQUASHFS_LBLKDEV_TYPE:
	case SQUASHFS_LCHRDEV_TYPE: {
		struct squashfs_ldev_inode *sqsh_ino = &squashfs_ino.ldev;
		unsigned int rdev;

		err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
				sizeof(*sqsh_ino));
		if (err < 0)
			goto failed_read;

		if (type == SQUASHFS_LCHRDEV_TYPE)
			inode->i_mode |= S_IFCHR;
		else
			inode->i_mode |= S_IFBLK;
		xattr_id = le32_to_cpu(sqsh_ino->xattr);
		inode->i_op = &squashfs_inode_ops;
		inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
		rdev = le32_to_cpu(sqsh_ino->rdev);
		init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));

		TRACE("Device inode %x:%x, rdev %x\n",
				SQUASHFS_INODE_BLK(ino), offset, rdev);
		break;
	}
	case SQUASHFS_FIFO_TYPE:
	case SQUASHFS_SOCKET_TYPE:
	case SQUASHFS_LFIFO_TYPE:
	case SQUASHFS_LSOCKET_TYPE: {
	case SQUASHFS_SOCKET_TYPE: {
		struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc;

		err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
@@ -334,14 +373,52 @@ int squashfs_read_inode(struct inode *inode, long long ino)
		init_special_inode(inode, inode->i_mode, 0);
		break;
	}
	case SQUASHFS_LFIFO_TYPE:
	case SQUASHFS_LSOCKET_TYPE: {
		struct squashfs_lipc_inode *sqsh_ino = &squashfs_ino.lipc;

		err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
				sizeof(*sqsh_ino));
		if (err < 0)
			goto failed_read;

		if (type == SQUASHFS_LFIFO_TYPE)
			inode->i_mode |= S_IFIFO;
		else
			inode->i_mode |= S_IFSOCK;
		xattr_id = le32_to_cpu(sqsh_ino->xattr);
		inode->i_op = &squashfs_inode_ops;
		inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
		init_special_inode(inode, inode->i_mode, 0);
		break;
	}
	default:
		ERROR("Unknown inode type %d in squashfs_iget!\n", type);
		return -EINVAL;
	}

	if (xattr_id != SQUASHFS_INVALID_XATTR && msblk->xattr_id_table) {
		err = squashfs_xattr_lookup(sb, xattr_id,
					&squashfs_i(inode)->xattr_count,
					&squashfs_i(inode)->xattr_size,
					&squashfs_i(inode)->xattr);
		if (err < 0)
			goto failed_read;
		inode->i_blocks += ((squashfs_i(inode)->xattr_size - 1) >> 9)
				+ 1;
	} else
		squashfs_i(inode)->xattr_count = 0;

	return 0;

failed_read:
	ERROR("Unable to read inode 0x%llx\n", ino);
	return err;
}


const struct inode_operations squashfs_inode_ops = {
	.getxattr = generic_getxattr,
	.listxattr = squashfs_listxattr
};
+4 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dcache.h>
#include <linux/xattr.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -237,5 +238,7 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry,


const struct inode_operations squashfs_dir_inode_ops = {
	.lookup = squashfs_lookup
	.lookup = squashfs_lookup,
	.getxattr = generic_getxattr,
	.listxattr = squashfs_listxattr
};
+11 −1
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ extern struct inode *squashfs_iget(struct super_block *, long long,
				unsigned int);
extern int squashfs_read_inode(struct inode *, long long);

/* xattr.c */
extern ssize_t squashfs_listxattr(struct dentry *, char *, size_t);

/* xattr_id.c */
extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
				int *, long long *);
@@ -80,7 +83,7 @@ extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
				u64 *, int *);

/*
 * Inodes, files and decompressor operations
 * Inodes, files,  decompressor and xattr operations
 */

/* dir.c */
@@ -92,11 +95,18 @@ extern const struct export_operations squashfs_export_ops;
/* file.c */
extern const struct address_space_operations squashfs_aops;

/* inode.c */
extern const struct inode_operations squashfs_inode_ops;

/* namei.c */
extern const struct inode_operations squashfs_dir_inode_ops;

/* symlink.c */
extern const struct address_space_operations squashfs_symlink_aops;
extern const struct inode_operations squashfs_symlink_inode_ops;

/* xattr.c */
extern struct xattr_handler *squashfs_xattr_handlers[];

/* zlib_wrapper.c */
extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
+25 −0
Original line number Diff line number Diff line
@@ -287,6 +287,17 @@ struct squashfs_ipc_inode {
	__le32			nlink;
};

struct squashfs_lipc_inode {
	__le16			inode_type;
	__le16			mode;
	__le16			uid;
	__le16			guid;
	__le32			mtime;
	__le32	 		inode_number;
	__le32			nlink;
	__le32			xattr;
};

struct squashfs_dev_inode {
	__le16			inode_type;
	__le16			mode;
@@ -298,6 +309,18 @@ struct squashfs_dev_inode {
	__le32			rdev;
};

struct squashfs_ldev_inode {
	__le16			inode_type;
	__le16			mode;
	__le16			uid;
	__le16			guid;
	__le32			mtime;
	__le32	 		inode_number;
	__le32			nlink;
	__le32			rdev;
	__le32			xattr;
};

struct squashfs_symlink_inode {
	__le16			inode_type;
	__le16			mode;
@@ -375,12 +398,14 @@ struct squashfs_ldir_inode {
union squashfs_inode {
	struct squashfs_base_inode		base;
	struct squashfs_dev_inode		dev;
	struct squashfs_ldev_inode		ldev;
	struct squashfs_symlink_inode		symlink;
	struct squashfs_reg_inode		reg;
	struct squashfs_lreg_inode		lreg;
	struct squashfs_dir_inode		dir;
	struct squashfs_ldir_inode		ldir;
	struct squashfs_ipc_inode		ipc;
	struct squashfs_lipc_inode		lipc;
};

struct squashfs_dir_entry {
+1 −7
Original line number Diff line number Diff line
@@ -140,13 +140,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
	if (msblk->decompressor == NULL)
		goto failed_mount;

	/*
	 * Check if there's xattrs in the filesystem.  These are not
	 * supported in this version, so warn that they will be ignored.
	 */
	if (le64_to_cpu(sblk->xattr_id_table_start) != SQUASHFS_INVALID_BLK)
		ERROR("Xattrs in filesystem, these will be ignored\n");

	/* Check the filesystem does not extend beyond the end of the
	   block device */
	msblk->bytes_used = le64_to_cpu(sblk->bytes_used);
@@ -268,6 +261,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
	sb->s_export_op = &squashfs_export_ops;

allocate_xattr_table:
	sb->s_xattr = squashfs_xattr_handlers;
	xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
	if (xattr_id_table_start == SQUASHFS_INVALID_BLK)
		goto allocate_root;
Loading