]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
kern/file: Implement filesystem reference counting
authorB Horn <b@horn.uk>
Sun, 12 May 2024 09:15:03 +0000 (10:15 +0100)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 23 Jan 2025 15:22:47 +0000 (16:22 +0100)
The grub_file_open() and grub_file_close() should be the only places
that allow a reference to a filesystem to stay open. So, add grub_dl_t
to grub_fs_t and set this in the GRUB_MOD_INIT() for each filesystem to
avoid issues when filesystems forget to do it themselves or do not track
their own references, e.g. squash4.

The fs_label(), fs_uuid(), fs_mtime() and fs_read() should all ref and
unref in the same function but it is essentially redundant in GRUB
single threaded model.

Signed-off-by: B Horn <b@horn.uk>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
31 files changed:
grub-core/fs/affs.c
grub-core/fs/bfs.c
grub-core/fs/btrfs.c
grub-core/fs/cbfs.c
grub-core/fs/cpio.c
grub-core/fs/cpio_be.c
grub-core/fs/erofs.c
grub-core/fs/ext2.c
grub-core/fs/f2fs.c
grub-core/fs/fat.c
grub-core/fs/hfs.c
grub-core/fs/hfsplus.c
grub-core/fs/iso9660.c
grub-core/fs/jfs.c
grub-core/fs/minix.c
grub-core/fs/newc.c
grub-core/fs/nilfs2.c
grub-core/fs/ntfs.c
grub-core/fs/odc.c
grub-core/fs/proc.c
grub-core/fs/reiserfs.c
grub-core/fs/romfs.c
grub-core/fs/sfs.c
grub-core/fs/squash4.c
grub-core/fs/tar.c
grub-core/fs/udf.c
grub-core/fs/ufs.c
grub-core/fs/xfs.c
grub-core/fs/zfs/zfs.c
grub-core/kern/file.c
include/grub/fs.h

index ed606b3f15a1c0fdef44432cf56ecb21473a3b15..9b0afb9541ef23b94665274775de88e6eaed3c42 100644 (file)
@@ -703,6 +703,7 @@ static struct grub_fs grub_affs_fs =
 
 GRUB_MOD_INIT(affs)
 {
+  grub_affs_fs.mod = mod;
   grub_fs_register (&grub_affs_fs);
   my_mod = mod;
 }
index 9bc478ce8f9120a9222497f586b2785197da4933..022f69fe215a515fb2e1d565f4f0083071eb0bf6 100644 (file)
@@ -1106,6 +1106,7 @@ GRUB_MOD_INIT (bfs)
 {
   COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE ==
                       sizeof (struct grub_bfs_extent));
+  grub_bfs_fs.mod = mod;
   grub_fs_register (&grub_bfs_fs);
 }
 
index ba0c583526d821a7eee1b8d7fccc2616ae8fbef2..aae81482b8b952f2b9531763ab043ff8c06603e0 100644 (file)
@@ -2413,6 +2413,7 @@ static struct grub_fs grub_btrfs_fs = {
 
 GRUB_MOD_INIT (btrfs)
 {
+  grub_btrfs_fs.mod = mod;
   grub_fs_register (&grub_btrfs_fs);
 }
 
index 8ab7106afbb6103e618322ebab86777e1ac6d66c..2332745fe8a53918f9adcc0d467aee6c77fcca2f 100644 (file)
@@ -390,6 +390,7 @@ GRUB_MOD_INIT (cbfs)
 #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
   init_cbfsdisk ();
 #endif
+  grub_cbfs_fs.mod = mod;
   grub_fs_register (&grub_cbfs_fs);
 }
 
index dab5f98988e8ac7d9d6d2a76ac4542db745b869c..1799f7ff5a539a3fbdbe82f5af13c3b216b44693 100644 (file)
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
 
 GRUB_MOD_INIT (cpio)
 {
+  grub_cpio_fs.mod = mod;
   grub_fs_register (&grub_cpio_fs);
 }
 
index 8465488921f2995b3a3d85c9ee218e7985b811ee..7bed1b848c71377a2a695d205b2836fb441a4b08 100644 (file)
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
 
 GRUB_MOD_INIT (cpio_be)
 {
+  grub_cpio_fs.mod = mod;
   grub_fs_register (&grub_cpio_fs);
 }
 
index f2a82e9884d704c75d605e7d991d01c21e807ba8..ae38b045e1ea91f700bf227b7cab313ae4382d90 100644 (file)
@@ -991,6 +991,7 @@ static struct grub_fs grub_erofs_fs = {
 
 GRUB_MOD_INIT (erofs)
 {
+  grub_erofs_fs.mod = mod;
   grub_fs_register (&grub_erofs_fs);
 }
 
index 3f9f6b208006853038289714dfa61726ed0a5b4d..c3058f7e71f15a25b8130f4ce34c7da27c07bb8c 100644 (file)
@@ -1131,6 +1131,7 @@ static struct grub_fs grub_ext2_fs =
 
 GRUB_MOD_INIT(ext2)
 {
+  grub_ext2_fs.mod = mod;
   grub_fs_register (&grub_ext2_fs);
   my_mod = mod;
 }
index db8a65f8d56b6edd948ff7c2183c73c4013c1f6d..f6d6beaa53f3e8ee37e3fae6090b8cd1caa0d96f 100644 (file)
@@ -1353,6 +1353,7 @@ static struct grub_fs grub_f2fs_fs = {
 
 GRUB_MOD_INIT (f2fs)
 {
+  grub_f2fs_fs.mod = mod;
   grub_fs_register (&grub_f2fs_fs);
   my_mod = mod;
 }
index c5efed72412444f90f28213f82c523ff1782a6ed..6e62b915dd1c797e3edbc5c2c388bb478999ebca 100644 (file)
@@ -1312,6 +1312,7 @@ GRUB_MOD_INIT(fat)
 #endif
 {
   COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
+  grub_fat_fs.mod = mod;
   grub_fs_register (&grub_fat_fs);
   my_mod = mod;
 }
index 920112b03e2f3fd2c50dac045e8c7db3659f2110..ce7581dd5f1c6c6bcc158d2e23ab0281c89143a2 100644 (file)
@@ -1434,6 +1434,7 @@ static struct grub_fs grub_hfs_fs =
 
 GRUB_MOD_INIT(hfs)
 {
+  grub_hfs_fs.mod = mod;
   if (!grub_is_lockdown ())
     grub_fs_register (&grub_hfs_fs);
   my_mod = mod;
index de71fd486bb298af6d2de0362dcea6ef75a18972..3f203abccdd5015e99a658dbec6b8e3b5a421559 100644 (file)
@@ -1176,6 +1176,7 @@ static struct grub_fs grub_hfsplus_fs =
 
 GRUB_MOD_INIT(hfsplus)
 {
+  grub_hfsplus_fs.mod = mod;
   grub_fs_register (&grub_hfsplus_fs);
   my_mod = mod;
 }
index 8e3c95c4f9b186ea1c52e9581065924519dad6a3..c73cb9ce05f7bf4653ab3858e09da0525fb5cc71 100644 (file)
@@ -1260,6 +1260,7 @@ static struct grub_fs grub_iso9660_fs =
 
 GRUB_MOD_INIT(iso9660)
 {
+  grub_iso9660_fs.mod = mod;
   grub_fs_register (&grub_iso9660_fs);
   my_mod = mod;
 }
index c06d174c9fb486cd0cf406dd8564adecdacec85a..a82800ac329261804b8a1a915409ae0fc4b291fe 100644 (file)
@@ -1004,6 +1004,7 @@ static struct grub_fs grub_jfs_fs =
 
 GRUB_MOD_INIT(jfs)
 {
+  grub_jfs_fs.mod = mod;
   grub_fs_register (&grub_jfs_fs);
   my_mod = mod;
 }
index 5354951d1052aee3063753d7f0b84079dae7f56a..b7679c3e257f60e4c6843d46035e81be8b2cea86 100644 (file)
@@ -734,6 +734,7 @@ GRUB_MOD_INIT(minix)
 #endif
 #endif
 {
+  grub_minix_fs.mod = mod;
   grub_fs_register (&grub_minix_fs);
   my_mod = mod;
 }
index 4fb8b2e3d21a937ff8bcccd6f08c7b7a7f0a9b6c..43b7f8b642816d911601df91804917a0a1bd50a1 100644 (file)
@@ -64,6 +64,7 @@ read_number (const char *str, grub_size_t size)
 
 GRUB_MOD_INIT (newc)
 {
+  grub_cpio_fs.mod = mod;
   grub_fs_register (&grub_cpio_fs);
 }
 
index fc7374ead4901493a267be5eb88664b90ddab2ab..4e1e7173866c280b30e695a7518e0e3e2da56ea0 100644 (file)
@@ -1231,6 +1231,7 @@ GRUB_MOD_INIT (nilfs2)
                                  grub_nilfs2_dat_entry));
   COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
                       == sizeof (struct grub_nilfs2_inode));
+  grub_nilfs2_fs.mod = mod;
   grub_fs_register (&grub_nilfs2_fs);
   my_mod = mod;
 }
index 64f4f22213ea486385272a515753b310f44708da..4e144cc3cd3f64d46f05344380921a79d39e838d 100644 (file)
@@ -1541,6 +1541,7 @@ static struct grub_fs grub_ntfs_fs =
 
 GRUB_MOD_INIT (ntfs)
 {
+  grub_ntfs_fs.mod = mod;
   grub_fs_register (&grub_ntfs_fs);
   my_mod = mod;
 }
index 790000622db620b0d289937a0646af49be10ca5b..8e4e8aeac87f0749a1746debe0246db9b81f3c0f 100644 (file)
@@ -52,6 +52,7 @@ read_number (const char *str, grub_size_t size)
 
 GRUB_MOD_INIT (odc)
 {
+  grub_cpio_fs.mod = mod;
   grub_fs_register (&grub_cpio_fs);
 }
 
index 5f516502d41969628c6a9514255b180464c461ff..bcde43349524a6f53641f006d1ddbfa64a0ab10b 100644 (file)
@@ -192,6 +192,7 @@ static struct grub_fs grub_procfs_fs =
 
 GRUB_MOD_INIT (procfs)
 {
+  grub_procfs_fs.mod = mod;
   grub_disk_dev_register (&grub_procfs_dev);
   grub_fs_register (&grub_procfs_fs);
 }
index 36b26ac98a02d5d9e518e1b14b6693d5b12752a8..c3850e0138ed0f016816278480679fe084ab6bd8 100644 (file)
@@ -1417,6 +1417,7 @@ static struct grub_fs grub_reiserfs_fs =
 
 GRUB_MOD_INIT(reiserfs)
 {
+  grub_reiserfs_fs.mod = mod;
   grub_fs_register (&grub_reiserfs_fs);
   my_mod = mod;
 }
index 1f7dcfca1d3a360feccb07fb99f0008478b4ebaa..56b0b2b2f3d02d2c22960208077637606f492512 100644 (file)
@@ -475,6 +475,7 @@ static struct grub_fs grub_romfs_fs =
 
 GRUB_MOD_INIT(romfs)
 {
+  grub_romfs_fs.mod = mod;
   grub_fs_register (&grub_romfs_fs);
 }
 
index 983e880088710755a49523748221a3c47c8274fc..f0d7cac435f71fe1e769028a1b2349f279ff50b7 100644 (file)
@@ -779,6 +779,7 @@ static struct grub_fs grub_sfs_fs =
 
 GRUB_MOD_INIT(sfs)
 {
+  grub_sfs_fs.mod = mod;
   grub_fs_register (&grub_sfs_fs);
   my_mod = mod;
 }
index a30e6ebe14a753c6c9c77e49defecc8615bb4dd4..6e9d63874c92bf6185428234f2be44f7b159ca67 100644 (file)
@@ -1044,6 +1044,7 @@ static struct grub_fs grub_squash_fs =
 
 GRUB_MOD_INIT(squash4)
 {
+  grub_squash_fs.mod = mod;
   grub_fs_register (&grub_squash_fs);
 }
 
index 386c090226f13f1601f25711715ea5bf6bbad4ce..fd2ec1f74a8d1af1384b3b80406c74bd16d6e08c 100644 (file)
@@ -354,6 +354,7 @@ static struct grub_fs grub_cpio_fs = {
 
 GRUB_MOD_INIT (tar)
 {
+  grub_cpio_fs.mod = mod;
   grub_fs_register (&grub_cpio_fs);
 }
 
index b836e61075ca8895454ab16f62c215cbef58cce9..8765c633c6f116ddc2b6600099b1a1e885bbc662 100644 (file)
@@ -1455,6 +1455,7 @@ static struct grub_fs grub_udf_fs = {
 
 GRUB_MOD_INIT (udf)
 {
+  grub_udf_fs.mod = mod;
   grub_fs_register (&grub_udf_fs);
   my_mod = mod;
 }
index 01235101b49b4a11b5a162ccc448326678957181..e82d9356d7df1bb1d4418f5d3fe4f2ab450e3ff8 100644 (file)
@@ -899,6 +899,7 @@ GRUB_MOD_INIT(ufs1)
 #endif
 #endif
 {
+  grub_ufs_fs.mod = mod;
   grub_fs_register (&grub_ufs_fs);
   my_mod = mod;
 }
index 8c0d60f7d974f96c5a87b39ac7a863080e3116ce..732c4aaf364e81b4c37b3ae6e6abbb02834112e5 100644 (file)
@@ -1304,6 +1304,7 @@ static struct grub_fs grub_xfs_fs =
 
 GRUB_MOD_INIT(xfs)
 {
+  grub_xfs_fs.mod = mod;
   grub_fs_register (&grub_xfs_fs);
   my_mod = mod;
 }
index 3fdf9bda89d170457eff43be5c2bff3c2e831b20..22ced40142f011dbd023f0b3c4dac59bfa30e6dd 100644 (file)
@@ -4464,6 +4464,7 @@ static struct grub_fs grub_zfs_fs = {
 GRUB_MOD_INIT (zfs)
 {
   COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
+  grub_zfs_fs.mod = mod;
   grub_fs_register (&grub_zfs_fs);
 #ifndef GRUB_UTIL
   my_mod = mod;
index e990507fca003c70b1c4df7797149270330a9dd4..6e7efe89abd67387625b1b51b30c812cf8f33d3a 100644 (file)
@@ -25,6 +25,7 @@
 #include <grub/fs.h>
 #include <grub/device.h>
 #include <grub/i18n.h>
+#include <grub/dl.h>
 
 void (*EXPORT_VAR (grub_grubnet_fini)) (void);
 
@@ -117,6 +118,9 @@ grub_file_open (const char *name, enum grub_file_type type)
   if (file->data == NULL)
     goto fail;
 
+  if (file->fs->mod)
+    grub_dl_ref (file->fs->mod);
+
   file->name = grub_strdup (name);
   grub_errno = GRUB_ERR_NONE;
 
@@ -197,6 +201,9 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
 grub_err_t
 grub_file_close (grub_file_t file)
 {
+  if (file->fs->mod)
+    grub_dl_unref (file->fs->mod);
+
   if (file->fs->fs_close)
     (file->fs->fs_close) (file);
 
index 026bc3bb8615c0a15676672a087c930e6b39e48f..df4c93b16f0451c749fd8c1a509eb013af233cbc 100644 (file)
@@ -23,6 +23,7 @@
 #include <grub/device.h>
 #include <grub/symbol.h>
 #include <grub/types.h>
+#include <grub/dl.h>
 
 #include <grub/list.h>
 /* For embedding types.  */
@@ -57,6 +58,9 @@ struct grub_fs
   /* My name.  */
   const char *name;
 
+  /* My module */
+  grub_dl_t mod;
+
   /* Call HOOK with each file under DIR.  */
   grub_err_t (*fs_dir) (grub_device_t device, const char *path,
                     grub_fs_dir_hook_t hook, void *hook_data);