summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-03-25 12:38:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2019-09-05 14:34:26 -0400
commit5a2be1288b514d74acdb3f0131d4d8fa3d689f06 (patch)
treea8cbd9201be52dd050f5104a3b1df4134b70e1f6
parent6d56e4184368e4fe611df0cd5aee78431f5eda3e (diff)
vfs: Convert squashfs to use the new mount API
Convert the squashfs filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.txt for more information. Signed-off-by: David Howells <dhowells@redhat.com> cc: Phillip Lougher <phillip@squashfs.org.uk> cc: squashfs-devel@lists.sourceforge.net Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/squashfs/super.c100
1 files changed, 55 insertions, 45 deletions
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index effa638d6d85..f908c6eb1b39 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -17,6 +17,7 @@
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 18
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/fs_context.h>
20#include <linux/vfs.h> 21#include <linux/vfs.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
@@ -36,26 +37,27 @@
36static struct file_system_type squashfs_fs_type; 37static struct file_system_type squashfs_fs_type;
37static const struct super_operations squashfs_super_ops; 38static const struct super_operations squashfs_super_ops;
38 39
39static const struct squashfs_decompressor *supported_squashfs_filesystem(short 40static const struct squashfs_decompressor *supported_squashfs_filesystem(
40 major, short minor, short id) 41 struct fs_context *fc,
42 short major, short minor, short id)
41{ 43{
42 const struct squashfs_decompressor *decompressor; 44 const struct squashfs_decompressor *decompressor;
43 45
44 if (major < SQUASHFS_MAJOR) { 46 if (major < SQUASHFS_MAJOR) {
45 ERROR("Major/Minor mismatch, older Squashfs %d.%d " 47 errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d "
46 "filesystems are unsupported\n", major, minor); 48 "filesystems are unsupported", major, minor);
47 return NULL; 49 return NULL;
48 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { 50 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
49 ERROR("Major/Minor mismatch, trying to mount newer " 51 errorf(fc, "Major/Minor mismatch, trying to mount newer "
50 "%d.%d filesystem\n", major, minor); 52 "%d.%d filesystem", major, minor);
51 ERROR("Please update your kernel\n"); 53 errorf(fc, "Please update your kernel");
52 return NULL; 54 return NULL;
53 } 55 }
54 56
55 decompressor = squashfs_lookup_decompressor(id); 57 decompressor = squashfs_lookup_decompressor(id);
56 if (!decompressor->supported) { 58 if (!decompressor->supported) {
57 ERROR("Filesystem uses \"%s\" compression. This is not " 59 errorf(fc, "Filesystem uses \"%s\" compression. This is not supported",
58 "supported\n", decompressor->name); 60 decompressor->name);
59 return NULL; 61 return NULL;
60 } 62 }
61 63
@@ -63,7 +65,7 @@ static const struct squashfs_decompressor *supported_squashfs_filesystem(short
63} 65}
64 66
65 67
66static int squashfs_fill_super(struct super_block *sb, void *data, int silent) 68static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
67{ 69{
68 struct squashfs_sb_info *msblk; 70 struct squashfs_sb_info *msblk;
69 struct squashfs_super_block *sblk = NULL; 71 struct squashfs_super_block *sblk = NULL;
@@ -98,7 +100,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
98 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk)); 100 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
99 101
100 if (IS_ERR(sblk)) { 102 if (IS_ERR(sblk)) {
101 ERROR("unable to read squashfs_super_block\n"); 103 errorf(fc, "unable to read squashfs_super_block");
102 err = PTR_ERR(sblk); 104 err = PTR_ERR(sblk);
103 sblk = NULL; 105 sblk = NULL;
104 goto failed_mount; 106 goto failed_mount;
@@ -109,14 +111,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
109 /* Check it is a SQUASHFS superblock */ 111 /* Check it is a SQUASHFS superblock */
110 sb->s_magic = le32_to_cpu(sblk->s_magic); 112 sb->s_magic = le32_to_cpu(sblk->s_magic);
111 if (sb->s_magic != SQUASHFS_MAGIC) { 113 if (sb->s_magic != SQUASHFS_MAGIC) {
112 if (!silent) 114 if (!(fc->sb_flags & SB_SILENT))
113 ERROR("Can't find a SQUASHFS superblock on %pg\n", 115 errorf(fc, "Can't find a SQUASHFS superblock on %pg",
114 sb->s_bdev); 116 sb->s_bdev);
115 goto failed_mount; 117 goto failed_mount;
116 } 118 }
117 119
118 /* Check the MAJOR & MINOR versions and lookup compression type */ 120 /* Check the MAJOR & MINOR versions and lookup compression type */
119 msblk->decompressor = supported_squashfs_filesystem( 121 msblk->decompressor = supported_squashfs_filesystem(
122 fc,
120 le16_to_cpu(sblk->s_major), 123 le16_to_cpu(sblk->s_major),
121 le16_to_cpu(sblk->s_minor), 124 le16_to_cpu(sblk->s_minor),
122 le16_to_cpu(sblk->compression)); 125 le16_to_cpu(sblk->compression));
@@ -133,15 +136,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
133 /* Check block size for sanity */ 136 /* Check block size for sanity */
134 msblk->block_size = le32_to_cpu(sblk->block_size); 137 msblk->block_size = le32_to_cpu(sblk->block_size);
135 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE) 138 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
136 goto failed_mount; 139 goto insanity;
137 140
138 /* 141 /*
139 * Check the system page size is not larger than the filesystem 142 * Check the system page size is not larger than the filesystem
140 * block size (by default 128K). This is currently not supported. 143 * block size (by default 128K). This is currently not supported.
141 */ 144 */
142 if (PAGE_SIZE > msblk->block_size) { 145 if (PAGE_SIZE > msblk->block_size) {
143 ERROR("Page size > filesystem block size (%d). This is " 146 errorf(fc, "Page size > filesystem block size (%d). This is "
144 "currently not supported!\n", msblk->block_size); 147 "currently not supported!", msblk->block_size);
145 goto failed_mount; 148 goto failed_mount;
146 } 149 }
147 150
@@ -152,12 +155,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
152 155
153 /* Check that block_size and block_log match */ 156 /* Check that block_size and block_log match */
154 if (msblk->block_size != (1 << msblk->block_log)) 157 if (msblk->block_size != (1 << msblk->block_log))
155 goto failed_mount; 158 goto insanity;
156 159
157 /* Check the root inode for sanity */ 160 /* Check the root inode for sanity */
158 root_inode = le64_to_cpu(sblk->root_inode); 161 root_inode = le64_to_cpu(sblk->root_inode);
159 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE) 162 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
160 goto failed_mount; 163 goto insanity;
161 164
162 msblk->inode_table = le64_to_cpu(sblk->inode_table_start); 165 msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
163 msblk->directory_table = le64_to_cpu(sblk->directory_table_start); 166 msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
@@ -197,7 +200,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
197 msblk->read_page = squashfs_cache_init("data", 200 msblk->read_page = squashfs_cache_init("data",
198 squashfs_max_decompressors(), msblk->block_size); 201 squashfs_max_decompressors(), msblk->block_size);
199 if (msblk->read_page == NULL) { 202 if (msblk->read_page == NULL) {
200 ERROR("Failed to allocate read_page block\n"); 203 errorf(fc, "Failed to allocate read_page block");
201 goto failed_mount; 204 goto failed_mount;
202 } 205 }
203 206
@@ -205,7 +208,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
205 if (IS_ERR(msblk->stream)) { 208 if (IS_ERR(msblk->stream)) {
206 err = PTR_ERR(msblk->stream); 209 err = PTR_ERR(msblk->stream);
207 msblk->stream = NULL; 210 msblk->stream = NULL;
208 goto failed_mount; 211 goto insanity;
209 } 212 }
210 213
211 /* Handle xattrs */ 214 /* Handle xattrs */
@@ -220,7 +223,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
220 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, 223 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
221 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); 224 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
222 if (IS_ERR(msblk->xattr_id_table)) { 225 if (IS_ERR(msblk->xattr_id_table)) {
223 ERROR("unable to read xattr id index table\n"); 226 errorf(fc, "unable to read xattr id index table");
224 err = PTR_ERR(msblk->xattr_id_table); 227 err = PTR_ERR(msblk->xattr_id_table);
225 msblk->xattr_id_table = NULL; 228 msblk->xattr_id_table = NULL;
226 if (err != -ENOTSUPP) 229 if (err != -ENOTSUPP)
@@ -234,7 +237,7 @@ allocate_id_index_table:
234 le64_to_cpu(sblk->id_table_start), next_table, 237 le64_to_cpu(sblk->id_table_start), next_table,
235 le16_to_cpu(sblk->no_ids)); 238 le16_to_cpu(sblk->no_ids));
236 if (IS_ERR(msblk->id_table)) { 239 if (IS_ERR(msblk->id_table)) {
237 ERROR("unable to read id index table\n"); 240 errorf(fc, "unable to read id index table");
238 err = PTR_ERR(msblk->id_table); 241 err = PTR_ERR(msblk->id_table);
239 msblk->id_table = NULL; 242 msblk->id_table = NULL;
240 goto failed_mount; 243 goto failed_mount;
@@ -250,7 +253,7 @@ allocate_id_index_table:
250 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, 253 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
251 lookup_table_start, next_table, msblk->inodes); 254 lookup_table_start, next_table, msblk->inodes);
252 if (IS_ERR(msblk->inode_lookup_table)) { 255 if (IS_ERR(msblk->inode_lookup_table)) {
253 ERROR("unable to read inode lookup table\n"); 256 errorf(fc, "unable to read inode lookup table");
254 err = PTR_ERR(msblk->inode_lookup_table); 257 err = PTR_ERR(msblk->inode_lookup_table);
255 msblk->inode_lookup_table = NULL; 258 msblk->inode_lookup_table = NULL;
256 goto failed_mount; 259 goto failed_mount;
@@ -275,7 +278,7 @@ handle_fragments:
275 msblk->fragment_index = squashfs_read_fragment_index_table(sb, 278 msblk->fragment_index = squashfs_read_fragment_index_table(sb,
276 le64_to_cpu(sblk->fragment_table_start), next_table, fragments); 279 le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
277 if (IS_ERR(msblk->fragment_index)) { 280 if (IS_ERR(msblk->fragment_index)) {
278 ERROR("unable to read fragment index table\n"); 281 errorf(fc, "unable to read fragment index table");
279 err = PTR_ERR(msblk->fragment_index); 282 err = PTR_ERR(msblk->fragment_index);
280 msblk->fragment_index = NULL; 283 msblk->fragment_index = NULL;
281 goto failed_mount; 284 goto failed_mount;
@@ -286,13 +289,13 @@ check_directory_table:
286 /* Sanity check directory_table */ 289 /* Sanity check directory_table */
287 if (msblk->directory_table > next_table) { 290 if (msblk->directory_table > next_table) {
288 err = -EINVAL; 291 err = -EINVAL;
289 goto failed_mount; 292 goto insanity;
290 } 293 }
291 294
292 /* Sanity check inode_table */ 295 /* Sanity check inode_table */
293 if (msblk->inode_table >= msblk->directory_table) { 296 if (msblk->inode_table >= msblk->directory_table) {
294 err = -EINVAL; 297 err = -EINVAL;
295 goto failed_mount; 298 goto insanity;
296 } 299 }
297 300
298 /* allocate root */ 301 /* allocate root */
@@ -321,6 +324,8 @@ check_directory_table:
321 kfree(sblk); 324 kfree(sblk);
322 return 0; 325 return 0;
323 326
327insanity:
328 errorf(fc, "squashfs image failed sanity check");
324failed_mount: 329failed_mount:
325 squashfs_cache_delete(msblk->block_cache); 330 squashfs_cache_delete(msblk->block_cache);
326 squashfs_cache_delete(msblk->fragment_cache); 331 squashfs_cache_delete(msblk->fragment_cache);
@@ -336,6 +341,28 @@ failed_mount:
336 return err; 341 return err;
337} 342}
338 343
344static int squashfs_get_tree(struct fs_context *fc)
345{
346 return get_tree_bdev(fc, squashfs_fill_super);
347}
348
349static int squashfs_reconfigure(struct fs_context *fc)
350{
351 sync_filesystem(fc->root->d_sb);
352 fc->sb_flags |= SB_RDONLY;
353 return 0;
354}
355
356static const struct fs_context_operations squashfs_context_ops = {
357 .get_tree = squashfs_get_tree,
358 .reconfigure = squashfs_reconfigure,
359};
360
361static int squashfs_init_fs_context(struct fs_context *fc)
362{
363 fc->ops = &squashfs_context_ops;
364 return 0;
365}
339 366
340static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) 367static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
341{ 368{
@@ -358,14 +385,6 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
358} 385}
359 386
360 387
361static int squashfs_remount(struct super_block *sb, int *flags, char *data)
362{
363 sync_filesystem(sb);
364 *flags |= SB_RDONLY;
365 return 0;
366}
367
368
369static void squashfs_put_super(struct super_block *sb) 388static void squashfs_put_super(struct super_block *sb)
370{ 389{
371 if (sb->s_fs_info) { 390 if (sb->s_fs_info) {
@@ -384,14 +403,6 @@ static void squashfs_put_super(struct super_block *sb)
384 } 403 }
385} 404}
386 405
387
388static struct dentry *squashfs_mount(struct file_system_type *fs_type,
389 int flags, const char *dev_name, void *data)
390{
391 return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
392}
393
394
395static struct kmem_cache *squashfs_inode_cachep; 406static struct kmem_cache *squashfs_inode_cachep;
396 407
397 408
@@ -468,7 +479,7 @@ static void squashfs_free_inode(struct inode *inode)
468static struct file_system_type squashfs_fs_type = { 479static struct file_system_type squashfs_fs_type = {
469 .owner = THIS_MODULE, 480 .owner = THIS_MODULE,
470 .name = "squashfs", 481 .name = "squashfs",
471 .mount = squashfs_mount, 482 .init_fs_context = squashfs_init_fs_context,
472 .kill_sb = kill_block_super, 483 .kill_sb = kill_block_super,
473 .fs_flags = FS_REQUIRES_DEV 484 .fs_flags = FS_REQUIRES_DEV
474}; 485};
@@ -479,7 +490,6 @@ static const struct super_operations squashfs_super_ops = {
479 .free_inode = squashfs_free_inode, 490 .free_inode = squashfs_free_inode,
480 .statfs = squashfs_statfs, 491 .statfs = squashfs_statfs,
481 .put_super = squashfs_put_super, 492 .put_super = squashfs_put_super,
482 .remount_fs = squashfs_remount
483}; 493};
484 494
485module_init(init_squashfs_fs); 495module_init(init_squashfs_fs);