aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-02-08 11:27:24 -0500
committerMatt Fleming <matt.fleming@intel.com>2013-04-17 08:25:09 -0400
commitd68772b7c83f4b518be15ae96f4827c8ed02f684 (patch)
treeb3408a750976edf6e0b62bfce3e26d1c9685a907
parent048517722cde2595a7366d0c3c72b8b1ec142a9c (diff)
efivarfs: Move to fs/efivarfs
Now that efivarfs uses the efivar API, move it out of efivars.c and into fs/efivarfs where it belongs. This move will eventually allow us to enable the efivarfs code without having to also enable CONFIG_EFI_VARS built, and vice versa. Furthermore, things like, mount -t efivarfs none /sys/firmware/efi/efivars will now work if efivarfs is built as a module without requiring the use of MODULE_ALIAS(), which would have been necessary when the efivarfs code was part of efivars.c. Cc: Matthew Garrett <matthew.garrett@nebula.com> Cc: Jeremy Kerr <jk@ozlabs.org> Reviewed-by: Tom Gundersen <teg@jklm.no> Tested-by: Tom Gundersen <teg@jklm.no> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--MAINTAINERS9
-rw-r--r--drivers/firmware/efivars.c496
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/Makefile1
-rw-r--r--fs/efivarfs/Kconfig12
-rw-r--r--fs/efivarfs/Makefile7
-rw-r--r--fs/efivarfs/file.c111
-rw-r--r--fs/efivarfs/inode.c173
-rw-r--r--fs/efivarfs/internal.h22
-rw-r--r--fs/efivarfs/super.c267
10 files changed, 603 insertions, 496 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 9e4862bf9961..0855f4450e91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2990,6 +2990,15 @@ F: arch/x86/platform/efi/*
2990F: drivers/firmware/efivars.c 2990F: drivers/firmware/efivars.c
2991F: include/linux/efi*.h 2991F: include/linux/efi*.h
2992 2992
2993EFI VARIABLE FILESYSTEM
2994M: Matthew Garrett <matthew.garrett@nebula.com>
2995M: Jeremy Kerr <jk@ozlabs.org>
2996M: Matt Fleming <matt.fleming@intel.com>
2997T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
2998L: linux-efi@vger.kernel.org
2999S: Maintained
3000F: fs/efivarfs/
3001
2993EFIFB FRAMEBUFFER DRIVER 3002EFIFB FRAMEBUFFER DRIVER
2994L: linux-fbdev@vger.kernel.org 3003L: linux-fbdev@vger.kernel.org
2995M: Peter Jones <pjones@redhat.com> 3004M: Peter Jones <pjones@redhat.com>
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 5e7c3b1acde9..af396758482f 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -94,7 +94,6 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables");
94MODULE_LICENSE("GPL"); 94MODULE_LICENSE("GPL");
95MODULE_VERSION(EFIVARS_VERSION); 95MODULE_VERSION(EFIVARS_VERSION);
96 96
97static LIST_HEAD(efivarfs_list);
98LIST_HEAD(efivar_sysfs_list); 97LIST_HEAD(efivar_sysfs_list);
99EXPORT_SYMBOL_GPL(efivar_sysfs_list); 98EXPORT_SYMBOL_GPL(efivar_sysfs_list);
100 99
@@ -558,12 +557,6 @@ static struct kobj_type efivar_ktype = {
558 .default_attrs = def_attrs, 557 .default_attrs = def_attrs,
559}; 558};
560 559
561static int efivarfs_file_open(struct inode *inode, struct file *file)
562{
563 file->private_data = inode->i_private;
564 return 0;
565}
566
567static int efi_status_to_err(efi_status_t status) 560static int efi_status_to_err(efi_status_t status)
568{ 561{
569 int err; 562 int err;
@@ -597,493 +590,6 @@ static int efi_status_to_err(efi_status_t status)
597 return err; 590 return err;
598} 591}
599 592
600static ssize_t efivarfs_file_write(struct file *file,
601 const char __user *userbuf, size_t count, loff_t *ppos)
602{
603 struct efivar_entry *var = file->private_data;
604 void *data;
605 u32 attributes;
606 struct inode *inode = file->f_mapping->host;
607 unsigned long datasize = count - sizeof(attributes);
608 ssize_t bytes = 0;
609 bool set = false;
610
611 if (count < sizeof(attributes))
612 return -EINVAL;
613
614 if (copy_from_user(&attributes, userbuf, sizeof(attributes)))
615 return -EFAULT;
616
617 if (attributes & ~(EFI_VARIABLE_MASK))
618 return -EINVAL;
619
620 data = kmalloc(datasize, GFP_KERNEL);
621 if (!data)
622 return -ENOMEM;
623
624 if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
625 bytes = -EFAULT;
626 goto out;
627 }
628
629 bytes = efivar_entry_set_get_size(var, attributes, &datasize,
630 data, &set);
631 if (!set && bytes)
632 goto out;
633
634 if (!bytes) {
635 mutex_lock(&inode->i_mutex);
636 i_size_write(inode, datasize + sizeof(attributes));
637 mutex_unlock(&inode->i_mutex);
638 } else if (bytes == -ENOENT) {
639 drop_nlink(inode);
640 d_delete(file->f_dentry);
641 dput(file->f_dentry);
642 } else
643 pr_warn("efivarfs: inconsistent EFI variable implementation? "
644 "status=%zu\n", bytes);
645
646 bytes = count;
647
648out:
649 kfree(data);
650
651 return bytes;
652}
653
654static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
655 size_t count, loff_t *ppos)
656{
657 struct efivar_entry *var = file->private_data;
658 unsigned long datasize = 0;
659 u32 attributes;
660 void *data;
661 ssize_t size = 0;
662 int err;
663
664 err = efivar_entry_size(var, &datasize);
665 if (err)
666 return err;
667
668 data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);
669
670 if (!data)
671 return -ENOMEM;
672
673 size = efivar_entry_get(var, &attributes, &datasize,
674 data + sizeof(attributes));
675 if (size)
676 goto out_free;
677
678 memcpy(data, &attributes, sizeof(attributes));
679 size = simple_read_from_buffer(userbuf, count, ppos,
680 data, datasize + sizeof(attributes));
681out_free:
682 kfree(data);
683
684 return size;
685}
686
687static void efivarfs_evict_inode(struct inode *inode)
688{
689 clear_inode(inode);
690}
691
692static const struct super_operations efivarfs_ops = {
693 .statfs = simple_statfs,
694 .drop_inode = generic_delete_inode,
695 .evict_inode = efivarfs_evict_inode,
696 .show_options = generic_show_options,
697};
698
699static struct super_block *efivarfs_sb;
700
701static const struct inode_operations efivarfs_dir_inode_operations;
702
703static const struct file_operations efivarfs_file_operations = {
704 .open = efivarfs_file_open,
705 .read = efivarfs_file_read,
706 .write = efivarfs_file_write,
707 .llseek = no_llseek,
708};
709
710static struct inode *efivarfs_get_inode(struct super_block *sb,
711 const struct inode *dir, int mode, dev_t dev)
712{
713 struct inode *inode = new_inode(sb);
714
715 if (inode) {
716 inode->i_ino = get_next_ino();
717 inode->i_mode = mode;
718 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
719 switch (mode & S_IFMT) {
720 case S_IFREG:
721 inode->i_fop = &efivarfs_file_operations;
722 break;
723 case S_IFDIR:
724 inode->i_op = &efivarfs_dir_inode_operations;
725 inode->i_fop = &simple_dir_operations;
726 inc_nlink(inode);
727 break;
728 }
729 }
730 return inode;
731}
732
733/*