| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012 Red Hat, Inc. |
|---|
| 3 | 4 | * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 7 | | - * published by the Free Software Foundation. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/ctype.h> |
|---|
| 11 | 8 | #include <linux/efi.h> |
|---|
| 12 | 9 | #include <linux/fs.h> |
|---|
| 10 | +#include <linux/fs_context.h> |
|---|
| 13 | 11 | #include <linux/module.h> |
|---|
| 14 | 12 | #include <linux/pagemap.h> |
|---|
| 15 | 13 | #include <linux/ucs2_string.h> |
|---|
| .. | .. |
|---|
| 30 | 28 | .drop_inode = generic_delete_inode, |
|---|
| 31 | 29 | .evict_inode = efivarfs_evict_inode, |
|---|
| 32 | 30 | }; |
|---|
| 33 | | - |
|---|
| 34 | | -static struct super_block *efivarfs_sb; |
|---|
| 35 | 31 | |
|---|
| 36 | 32 | /* |
|---|
| 37 | 33 | * Compare two efivarfs file names. |
|---|
| .. | .. |
|---|
| 194 | 190 | return 0; |
|---|
| 195 | 191 | } |
|---|
| 196 | 192 | |
|---|
| 197 | | -static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) |
|---|
| 193 | +static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) |
|---|
| 198 | 194 | { |
|---|
| 199 | 195 | struct inode *inode = NULL; |
|---|
| 200 | 196 | struct dentry *root; |
|---|
| 201 | 197 | int err; |
|---|
| 202 | | - |
|---|
| 203 | | - efivarfs_sb = sb; |
|---|
| 204 | 198 | |
|---|
| 205 | 199 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
|---|
| 206 | 200 | sb->s_blocksize = PAGE_SIZE; |
|---|
| .. | .. |
|---|
| 209 | 203 | sb->s_op = &efivarfs_ops; |
|---|
| 210 | 204 | sb->s_d_op = &efivarfs_d_ops; |
|---|
| 211 | 205 | sb->s_time_gran = 1; |
|---|
| 206 | + |
|---|
| 207 | + if (!efivar_supports_writes()) |
|---|
| 208 | + sb->s_flags |= SB_RDONLY; |
|---|
| 212 | 209 | |
|---|
| 213 | 210 | inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true); |
|---|
| 214 | 211 | if (!inode) |
|---|
| .. | .. |
|---|
| 229 | 226 | return err; |
|---|
| 230 | 227 | } |
|---|
| 231 | 228 | |
|---|
| 232 | | -static struct dentry *efivarfs_mount(struct file_system_type *fs_type, |
|---|
| 233 | | - int flags, const char *dev_name, void *data) |
|---|
| 229 | +static int efivarfs_get_tree(struct fs_context *fc) |
|---|
| 234 | 230 | { |
|---|
| 235 | | - return mount_single(fs_type, flags, data, efivarfs_fill_super); |
|---|
| 231 | + return get_tree_single(fc, efivarfs_fill_super); |
|---|
| 232 | +} |
|---|
| 233 | + |
|---|
| 234 | +static const struct fs_context_operations efivarfs_context_ops = { |
|---|
| 235 | + .get_tree = efivarfs_get_tree, |
|---|
| 236 | +}; |
|---|
| 237 | + |
|---|
| 238 | +static int efivarfs_init_fs_context(struct fs_context *fc) |
|---|
| 239 | +{ |
|---|
| 240 | + fc->ops = &efivarfs_context_ops; |
|---|
| 241 | + return 0; |
|---|
| 236 | 242 | } |
|---|
| 237 | 243 | |
|---|
| 238 | 244 | static void efivarfs_kill_sb(struct super_block *sb) |
|---|
| 239 | 245 | { |
|---|
| 240 | 246 | kill_litter_super(sb); |
|---|
| 241 | | - efivarfs_sb = NULL; |
|---|
| 242 | 247 | |
|---|
| 243 | 248 | /* Remove all entries and destroy */ |
|---|
| 244 | 249 | __efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL, NULL); |
|---|
| .. | .. |
|---|
| 247 | 252 | static struct file_system_type efivarfs_type = { |
|---|
| 248 | 253 | .owner = THIS_MODULE, |
|---|
| 249 | 254 | .name = "efivarfs", |
|---|
| 250 | | - .mount = efivarfs_mount, |
|---|
| 255 | + .init_fs_context = efivarfs_init_fs_context, |
|---|
| 251 | 256 | .kill_sb = efivarfs_kill_sb, |
|---|
| 252 | 257 | }; |
|---|
| 253 | 258 | |
|---|
| 254 | 259 | static __init int efivarfs_init(void) |
|---|
| 255 | 260 | { |
|---|
| 256 | | - if (!efi_enabled(EFI_RUNTIME_SERVICES)) |
|---|
| 257 | | - return -ENODEV; |
|---|
| 258 | | - |
|---|
| 259 | 261 | if (!efivars_kobject()) |
|---|
| 260 | 262 | return -ENODEV; |
|---|
| 261 | 263 | |
|---|
| .. | .. |
|---|
| 270 | 272 | MODULE_AUTHOR("Matthew Garrett, Jeremy Kerr"); |
|---|
| 271 | 273 | MODULE_DESCRIPTION("EFI Variable Filesystem"); |
|---|
| 272 | 274 | MODULE_LICENSE("GPL"); |
|---|
| 275 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 273 | 276 | MODULE_ALIAS_FS("efivarfs"); |
|---|
| 274 | 277 | |
|---|
| 275 | 278 | module_init(efivarfs_init); |
|---|