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

Commit 4b5397dc authored by Phillip Lougher's avatar Phillip Lougher
Browse files

squashfs: add xattr id support



This patch adds support for mapping xattr ids (stored in inodes)
into the on-disk location of the xattrs themselves.

Signed-off-by: default avatarPhillip Lougher <phillip@lougher.demon.co.uk>
parent b57f95a3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5,3 +5,5 @@
obj-$(CONFIG_SQUASHFS) += squashfs.o
squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
squashfs-y += xattr_id.o
+6 −0
Original line number Diff line number Diff line
@@ -73,6 +73,12 @@ extern struct inode *squashfs_iget(struct super_block *, long long,
				unsigned int);
extern int squashfs_read_inode(struct inode *, long long);

/* xattr_id.c */
extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
				int *, long long *);
extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
				u64 *, int *);

/*
 * Inodes, files and decompressor operations
 */
+31 −1
Original line number Diff line number Diff line
@@ -174,6 +174,24 @@

#define SQUASHFS_ID_BLOCK_BYTES(A)	(SQUASHFS_ID_BLOCKS(A) *\
					sizeof(u64))
/* xattr id lookup table defines */
#define SQUASHFS_XATTR_BYTES(A)		((A) * sizeof(struct squashfs_xattr_id))

#define SQUASHFS_XATTR_BLOCK(A)		(SQUASHFS_XATTR_BYTES(A) / \
					SQUASHFS_METADATA_SIZE)

#define SQUASHFS_XATTR_BLOCK_OFFSET(A)	(SQUASHFS_XATTR_BYTES(A) % \
					SQUASHFS_METADATA_SIZE)

#define SQUASHFS_XATTR_BLOCKS(A)	((SQUASHFS_XATTR_BYTES(A) + \
					SQUASHFS_METADATA_SIZE - 1) / \
					SQUASHFS_METADATA_SIZE)

#define SQUASHFS_XATTR_BLOCK_BYTES(A)	(SQUASHFS_XATTR_BLOCKS(A) *\
					sizeof(u64))
#define SQUASHFS_XATTR_BLK(A)		((unsigned int) ((A) >> 16))

#define SQUASHFS_XATTR_OFFSET(A)	((unsigned int) ((A) & 0xffff))

/* cached data constants for filesystem */
#define SQUASHFS_CACHED_BLKS		8
@@ -228,7 +246,7 @@ struct squashfs_super_block {
	__le64			root_inode;
	__le64			bytes_used;
	__le64			id_table_start;
	__le64			xattr_table_start;
	__le64			xattr_id_table_start;
	__le64			inode_table_start;
	__le64			directory_table_start;
	__le64			fragment_table_start;
@@ -377,4 +395,16 @@ struct squashfs_fragment_entry {
	unsigned int		unused;
};

struct squashfs_xattr_id {
	__le64			xattr;
	__le32			count;
	__le32			size;
};

struct squashfs_xattr_id_table {
	__le64			xattr_table_start;
	__le32			xattr_ids;
	__le32			unused;
};

#endif
+3 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ struct squashfs_sb_info {
	int					next_meta_index;
	__le64					*id_table;
	__le64					*fragment_index;
	__le64					*xattr_id_table;
	struct mutex				read_data_mutex;
	struct mutex				meta_index_mutex;
	struct meta_index			*meta_index;
@@ -68,9 +69,11 @@ struct squashfs_sb_info {
	__le64					*inode_lookup_table;
	u64					inode_table;
	u64					directory_table;
	u64					xattr_table;
	unsigned int				block_size;
	unsigned short				block_log;
	long long				bytes_used;
	unsigned int				inodes;
	int					xattr_ids;
};
#endif
+19 −3
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/magic.h>
#include <linux/xattr.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -82,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
	long long root_inode;
	unsigned short flags;
	unsigned int fragments;
	u64 lookup_table_start;
	u64 lookup_table_start, xattr_id_table_start;
	int err;

	TRACE("Entered squashfs_fill_superblock\n");
@@ -143,7 +144,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
	 * 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_table_start) != SQUASHFS_INVALID_BLK)
	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
@@ -253,7 +254,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
allocate_lookup_table:
	lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
	if (lookup_table_start == SQUASHFS_INVALID_BLK)
		goto allocate_root;
		goto allocate_xattr_table;

	/* Allocate and read inode lookup table */
	msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
@@ -266,6 +267,19 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)

	sb->s_export_op = &squashfs_export_ops;

allocate_xattr_table:
	xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
	if (xattr_id_table_start == SQUASHFS_INVALID_BLK)
		goto allocate_root;

	/* Allocate and read xattr id lookup table */
	msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
		xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
	if (IS_ERR(msblk->xattr_id_table)) {
		err = PTR_ERR(msblk->xattr_id_table);
		msblk->xattr_id_table = NULL;
		goto failed_mount;
	}
allocate_root:
	root = new_inode(sb);
	if (!root) {
@@ -301,6 +315,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
	kfree(msblk->inode_lookup_table);
	kfree(msblk->fragment_index);
	kfree(msblk->id_table);
	kfree(msblk->xattr_id_table);
	kfree(sb->s_fs_info);
	sb->s_fs_info = NULL;
	kfree(sblk);
@@ -355,6 +370,7 @@ static void squashfs_put_super(struct super_block *sb)
		kfree(sbi->fragment_index);
		kfree(sbi->meta_index);
		kfree(sbi->inode_lookup_table);
		kfree(sbi->xattr_id_table);
		kfree(sb->s_fs_info);
		sb->s_fs_info = NULL;
	}
Loading