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
,
53 if (bytes
== -ENOENT
) {
55 d_delete(file
->f_dentry
);
58 mutex_lock(&inode
->i_mutex
);
59 i_size_write(inode
, datasize
+ sizeof(attributes
));
60 mutex_unlock(&inode
->i_mutex
);
71 static ssize_t
efivarfs_file_read(struct file
*file
, char __user
*userbuf
,
72 size_t count
, loff_t
*ppos
)
74 struct efivar_entry
*var
= file
->private_data
;
75 unsigned long datasize
= 0;
81 err
= efivar_entry_size(var
, &datasize
);
84 * efivarfs represents uncommitted variables with
85 * zero-length files. Reading them should return EOF.
92 data
= kmalloc(datasize
+ sizeof(attributes
), GFP_KERNEL
);
97 size
= efivar_entry_get(var
, &attributes
, &datasize
,
98 data
+ sizeof(attributes
));
102 memcpy(data
, &attributes
, sizeof(attributes
));
103 size
= simple_read_from_buffer(userbuf
, count
, ppos
,
104 data
, datasize
+ sizeof(attributes
));
111 const struct file_operations efivarfs_file_operations
= {
113 .read
= efivarfs_file_read
,
114 .write
= efivarfs_file_write
,