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
= memdup_user(userbuf
+ sizeof(attributes
), datasize
);
40 bytes
= efivar_entry_set_get_size(var
, attributes
, &datasize
,
48 if (bytes
== -ENOENT
) {
50 d_delete(file
->f_path
.dentry
);
51 dput(file
->f_path
.dentry
);
53 mutex_lock(&inode
->i_mutex
);
54 i_size_write(inode
, datasize
+ sizeof(attributes
));
55 mutex_unlock(&inode
->i_mutex
);
66 static ssize_t
efivarfs_file_read(struct file
*file
, char __user
*userbuf
,
67 size_t count
, loff_t
*ppos
)
69 struct efivar_entry
*var
= file
->private_data
;
70 unsigned long datasize
= 0;
76 err
= efivar_entry_size(var
, &datasize
);
79 * efivarfs represents uncommitted variables with
80 * zero-length files. Reading them should return EOF.
87 data
= kmalloc(datasize
+ sizeof(attributes
), GFP_KERNEL
);
92 size
= efivar_entry_get(var
, &attributes
, &datasize
,
93 data
+ sizeof(attributes
));
97 memcpy(data
, &attributes
, sizeof(attributes
));
98 size
= simple_read_from_buffer(userbuf
, count
, ppos
,
99 data
, datasize
+ sizeof(attributes
));
106 const struct file_operations efivarfs_file_operations
= {
108 .read
= efivarfs_file_read
,
109 .write
= efivarfs_file_write
,