2 * Copyright (C) 2012 Red Hat, Inc.
3 * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
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.
10 #include <linux/efi.h>
12 #include <linux/slab.h>
16 static ssize_t
efivarfs_file_write(struct file
*file
,
17 const char __user
*userbuf
, size_t count
, loff_t
*ppos
)
19 struct efivar_entry
*var
= file
->private_data
;
22 struct inode
*inode
= file
->f_mapping
->host
;
23 unsigned long datasize
= count
- sizeof(attributes
);
27 if (count
< sizeof(attributes
))
30 if (copy_from_user(&attributes
, userbuf
, sizeof(attributes
)))
33 if (attributes
& ~(EFI_VARIABLE_MASK
))
36 data
= kmalloc(datasize
, GFP_KERNEL
);
40 if (copy_from_user(data
, userbuf
+ sizeof(attributes
), datasize
)) {
45 bytes
= efivar_entry_set_get_size(var
, attributes
, &datasize
,
50 if (bytes
== -ENOENT
) {
52 d_delete(file
->f_dentry
);
55 mutex_lock(&inode
->i_mutex
);
56 i_size_write(inode
, datasize
+ sizeof(attributes
));
57 mutex_unlock(&inode
->i_mutex
);
68 static ssize_t
efivarfs_file_read(struct file
*file
, char __user
*userbuf
,
69 size_t count
, loff_t
*ppos
)
71 struct efivar_entry
*var
= file
->private_data
;
72 unsigned long datasize
= 0;
78 err
= efivar_entry_size(var
, &datasize
);
82 data
= kmalloc(datasize
+ sizeof(attributes
), GFP_KERNEL
);
87 size
= efivar_entry_get(var
, &attributes
, &datasize
,
88 data
+ sizeof(attributes
));
92 memcpy(data
, &attributes
, sizeof(attributes
));
93 size
= simple_read_from_buffer(userbuf
, count
, ppos
,
94 data
, datasize
+ sizeof(attributes
));
101 const struct file_operations efivarfs_file_operations
= {
103 .read
= efivarfs_file_read
,
104 .write
= efivarfs_file_write
,