8
8
#include <linux/efi.h>
9
9
#include <linux/fs.h>
10
10
#include <linux/fs_context.h>
11
+ #include <linux/fs_parser.h>
11
12
#include <linux/module.h>
12
13
#include <linux/pagemap.h>
13
14
#include <linux/ucs2_string.h>
@@ -24,6 +25,21 @@ static void efivarfs_evict_inode(struct inode *inode)
24
25
clear_inode (inode );
25
26
}
26
27
28
+ static int efivarfs_show_options (struct seq_file * m , struct dentry * root )
29
+ {
30
+ struct super_block * sb = root -> d_sb ;
31
+ struct efivarfs_fs_info * sbi = sb -> s_fs_info ;
32
+ struct efivarfs_mount_opts * opts = & sbi -> mount_opts ;
33
+
34
+ if (!uid_eq (opts -> uid , GLOBAL_ROOT_UID ))
35
+ seq_printf (m , ",uid=%u" ,
36
+ from_kuid_munged (& init_user_ns , opts -> uid ));
37
+ if (!gid_eq (opts -> gid , GLOBAL_ROOT_GID ))
38
+ seq_printf (m , ",gid=%u" ,
39
+ from_kgid_munged (& init_user_ns , opts -> gid ));
40
+ return 0 ;
41
+ }
42
+
27
43
static int efivarfs_statfs (struct dentry * dentry , struct kstatfs * buf )
28
44
{
29
45
const u32 attr = EFI_VARIABLE_NON_VOLATILE |
@@ -70,6 +86,7 @@ static const struct super_operations efivarfs_ops = {
70
86
.statfs = efivarfs_statfs ,
71
87
.drop_inode = generic_delete_inode ,
72
88
.evict_inode = efivarfs_evict_inode ,
89
+ .show_options = efivarfs_show_options ,
73
90
};
74
91
75
92
/*
@@ -231,6 +248,45 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data)
231
248
return 0 ;
232
249
}
233
250
251
+ enum {
252
+ Opt_uid , Opt_gid ,
253
+ };
254
+
255
+ static const struct fs_parameter_spec efivarfs_parameters [] = {
256
+ fsparam_u32 ("uid" , Opt_uid ),
257
+ fsparam_u32 ("gid" , Opt_gid ),
258
+ {},
259
+ };
260
+
261
+ static int efivarfs_parse_param (struct fs_context * fc , struct fs_parameter * param )
262
+ {
263
+ struct efivarfs_fs_info * sbi = fc -> s_fs_info ;
264
+ struct efivarfs_mount_opts * opts = & sbi -> mount_opts ;
265
+ struct fs_parse_result result ;
266
+ int opt ;
267
+
268
+ opt = fs_parse (fc , efivarfs_parameters , param , & result );
269
+ if (opt < 0 )
270
+ return opt ;
271
+
272
+ switch (opt ) {
273
+ case Opt_uid :
274
+ opts -> uid = make_kuid (current_user_ns (), result .uint_32 );
275
+ if (!uid_valid (opts -> uid ))
276
+ return - EINVAL ;
277
+ break ;
278
+ case Opt_gid :
279
+ opts -> gid = make_kgid (current_user_ns (), result .uint_32 );
280
+ if (!gid_valid (opts -> gid ))
281
+ return - EINVAL ;
282
+ break ;
283
+ default :
284
+ return - EINVAL ;
285
+ }
286
+
287
+ return 0 ;
288
+ }
289
+
234
290
static int efivarfs_fill_super (struct super_block * sb , struct fs_context * fc )
235
291
{
236
292
struct inode * inode = NULL ;
@@ -277,10 +333,21 @@ static int efivarfs_get_tree(struct fs_context *fc)
277
333
278
334
static const struct fs_context_operations efivarfs_context_ops = {
279
335
.get_tree = efivarfs_get_tree ,
336
+ .parse_param = efivarfs_parse_param ,
280
337
};
281
338
282
339
static int efivarfs_init_fs_context (struct fs_context * fc )
283
340
{
341
+ struct efivarfs_fs_info * sfi ;
342
+
343
+ sfi = kzalloc (sizeof (* sfi ), GFP_KERNEL );
344
+ if (!sfi )
345
+ return - ENOMEM ;
346
+
347
+ sfi -> mount_opts .uid = GLOBAL_ROOT_UID ;
348
+ sfi -> mount_opts .gid = GLOBAL_ROOT_GID ;
349
+
350
+ fc -> s_fs_info = sfi ;
284
351
fc -> ops = & efivarfs_context_ops ;
285
352
return 0 ;
286
353
}
@@ -301,6 +368,7 @@ static struct file_system_type efivarfs_type = {
301
368
.name = "efivarfs" ,
302
369
.init_fs_context = efivarfs_init_fs_context ,
303
370
.kill_sb = efivarfs_kill_sb ,
371
+ .parameters = efivarfs_parameters ,
304
372
};
305
373
306
374
static __init int efivarfs_init (void )
0 commit comments