hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/fs/squashfs/super.c
....@@ -1,22 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Squashfs - a compressed read only filesystem for Linux
34 *
45 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
56 * Phillip Lougher <phillip@squashfs.org.uk>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version 2,
10
- * or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
207 *
218 * super.c
229 */
....@@ -30,6 +17,7 @@
3017 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3118
3219 #include <linux/fs.h>
20
+#include <linux/fs_context.h>
3321 #include <linux/vfs.h>
3422 #include <linux/slab.h>
3523 #include <linux/mutex.h>
....@@ -49,26 +37,27 @@
4937 static struct file_system_type squashfs_fs_type;
5038 static const struct super_operations squashfs_super_ops;
5139
52
-static const struct squashfs_decompressor *supported_squashfs_filesystem(short
53
- major, short minor, short id)
40
+static const struct squashfs_decompressor *supported_squashfs_filesystem(
41
+ struct fs_context *fc,
42
+ short major, short minor, short id)
5443 {
5544 const struct squashfs_decompressor *decompressor;
5645
5746 if (major < SQUASHFS_MAJOR) {
58
- ERROR("Major/Minor mismatch, older Squashfs %d.%d "
59
- "filesystems are unsupported\n", major, minor);
47
+ errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d "
48
+ "filesystems are unsupported", major, minor);
6049 return NULL;
6150 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
62
- ERROR("Major/Minor mismatch, trying to mount newer "
63
- "%d.%d filesystem\n", major, minor);
64
- ERROR("Please update your kernel\n");
51
+ errorf(fc, "Major/Minor mismatch, trying to mount newer "
52
+ "%d.%d filesystem", major, minor);
53
+ errorf(fc, "Please update your kernel");
6554 return NULL;
6655 }
6756
6857 decompressor = squashfs_lookup_decompressor(id);
6958 if (!decompressor->supported) {
70
- ERROR("Filesystem uses \"%s\" compression. This is not "
71
- "supported\n", decompressor->name);
59
+ errorf(fc, "Filesystem uses \"%s\" compression. This is not supported",
60
+ decompressor->name);
7261 return NULL;
7362 }
7463
....@@ -76,7 +65,7 @@
7665 }
7766
7867
79
-static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
68
+static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
8069 {
8170 struct squashfs_sb_info *msblk;
8271 struct squashfs_super_block *sblk = NULL;
....@@ -111,7 +100,7 @@
111100 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
112101
113102 if (IS_ERR(sblk)) {
114
- ERROR("unable to read squashfs_super_block\n");
103
+ errorf(fc, "unable to read squashfs_super_block");
115104 err = PTR_ERR(sblk);
116105 sblk = NULL;
117106 goto failed_mount;
....@@ -122,14 +111,15 @@
122111 /* Check it is a SQUASHFS superblock */
123112 sb->s_magic = le32_to_cpu(sblk->s_magic);
124113 if (sb->s_magic != SQUASHFS_MAGIC) {
125
- if (!silent)
126
- ERROR("Can't find a SQUASHFS superblock on %pg\n",
127
- sb->s_bdev);
114
+ if (!(fc->sb_flags & SB_SILENT))
115
+ errorf(fc, "Can't find a SQUASHFS superblock on %pg",
116
+ sb->s_bdev);
128117 goto failed_mount;
129118 }
130119
131120 /* Check the MAJOR & MINOR versions and lookup compression type */
132121 msblk->decompressor = supported_squashfs_filesystem(
122
+ fc,
133123 le16_to_cpu(sblk->s_major),
134124 le16_to_cpu(sblk->s_minor),
135125 le16_to_cpu(sblk->compression));
....@@ -146,15 +136,15 @@
146136 /* Check block size for sanity */
147137 msblk->block_size = le32_to_cpu(sblk->block_size);
148138 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
149
- goto failed_mount;
139
+ goto insanity;
150140
151141 /*
152142 * Check the system page size is not larger than the filesystem
153143 * block size (by default 128K). This is currently not supported.
154144 */
155145 if (PAGE_SIZE > msblk->block_size) {
156
- ERROR("Page size > filesystem block size (%d). This is "
157
- "currently not supported!\n", msblk->block_size);
146
+ errorf(fc, "Page size > filesystem block size (%d). This is "
147
+ "currently not supported!", msblk->block_size);
158148 goto failed_mount;
159149 }
160150
....@@ -165,12 +155,12 @@
165155
166156 /* Check that block_size and block_log match */
167157 if (msblk->block_size != (1 << msblk->block_log))
168
- goto failed_mount;
158
+ goto insanity;
169159
170160 /* Check the root inode for sanity */
171161 root_inode = le64_to_cpu(sblk->root_inode);
172162 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
173
- goto failed_mount;
163
+ goto insanity;
174164
175165 msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
176166 msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
....@@ -197,6 +187,8 @@
197187 (u64) le64_to_cpu(sblk->id_table_start));
198188
199189 sb->s_maxbytes = MAX_LFS_FILESIZE;
190
+ sb->s_time_min = 0;
191
+ sb->s_time_max = U32_MAX;
200192 sb->s_flags |= SB_RDONLY;
201193 sb->s_op = &squashfs_super_ops;
202194
....@@ -211,7 +203,7 @@
211203 msblk->read_page = squashfs_cache_init("data",
212204 squashfs_max_decompressors(), msblk->block_size);
213205 if (msblk->read_page == NULL) {
214
- ERROR("Failed to allocate read_page block\n");
206
+ errorf(fc, "Failed to allocate read_page block");
215207 goto failed_mount;
216208 }
217209
....@@ -219,7 +211,7 @@
219211 if (IS_ERR(msblk->stream)) {
220212 err = PTR_ERR(msblk->stream);
221213 msblk->stream = NULL;
222
- goto failed_mount;
214
+ goto insanity;
223215 }
224216
225217 /* Handle xattrs */
....@@ -234,7 +226,7 @@
234226 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
235227 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
236228 if (IS_ERR(msblk->xattr_id_table)) {
237
- ERROR("unable to read xattr id index table\n");
229
+ errorf(fc, "unable to read xattr id index table");
238230 err = PTR_ERR(msblk->xattr_id_table);
239231 msblk->xattr_id_table = NULL;
240232 if (err != -ENOTSUPP)
....@@ -247,7 +239,7 @@
247239 msblk->id_table = squashfs_read_id_index_table(sb,
248240 le64_to_cpu(sblk->id_table_start), next_table, msblk->ids);
249241 if (IS_ERR(msblk->id_table)) {
250
- ERROR("unable to read id index table\n");
242
+ errorf(fc, "unable to read id index table");
251243 err = PTR_ERR(msblk->id_table);
252244 msblk->id_table = NULL;
253245 goto failed_mount;
....@@ -263,7 +255,7 @@
263255 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
264256 lookup_table_start, next_table, msblk->inodes);
265257 if (IS_ERR(msblk->inode_lookup_table)) {
266
- ERROR("unable to read inode lookup table\n");
258
+ errorf(fc, "unable to read inode lookup table");
267259 err = PTR_ERR(msblk->inode_lookup_table);
268260 msblk->inode_lookup_table = NULL;
269261 goto failed_mount;
....@@ -288,7 +280,7 @@
288280 msblk->fragment_index = squashfs_read_fragment_index_table(sb,
289281 le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
290282 if (IS_ERR(msblk->fragment_index)) {
291
- ERROR("unable to read fragment index table\n");
283
+ errorf(fc, "unable to read fragment index table");
292284 err = PTR_ERR(msblk->fragment_index);
293285 msblk->fragment_index = NULL;
294286 goto failed_mount;
....@@ -299,13 +291,13 @@
299291 /* Sanity check directory_table */
300292 if (msblk->directory_table > next_table) {
301293 err = -EINVAL;
302
- goto failed_mount;
294
+ goto insanity;
303295 }
304296
305297 /* Sanity check inode_table */
306298 if (msblk->inode_table >= msblk->directory_table) {
307299 err = -EINVAL;
308
- goto failed_mount;
300
+ goto insanity;
309301 }
310302
311303 /* allocate root */
....@@ -334,6 +326,8 @@
334326 kfree(sblk);
335327 return 0;
336328
329
+insanity:
330
+ errorf(fc, "squashfs image failed sanity check");
337331 failed_mount:
338332 squashfs_cache_delete(msblk->block_cache);
339333 squashfs_cache_delete(msblk->fragment_cache);
....@@ -349,6 +343,28 @@
349343 return err;
350344 }
351345
346
+static int squashfs_get_tree(struct fs_context *fc)
347
+{
348
+ return get_tree_bdev(fc, squashfs_fill_super);
349
+}
350
+
351
+static int squashfs_reconfigure(struct fs_context *fc)
352
+{
353
+ sync_filesystem(fc->root->d_sb);
354
+ fc->sb_flags |= SB_RDONLY;
355
+ return 0;
356
+}
357
+
358
+static const struct fs_context_operations squashfs_context_ops = {
359
+ .get_tree = squashfs_get_tree,
360
+ .reconfigure = squashfs_reconfigure,
361
+};
362
+
363
+static int squashfs_init_fs_context(struct fs_context *fc)
364
+{
365
+ fc->ops = &squashfs_context_ops;
366
+ return 0;
367
+}
352368
353369 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
354370 {
....@@ -364,17 +380,8 @@
364380 buf->f_files = msblk->inodes;
365381 buf->f_ffree = 0;
366382 buf->f_namelen = SQUASHFS_NAME_LEN;
367
- buf->f_fsid.val[0] = (u32)id;
368
- buf->f_fsid.val[1] = (u32)(id >> 32);
383
+ buf->f_fsid = u64_to_fsid(id);
369384
370
- return 0;
371
-}
372
-
373
-
374
-static int squashfs_remount(struct super_block *sb, int *flags, char *data)
375
-{
376
- sync_filesystem(sb);
377
- *flags |= SB_RDONLY;
378385 return 0;
379386 }
380387
....@@ -396,14 +403,6 @@
396403 sb->s_fs_info = NULL;
397404 }
398405 }
399
-
400
-
401
-static struct dentry *squashfs_mount(struct file_system_type *fs_type,
402
- int flags, const char *dev_name, void *data)
403
-{
404
- return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
405
-}
406
-
407406
408407 static struct kmem_cache *squashfs_inode_cachep;
409408
....@@ -473,22 +472,15 @@
473472 }
474473
475474
476
-static void squashfs_i_callback(struct rcu_head *head)
475
+static void squashfs_free_inode(struct inode *inode)
477476 {
478
- struct inode *inode = container_of(head, struct inode, i_rcu);
479477 kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
480478 }
481
-
482
-static void squashfs_destroy_inode(struct inode *inode)
483
-{
484
- call_rcu(&inode->i_rcu, squashfs_i_callback);
485
-}
486
-
487479
488480 static struct file_system_type squashfs_fs_type = {
489481 .owner = THIS_MODULE,
490482 .name = "squashfs",
491
- .mount = squashfs_mount,
483
+ .init_fs_context = squashfs_init_fs_context,
492484 .kill_sb = kill_block_super,
493485 .fs_flags = FS_REQUIRES_DEV
494486 };
....@@ -496,10 +488,9 @@
496488
497489 static const struct super_operations squashfs_super_ops = {
498490 .alloc_inode = squashfs_alloc_inode,
499
- .destroy_inode = squashfs_destroy_inode,
491
+ .free_inode = squashfs_free_inode,
500492 .statfs = squashfs_statfs,
501493 .put_super = squashfs_put_super,
502
- .remount_fs = squashfs_remount
503494 };
504495
505496 module_init(init_squashfs_fs);
....@@ -507,3 +498,4 @@
507498 MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem");
508499 MODULE_AUTHOR("Phillip Lougher <phillip@squashfs.org.uk>");
509500 MODULE_LICENSE("GPL");
501
+MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);