Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Linus Torvalds [Thu, 2 May 2013 00:51:54 +0000 (17:51 -0700)]
Pull VFS updates from Al Viro,

Misc cleanups all over the place, mainly wrt /proc interfaces (switch
create_proc_entry to proc_create(), get rid of the deprecated
create_proc_read_entry() in favor of using proc_create_data() and
seq_file etc).

7kloc removed.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (204 commits)
  don't bother with deferred freeing of fdtables
  proc: Move non-public stuff from linux/proc_fs.h to fs/proc/internal.h
  proc: Make the PROC_I() and PDE() macros internal to procfs
  proc: Supply a function to remove a proc entry by PDE
  take cgroup_open() and cpuset_open() to fs/proc/base.c
  ppc: Clean up scanlog
  ppc: Clean up rtas_flash driver somewhat
  hostap: proc: Use remove_proc_subtree()
  drm: proc: Use remove_proc_subtree()
  drm: proc: Use minor->index to label things, not PDE->name
  drm: Constify drm_proc_list[]
  zoran: Don't print proc_dir_entry data in debug
  reiserfs: Don't access the proc_dir_entry in r_open(), r_start() r_show()
  proc: Supply an accessor for getting the data from a PDE's parent
  airo: Use remove_proc_subtree()
  rtl8192u: Don't need to save device proc dir PDE
  rtl8187se: Use a dir under /proc/net/r8180/
  proc: Add proc_mkdir_data()
  proc: Move some bits from linux/proc_fs.h to linux/{of.h,signal.h,tty.h}
  proc: Move PDE_NET() to fs/proc/proc_net.c
  ...

103 files changed:
1  2 
arch/arm/mach-omap1/pm.c
arch/mips/mm/init.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/irq.c
arch/s390/kernel/syscalls.S
arch/score/mm/init.c
arch/x86/ia32/ia32_aout.c
arch/x86/mm/init_64.c
arch/x86/platform/efi/efi.c
drivers/acpi/battery.c
drivers/acpi/button.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/firmware/efi/efi-pstore.c
drivers/firmware/efi/efivars.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_net.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/media/rc/ir-lirc-codec.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/ray_cs.c
drivers/of/base.c
drivers/platform/x86/thinkpad_acpi.c
drivers/pnp/pnpbios/proc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/qla2xxx/qla_os.c
drivers/staging/csr/drv.c
drivers/staging/dgrp/dgrp_common.h
drivers/staging/dgrp/dgrp_dpa_ops.c
drivers/staging/dgrp/dgrp_net_ops.c
drivers/staging/rts5139/rts51x_scsi.c
drivers/staging/rts5139/rts51x_scsi.h
drivers/staging/silicom/bpctl_mod.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6656/main_usb.c
drivers/tty/serial/serial_core.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/lpc32xx_udc.c
drivers/usb/host/sl811-hcd.c
drivers/usb/storage/scsiglue.c
fs/Makefile
fs/aio.c
fs/binfmt_aout.c
fs/binfmt_elf_fdpic.c
fs/btrfs/file.c
fs/compat.c
fs/coredump.c
fs/efivarfs/file.c
fs/efivarfs/inode.c
fs/efivarfs/super.c
fs/exec.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/inode.c
fs/jbd2/journal.c
fs/namespace.c
fs/notify/inotify/inotify_user.c
fs/pnode.c
fs/pnode.h
fs/proc/base.c
fs/proc/internal.h
fs/proc/kcore.c
fs/proc/root.c
fs/read_write.c
fs/read_write.h
fs/splice.c
include/linux/cgroup.h
include/linux/cpuset.h
include/linux/fs.h
include/linux/pid_namespace.h
include/linux/signal.h
include/linux/tty.h
include/net/bluetooth/bluetooth.h
ipc/msgutil.c
ipc/util.c
kernel/cgroup.c
kernel/cpuset.c
kernel/exit.c
kernel/pid.c
kernel/pid_namespace.c
kernel/user.c
kernel/user_namespace.c
mm/filemap.c
mm/vmalloc.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/core/neighbour.c
net/core/pktgen.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/proc.c
net/netfilter/x_tables.c
net/netfilter/xt_hashlimit.c
net/socket.c
net/sunrpc/cache.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 67615d6,0000000..202d2c8
mode 100644,000000..100644
--- /dev/null
@@@ -1,251 -1,0 +1,252 @@@
 +#include <linux/efi.h>
 +#include <linux/module.h>
 +#include <linux/pstore.h>
++#include <linux/slab.h>
 +#include <linux/ucs2_string.h>
 +
 +#define DUMP_NAME_LEN 52
 +
 +static bool efivars_pstore_disable =
 +      IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
 +
 +module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
 +
 +#define PSTORE_EFI_ATTRIBUTES \
 +      (EFI_VARIABLE_NON_VOLATILE | \
 +       EFI_VARIABLE_BOOTSERVICE_ACCESS | \
 +       EFI_VARIABLE_RUNTIME_ACCESS)
 +
 +static int efi_pstore_open(struct pstore_info *psi)
 +{
 +      efivar_entry_iter_begin();
 +      psi->data = NULL;
 +      return 0;
 +}
 +
 +static int efi_pstore_close(struct pstore_info *psi)
 +{
 +      efivar_entry_iter_end();
 +      psi->data = NULL;
 +      return 0;
 +}
 +
 +struct pstore_read_data {
 +      u64 *id;
 +      enum pstore_type_id *type;
 +      int *count;
 +      struct timespec *timespec;
 +      char **buf;
 +};
 +
 +static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
 +{
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      struct pstore_read_data *cb_data = data;
 +      char name[DUMP_NAME_LEN];
 +      int i;
 +      int cnt;
 +      unsigned int part;
 +      unsigned long time, size;
 +
 +      if (efi_guidcmp(entry->var.VendorGuid, vendor))
 +              return 0;
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              name[i] = entry->var.VariableName[i];
 +
 +      if (sscanf(name, "dump-type%u-%u-%d-%lu",
 +                 cb_data->type, &part, &cnt, &time) == 4) {
 +              *cb_data->id = part;
 +              *cb_data->count = cnt;
 +              cb_data->timespec->tv_sec = time;
 +              cb_data->timespec->tv_nsec = 0;
 +      } else if (sscanf(name, "dump-type%u-%u-%lu",
 +                        cb_data->type, &part, &time) == 3) {
 +              /*
 +               * Check if an old format,
 +               * which doesn't support holding
 +               * multiple logs, remains.
 +               */
 +              *cb_data->id = part;
 +              *cb_data->count = 0;
 +              cb_data->timespec->tv_sec = time;
 +              cb_data->timespec->tv_nsec = 0;
 +      } else
 +              return 0;
 +
 +      entry->var.DataSize = 1024;
 +      __efivar_entry_get(entry, &entry->var.Attributes,
 +                         &entry->var.DataSize, entry->var.Data);
 +      size = entry->var.DataSize;
 +
 +      *cb_data->buf = kmalloc(size, GFP_KERNEL);
 +      if (*cb_data->buf == NULL)
 +              return -ENOMEM;
 +      memcpy(*cb_data->buf, entry->var.Data, size);
 +      return size;
 +}
 +
 +static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
 +                             int *count, struct timespec *timespec,
 +                             char **buf, struct pstore_info *psi)
 +{
 +      struct pstore_read_data data;
 +
 +      data.id = id;
 +      data.type = type;
 +      data.count = count;
 +      data.timespec = timespec;
 +      data.buf = buf;
 +
 +      return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
 +                                 (struct efivar_entry **)&psi->data);
 +}
 +
 +static int efi_pstore_write(enum pstore_type_id type,
 +              enum kmsg_dump_reason reason, u64 *id,
 +              unsigned int part, int count, size_t size,
 +              struct pstore_info *psi)
 +{
 +      char name[DUMP_NAME_LEN];
 +      efi_char16_t efi_name[DUMP_NAME_LEN];
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      int i, ret = 0;
 +
 +      sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
 +              get_seconds());
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              efi_name[i] = name[i];
 +
 +      efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
 +                            !pstore_cannot_block_path(reason),
 +                            size, psi->buf);
 +
 +      if (reason == KMSG_DUMP_OOPS)
 +              efivar_run_worker();
 +
 +      *id = part;
 +      return ret;
 +};
 +
 +struct pstore_erase_data {
 +      u64 id;
 +      enum pstore_type_id type;
 +      int count;
 +      struct timespec time;
 +      efi_char16_t *name;
 +};
 +
 +/*
 + * Clean up an entry with the same name
 + */
 +static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
 +{
 +      struct pstore_erase_data *ed = data;
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      efi_char16_t efi_name_old[DUMP_NAME_LEN];
 +      efi_char16_t *efi_name = ed->name;
 +      unsigned long ucs2_len = ucs2_strlen(ed->name);
 +      char name_old[DUMP_NAME_LEN];
 +      int i;
 +
 +      if (efi_guidcmp(entry->var.VendorGuid, vendor))
 +              return 0;
 +
 +      if (ucs2_strncmp(entry->var.VariableName,
 +                        efi_name, (size_t)ucs2_len)) {
 +              /*
 +               * Check if an old format, which doesn't support
 +               * holding multiple logs, remains.
 +               */
 +              sprintf(name_old, "dump-type%u-%u-%lu", ed->type,
 +                      (unsigned int)ed->id, ed->time.tv_sec);
 +
 +              for (i = 0; i < DUMP_NAME_LEN; i++)
 +                      efi_name_old[i] = name_old[i];
 +
 +              if (ucs2_strncmp(entry->var.VariableName, efi_name_old,
 +                                ucs2_strlen(efi_name_old)))
 +                      return 0;
 +      }
 +
 +      /* found */
 +      __efivar_entry_delete(entry);
 +      list_del(&entry->list);
 +
 +      return 1;
 +}
 +
 +static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 +                          struct timespec time, struct pstore_info *psi)
 +{
 +      struct pstore_erase_data edata;
 +      struct efivar_entry *entry = NULL;
 +      char name[DUMP_NAME_LEN];
 +      efi_char16_t efi_name[DUMP_NAME_LEN];
 +      int found, i;
 +
 +      sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
 +              time.tv_sec);
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              efi_name[i] = name[i];
 +
 +      edata.id = id;
 +      edata.type = type;
 +      edata.count = count;
 +      edata.time = time;
 +      edata.name = efi_name;
 +
 +      efivar_entry_iter_begin();
 +      found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
 +      efivar_entry_iter_end();
 +
 +      if (found)
 +              efivar_unregister(entry);
 +
 +      return 0;
 +}
 +
 +static struct pstore_info efi_pstore_info = {
 +      .owner          = THIS_MODULE,
 +      .name           = "efi",
 +      .open           = efi_pstore_open,
 +      .close          = efi_pstore_close,
 +      .read           = efi_pstore_read,
 +      .write          = efi_pstore_write,
 +      .erase          = efi_pstore_erase,
 +};
 +
 +static __init int efivars_pstore_init(void)
 +{
 +      if (!efi_enabled(EFI_RUNTIME_SERVICES))
 +              return 0;
 +
 +      if (!efivars_kobject())
 +              return 0;
 +
 +      if (efivars_pstore_disable)
 +              return 0;
 +
 +      efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
 +      if (!efi_pstore_info.buf)
 +              return -ENOMEM;
 +
 +      efi_pstore_info.bufsize = 1024;
 +      spin_lock_init(&efi_pstore_info.buf_lock);
 +
 +      pstore_register(&efi_pstore_info);
 +
 +      return 0;
 +}
 +
 +static __exit void efivars_pstore_exit(void)
 +{
 +}
 +
 +module_init(efivars_pstore_init);
 +module_exit(efivars_pstore_exit);
 +
 +MODULE_DESCRIPTION("EFI variable backend for pstore");
 +MODULE_LICENSE("GPL");
index 5e94897,0000000..b623c59
mode 100644,000000..100644
--- /dev/null
@@@ -1,616 -1,0 +1,617 @@@
 +/*
 + * Originally from efivars.c,
 + *
 + * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
 + * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
 + *
 + * This code takes all variables accessible from EFI runtime and
 + *  exports them via sysfs
 + *
 + *  This program is free software; you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation; either version 2 of the License, or
 + *  (at your option) any later version.
 + *
 + *  This program is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with this program; if not, write to the Free Software
 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + *
 + * Changelog:
 + *
 + *  17 May 2004 - Matt Domsch <Matt_Domsch@dell.com>
 + *   remove check for efi_enabled in exit
 + *   add MODULE_VERSION
 + *
 + *  26 Apr 2004 - Matt Domsch <Matt_Domsch@dell.com>
 + *   minor bug fixes
 + *
 + *  21 Apr 2004 - Matt Tolentino <matthew.e.tolentino@intel.com)
 + *   converted driver to export variable information via sysfs
 + *   and moved to drivers/firmware directory
 + *   bumped revision number to v0.07 to reflect conversion & move
 + *
 + *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   fix locking per Peter Chubb's findings
 + *
 + *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
 + *
 + *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   use list_for_each_safe when deleting vars.
 + *   remove ifdef CONFIG_SMP around include <linux/smp.h>
 + *   v0.04 release to linux-ia64@linuxia64.org
 + *
 + *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   Moved vars from /proc/efi to /proc/efi/vars, and made
 + *   efi.c own the /proc/efi directory.
 + *   v0.03 release to linux-ia64@linuxia64.org
 + *
 + *  26 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   At the request of Stephane, moved ownership of /proc/efi
 + *   to efi.c, and now efivars lives under /proc/efi/vars.
 + *
 + *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   Feedback received from Stephane Eranian incorporated.
 + *   efivar_write() checks copy_from_user() return value.
 + *   efivar_read/write() returns proper errno.
 + *   v0.02 release to linux-ia64@linuxia64.org
 + *
 + *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   v0.01 release to linux-ia64@linuxia64.org
 + */
 +
 +#include <linux/efi.h>
 +#include <linux/module.h>
++#include <linux/slab.h>
 +#include <linux/ucs2_string.h>
 +
 +#define EFIVARS_VERSION "0.08"
 +#define EFIVARS_DATE "2004-May-17"
 +
 +MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 +MODULE_DESCRIPTION("sysfs interface to EFI Variables");
 +MODULE_LICENSE("GPL");
 +MODULE_VERSION(EFIVARS_VERSION);
 +
 +LIST_HEAD(efivar_sysfs_list);
 +EXPORT_SYMBOL_GPL(efivar_sysfs_list);
 +
 +static struct kset *efivars_kset;
 +
 +static struct bin_attribute *efivars_new_var;
 +static struct bin_attribute *efivars_del_var;
 +
 +struct efivar_attribute {
 +      struct attribute attr;
 +      ssize_t (*show) (struct efivar_entry *entry, char *buf);
 +      ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
 +};
 +
 +#define EFIVAR_ATTR(_name, _mode, _show, _store) \
 +struct efivar_attribute efivar_attr_##_name = { \
 +      .attr = {.name = __stringify(_name), .mode = _mode}, \
 +      .show = _show, \
 +      .store = _store, \
 +};
 +
 +#define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
 +#define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
 +
 +/*
 + * Prototype for sysfs creation function
 + */
 +static int
 +efivar_create_sysfs_entry(struct efivar_entry *new_var);
 +
 +static ssize_t
 +efivar_guid_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return 0;
 +
 +      efi_guid_unparse(&var->VendorGuid, str);
 +      str += strlen(str);
 +      str += sprintf(str, "\n");
 +
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_attr_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
 +              str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
 +      if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
 +              str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
 +              str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
 +              str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
 +      if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
 +              str += sprintf(str,
 +                      "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
 +      if (var->Attributes &
 +                      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
 +              str += sprintf(str,
 +                      "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
 +              str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_size_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      str += sprintf(str, "0x%lx\n", var->DataSize);
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_data_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      memcpy(buf, var->Data, var->DataSize);
 +      return var->DataSize;
 +}
 +/*
 + * We allow each variable to be edited via rewriting the
 + * entire efi variable structure.
 + */
 +static ssize_t
 +efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
 +{
 +      struct efi_variable *new_var, *var = &entry->var;
 +      int err;
 +
 +      if (count != sizeof(struct efi_variable))
 +              return -EINVAL;
 +
 +      new_var = (struct efi_variable *)buf;
 +      /*
 +       * If only updating the variable data, then the name
 +       * and guid should remain the same
 +       */
 +      if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
 +              efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
 +              printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
 +              return -EINVAL;
 +      }
 +
 +      if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
 +              printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
 +              return -EINVAL;
 +      }
 +
 +      if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
 +          efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
 +              printk(KERN_ERR "efivars: Malformed variable content\n");
 +              return -EINVAL;
 +      }
 +
 +      memcpy(&entry->var, new_var, count);
 +
 +      err = efivar_entry_set(entry, new_var->Attributes,
 +                             new_var->DataSize, new_var->Data, false);
 +      if (err) {
 +              printk(KERN_WARNING "efivars: set_variable() failed: status=%d\n", err);
 +              return -EIO;
 +      }
 +
 +      return count;
 +}
 +
 +static ssize_t
 +efivar_show_raw(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +
 +      if (!entry || !buf)
 +              return 0;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &entry->var.Attributes,
 +                           &entry->var.DataSize, entry->var.Data))
 +              return -EIO;
 +
 +      memcpy(buf, var, sizeof(*var));
 +
 +      return sizeof(*var);
 +}
 +
 +/*
 + * Generic read/write functions that call the specific functions of
 + * the attributes...
 + */
 +static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
 +                              char *buf)
 +{
 +      struct efivar_entry *var = to_efivar_entry(kobj);
 +      struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 +      ssize_t ret = -EIO;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if (efivar_attr->show) {
 +              ret = efivar_attr->show(var, buf);
 +      }
 +      return ret;
 +}
 +
 +static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
 +                              const char *buf, size_t count)
 +{
 +      struct efivar_entry *var = to_efivar_entry(kobj);
 +      struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 +      ssize_t ret = -EIO;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if (efivar_attr->store)
 +              ret = efivar_attr->store(var, buf, count);
 +
 +      return ret;
 +}
 +
 +static const struct sysfs_ops efivar_attr_ops = {
 +      .show = efivar_attr_show,
 +      .store = efivar_attr_store,
 +};
 +
 +static void efivar_release(struct kobject *kobj)
 +{
 +      struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
 +      kfree(var);
 +}
 +
 +static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
 +static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
 +static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
 +static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
 +static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
 +
 +static struct attribute *def_attrs[] = {
 +      &efivar_attr_guid.attr,
 +      &efivar_attr_size.attr,
 +      &efivar_attr_attributes.attr,
 +      &efivar_attr_data.attr,
 +      &efivar_attr_raw_var.attr,
 +      NULL,
 +};
 +
 +static struct kobj_type efivar_ktype = {
 +      .release = efivar_release,
 +      .sysfs_ops = &efivar_attr_ops,
 +      .default_attrs = def_attrs,
 +};
 +
 +static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
 +                           struct bin_attribute *bin_attr,
 +                           char *buf, loff_t pos, size_t count)
 +{
 +      struct efi_variable *new_var = (struct efi_variable *)buf;
 +      struct efivar_entry *new_entry;
 +      int err;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
 +          efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
 +              printk(KERN_ERR "efivars: Malformed variable content\n");
 +              return -EINVAL;
 +      }
 +
 +      new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
 +      if (!new_entry)
 +              return -ENOMEM;
 +
 +      memcpy(&new_entry->var, new_var, sizeof(*new_var));
 +
 +      err = efivar_entry_set(new_entry, new_var->Attributes, new_var->DataSize,
 +                             new_var->Data, &efivar_sysfs_list);
 +      if (err) {
 +              if (err == -EEXIST)
 +                      err = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (efivar_create_sysfs_entry(new_entry)) {
 +              printk(KERN_WARNING "efivars: failed to create sysfs entry.\n");
 +              kfree(new_entry);
 +      }
 +      return count;
 +
 +out:
 +      kfree(new_entry);
 +      return err;
 +}
 +
 +static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
 +                           struct bin_attribute *bin_attr,
 +                           char *buf, loff_t pos, size_t count)
 +{
 +      struct efi_variable *del_var = (struct efi_variable *)buf;
 +      struct efivar_entry *entry;
 +      int err = 0;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      efivar_entry_iter_begin();
 +      entry = efivar_entry_find(del_var->VariableName, del_var->VendorGuid,
 +                                &efivar_sysfs_list, true);
 +      if (!entry)
 +              err = -EINVAL;
 +      else if (__efivar_entry_delete(entry))
 +              err = -EIO;
 +
 +      efivar_entry_iter_end();
 +
 +      if (err)
 +              return err;
 +
 +      efivar_unregister(entry);
 +
 +      /* It's dead Jim.... */
 +      return count;
 +}
 +
 +/**
 + * efivar_create_sysfs_entry - create a new entry in sysfs
 + * @new_var: efivar entry to create
 + *
 + * Returns 1 on failure, 0 on success
 + */
 +static int
 +efivar_create_sysfs_entry(struct efivar_entry *new_var)
 +{
 +      int i, short_name_size;
 +      char *short_name;
 +      unsigned long variable_name_size;
 +      efi_char16_t *variable_name;
 +
 +      variable_name = new_var->var.VariableName;
 +      variable_name_size = ucs2_strlen(variable_name) * sizeof(efi_char16_t);
 +
 +      /*
 +       * Length of the variable bytes in ASCII, plus the '-' separator,
 +       * plus the GUID, plus trailing NUL
 +       */
 +      short_name_size = variable_name_size / sizeof(efi_char16_t)
 +                              + 1 + EFI_VARIABLE_GUID_LEN + 1;
 +
 +      short_name = kzalloc(short_name_size, GFP_KERNEL);
 +
 +      if (!short_name)
 +              return 1;
 +
 +      /* Convert Unicode to normal chars (assume top bits are 0),
 +         ala UTF-8 */
 +      for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
 +              short_name[i] = variable_name[i] & 0xFF;
 +      }
 +      /* This is ugly, but necessary to separate one vendor's
 +         private variables from another's.         */
 +
 +      *(short_name + strlen(short_name)) = '-';
 +      efi_guid_unparse(&new_var->var.VendorGuid,
 +                       short_name + strlen(short_name));
 +
 +      new_var->kobj.kset = efivars_kset;
 +
 +      i = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
 +                                 NULL, "%s", short_name);
 +      kfree(short_name);
 +      if (i)
 +              return 1;
 +
 +      kobject_uevent(&new_var->kobj, KOBJ_ADD);
 +      efivar_entry_add(new_var, &efivar_sysfs_list);
 +
 +      return 0;
 +}
 +
 +static int
 +create_efivars_bin_attributes(void)
 +{
 +      struct bin_attribute *attr;
 +      int error;
 +
 +      /* new_var */
 +      attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 +      if (!attr)
 +              return -ENOMEM;
 +
 +      attr->attr.name = "new_var";
 +      attr->attr.mode = 0200;
 +      attr->write = efivar_create;
 +      efivars_new_var = attr;
 +
 +      /* del_var */
 +      attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 +      if (!attr) {
 +              error = -ENOMEM;
 +              goto out_free;
 +      }
 +      attr->attr.name = "del_var";
 +      attr->attr.mode = 0200;
 +      attr->write = efivar_delete;
 +      efivars_del_var = attr;
 +
 +      sysfs_bin_attr_init(efivars_new_var);
 +      sysfs_bin_attr_init(efivars_del_var);
 +
 +      /* Register */
 +      error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_new_var);
 +      if (error) {
 +              printk(KERN_ERR "efivars: unable to create new_var sysfs file"
 +                      " due to error %d\n", error);
 +              goto out_free;
 +      }
 +
 +      error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_del_var);
 +      if (error) {
 +              printk(KERN_ERR "efivars: unable to create del_var sysfs file"
 +                      " due to error %d\n", error);
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 +              goto out_free;
 +      }
 +
 +      return 0;
 +out_free:
 +      kfree(efivars_del_var);
 +      efivars_del_var = NULL;
 +      kfree(efivars_new_var);
 +      efivars_new_var = NULL;
 +      return error;
 +}
 +
 +static int efivar_update_sysfs_entry(efi_char16_t *name, efi_guid_t vendor,
 +                                   unsigned long name_size, void *data)
 +{
 +      struct efivar_entry *entry = data;
 +
 +      if (efivar_entry_find(name, vendor, &efivar_sysfs_list, false))
 +              return 0;
 +
 +      memcpy(entry->var.VariableName, name, name_size);
 +      memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 +
 +      return 1;
 +}
 +
 +static void efivar_update_sysfs_entries(struct work_struct *work)
 +{
 +      struct efivar_entry *entry;
 +      int err;
 +
 +      entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry)
 +              return;
 +
 +      /* Add new sysfs entries */
 +      while (1) {
 +              memset(entry, 0, sizeof(*entry));
 +
 +              err = efivar_init(efivar_update_sysfs_entry, entry,
 +                                true, false, &efivar_sysfs_list);
 +              if (!err)
 +                      break;
 +
 +              efivar_create_sysfs_entry(entry);
 +      }
 +
 +      kfree(entry);
 +}
 +
 +static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,
 +                                unsigned long name_size, void *data)
 +{
 +      struct efivar_entry *entry;
 +
 +      entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry)
 +              return -ENOMEM;
 +
 +      memcpy(entry->var.VariableName, name, name_size);
 +      memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 +
 +      efivar_create_sysfs_entry(entry);
 +
 +      return 0;
 +}
 +
 +static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
 +{
 +      efivar_entry_remove(entry);
 +      efivar_unregister(entry);
 +      return 0;
 +}
 +
 +void efivars_sysfs_exit(void)
 +{
 +      /* Remove all entries and destroy */
 +      __efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL);
 +
 +      if (efivars_new_var)
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 +      if (efivars_del_var)
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_del_var);
 +      kfree(efivars_new_var);
 +      kfree(efivars_del_var);
 +      kset_unregister(efivars_kset);
 +}
 +
 +int efivars_sysfs_init(void)
 +{
 +      struct kobject *parent_kobj = efivars_kobject();
 +      int error = 0;
 +
 +      /* No efivars has been registered yet */
 +      if (!parent_kobj)
 +              return 0;
 +
 +      printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
 +             EFIVARS_DATE);
 +
 +      efivars_kset = kset_create_and_add("vars", NULL, parent_kobj);
 +      if (!efivars_kset) {
 +              printk(KERN_ERR "efivars: Subsystem registration failed.\n");
 +              return -ENOMEM;
 +      }
 +
 +      efivar_init(efivars_sysfs_callback, NULL, false,
 +                  true, &efivar_sysfs_list);
 +
 +      error = create_efivars_bin_attributes();
 +      if (error) {
 +              efivars_sysfs_exit();
 +              return error;
 +      }
 +
 +      INIT_WORK(&efivar_work, efivar_update_sysfs_entries);
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(efivars_sysfs_init);
 +
 +module_init(efivars_sysfs_init);
 +module_exit(efivars_sysfs_exit);
Simple merge
Simple merge
@@@ -257,19 -257,16 +257,16 @@@ void cx25821_free_mem_upstream_audio(st
  }
  
  static int cx25821_get_audio_data(struct cx25821_dev *dev,
 -                         struct sram_channel *sram_ch)
 +                         const struct sram_channel *sram_ch)
  {
-       struct file *myfile;
+       struct file *file;
        int frame_index_temp = dev->_audioframe_index;
        int i = 0;
-       int line_size = AUDIO_LINE_SIZE;
        int frame_size = AUDIO_DATA_BUF_SZ;
        int frame_offset = frame_size * frame_index_temp;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
+       char mybuf[AUDIO_LINE_SIZE];
        loff_t file_offset = dev->_audioframe_count * frame_size;
-       loff_t pos;
-       mm_segment_t old_fs;
+       char *p = NULL;
  
        if (dev->_audiofile_status == END_OF_FILE)
                return 0;
@@@ -352,83 -319,43 +319,43 @@@ static void cx25821_audioups_handler(st
  }
  
  static int cx25821_openfile_audio(struct cx25821_dev *dev,
 -                         struct sram_channel *sram_ch)
 +                         const struct sram_channel *sram_ch)
  {
-       struct file *myfile;
-       int i = 0, j = 0;
-       int line_size = AUDIO_LINE_SIZE;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
-       loff_t pos;
-       loff_t offset = (unsigned long)0;
-       mm_segment_t old_fs;
-       myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
-       if (IS_ERR(myfile)) {
-               const int open_errno = -PTR_ERR(myfile);
-               pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
-                       __func__, dev->_audiofilename, open_errno);
-               return PTR_ERR(myfile);
-       } else {
-               if (!(myfile->f_op)) {
-                       pr_err("%s(): File has no file operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
+       char *p = (void *)dev->_audiodata_buf_virt_addr;
+       struct file *file;
+       loff_t offset;
+       int i, j;
+       file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+       if (IS_ERR(file)) {
+               pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n",
+                       __func__, dev->_audiofilename, PTR_ERR(file));
+               return PTR_ERR(file);
+       }
  
-               if (!myfile->f_op->read) {
-                       pr_err("%s(): File has no READ operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
+       for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) {
+               for (i = 0; i < dev->_audio_lines_count; i++) {
+                       char buf[AUDIO_LINE_SIZE];
+                       int n = kernel_read(file, offset, buf,
+                                               AUDIO_LINE_SIZE);
  
-               pos = myfile->f_pos;
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-               for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
-                       for (i = 0; i < dev->_audio_lines_count; i++) {
-                               pos = offset;
-                               vfs_read_retval = vfs_read(myfile, mybuf,
-                                               line_size, &pos);
-                               if (vfs_read_retval > 0 &&
-                                   vfs_read_retval == line_size &&
-                                   dev->_audiodata_buf_virt_addr != NULL) {
-                                       memcpy((void *)(dev->
-                                                       _audiodata_buf_virt_addr
-                                                       + offset / 4), mybuf,
-                                              vfs_read_retval);
-                               }
-                               offset += vfs_read_retval;
-                               if (vfs_read_retval < line_size) {
-                                       pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
-                                               __func__);
-                                       break;
-                               }
+                       if (n < AUDIO_LINE_SIZE) {
+                               pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+                                       __func__);
+                               dev->_audiofile_status = END_OF_FILE;
+                               fput(file);
+                               return 0;
                        }
  
-                       if (i > 0)
-                               dev->_audioframe_count++;
+                       if (p)
+                               memcpy(p + offset, buf, n);
  
-                       if (vfs_read_retval < line_size)
-                               break;
+                       offset += n;
                }
-               dev->_audiofile_status = (vfs_read_retval == line_size) ?
-                                               IN_PROGRESS : END_OF_FILE;
-               set_fs(old_fs);
-               myfile->f_pos = 0;
-               filp_close(myfile, NULL);
+               dev->_audioframe_count++;
        }
+       dev->_audiofile_status = IN_PROGRESS;
+       fput(file);
        return 0;
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -147,10 -147,9 +147,8 @@@ struct scsi_cmnd
  
  int slave_alloc(struct scsi_device *sdev);
  int slave_configure(struct scsi_device *sdev);
- int proc_info(struct Scsi_Host *host, char *buffer,
-             char **start, off_t offset, int length, int inout);
  int queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
  int command_abort(struct scsi_cmnd *srb);
 -int device_reset(struct scsi_cmnd *srb);
  int bus_reset(struct scsi_cmnd *srb);
  
  #endif /* __RTS51X_SCSI_H */
Simple merge
@@@ -2723,61 -2933,39 +2724,39 @@@ static inline u32 ether_crc(int length
  
  //2008-8-4 <add> by chester
  static int Config_FileGetParameter(unsigned char *string,
 -              unsigned char *dest, unsigned char *source)
 +                                 unsigned char *dest, unsigned char *source)
  {
 -  unsigned char buf1[100];
 -  int source_len = strlen(source);
 +      unsigned char buf1[100];
 +      int source_len = strlen(source);
  
 -    memset(buf1,0,100);
 -    strcat(buf1, string);
 -    strcat(buf1, "=");
 -    source+=strlen(buf1);
 +      memset(buf1, 0, 100);
 +      strcat(buf1, string);
 +      strcat(buf1, "=");
 +      source += strlen(buf1);
  
 -   memcpy(dest,source,source_len-strlen(buf1));
 - return true;
 +      memcpy(dest, source, source_len - strlen(buf1));
 +      return true;
  }
  
- int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter) {
-       unsigned char *config_path = CONFIG_PATH;
-       unsigned char *buffer = NULL;
+ int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter)
+ {
+       unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
        unsigned char tmpbuffer[20];
-       struct file   *filp = NULL;
-       mm_segment_t old_fs = get_fs();
-       //int oldfsuid=0,oldfsgid=0;
-       int result = 0;
-       set_fs(KERNEL_DS);
-       /* Can't do this anymore, so we rely on correct filesystem permissions:
-       //Make sure a caller can read or write power as root
-       oldfsuid=current->cred->fsuid;
-       oldfsgid=current->cred->fsgid;
-       current->cred->fsuid = 0;
-       current->cred->fsgid = 0;
-       */
-       //open file
-       filp = filp_open(config_path, O_RDWR, 0);
-       if (IS_ERR(filp)) {
-               printk("Config_FileOperation:open file fail?\n");
-               result = -1;
-               goto error2;
-       }
+       struct file *file;
+       int result=0;
  
-       if (!(filp->f_op) || !(filp->f_op->read) || !(filp->f_op->write)) {
-               printk("file %s cann't readable or writable?\n", config_path);
-               result = -1;
-               goto error1;
-       }
-       buffer = kmalloc(1024, GFP_KERNEL);
-       if (buffer == NULL) {
+       if (!buffer) {
                printk("allocate mem for file fail?\n");
-               result = -1;
-               goto error1;
+               return -1;
+       }
+       file = filp_open(CONFIG_PATH, O_RDONLY, 0);
+       if (IS_ERR(file)) {
+               kfree(buffer);
+               printk("Config_FileOperation:open file fail?\n");
+               return -1;
        }
  
-       if (filp->f_op->read(filp, buffer, 1024, &filp->f_pos) < 0) {
+       if (kernel_read(file, 0, buffer, 1024) < 0) {
                printk("read file error?\n");
                result = -1;
                goto error1;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1796,11 -1796,16 +1785,11 @@@ static int goku_probe(struct pci_dev *p
  
  
  #ifdef CONFIG_USB_GADGET_DEBUG_FILES
-       create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev);
+       proc_create_data(proc_node_name, 0, NULL, &udc_proc_fops, dev);
  #endif
  
 -      retval = device_register(&dev->gadget.dev);
 -      if (retval) {
 -              put_device(&dev->gadget.dev);
 -              goto err;
 -      }
 -      dev->registered = 1;
 -      retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
 +      retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget,
 +                      gadget_release);
        if (retval)
                goto err;
  
Simple merge
Simple merge
Simple merge
diff --cc fs/Makefile
@@@ -7,10 -7,10 +7,10 @@@
  
  obj-y :=      open.o read_write.o file_table.o super.o \
                char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
-               ioctl.o readdir.o select.o fifo.o dcache.o inode.o \
+               ioctl.o readdir.o select.o dcache.o inode.o \
                attr.o bad_inode.o file.o filesystems.o namespace.o \
                seq_file.o xattr.o libfs.o fs-writeback.o \
 -              pnode.o drop_caches.o splice.o sync.o utimes.o \
 +              pnode.o splice.o sync.o utimes.o \
                stack.o fs_struct.o statfs.o
  
  ifeq ($(CONFIG_BLOCK),y)
diff --cc fs/aio.c
Simple merge
Simple merge
Simple merge
diff --cc fs/btrfs/file.c
Simple merge
diff --cc fs/compat.c
@@@ -1068,190 -1069,26 +1068,6 @@@ asmlinkage long compat_sys_getdents64(u
  }
  #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
  
- static ssize_t compat_do_readv_writev(int type, struct file *file,
-                              const struct compat_iovec __user *uvector,
-                              unsigned long nr_segs, loff_t *pos)
- {
-       compat_ssize_t tot_len;
-       struct iovec iovstack[UIO_FASTIOV];
-       struct iovec *iov = iovstack;
-       ssize_t ret;
-       io_fn_t fn;
-       iov_fn_t fnv;
-       ret = -EINVAL;
-       if (!file->f_op)
-               goto out;
-       ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
-                                              UIO_FASTIOV, iovstack, &iov);
-       if (ret <= 0)
-               goto out;
-       tot_len = ret;
-       ret = rw_verify_area(type, file, pos, tot_len);
-       if (ret < 0)
-               goto out;
-       fnv = NULL;
-       if (type == READ) {
-               fn = file->f_op->read;
-               fnv = file->f_op->aio_read;
-       } else {
-               fn = (io_fn_t)file->f_op->write;
-               fnv = file->f_op->aio_write;
-       }
-       if (fnv)
-               ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
-                                               pos, fnv);
-       else
-               ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
- out:
-       if (iov != iovstack)
-               kfree(iov);
-       if ((ret + (type == READ)) > 0) {
-               if (type == READ)
-                       fsnotify_access(file);
-               else
-                       fsnotify_modify(file);
-       }
-       return ret;
- }
- static size_t compat_readv(struct file *file,
-                          const struct compat_iovec __user *vec,
-                          unsigned long vlen, loff_t *pos)
- {
-       ssize_t ret = -EBADF;
-       if (!(file->f_mode & FMODE_READ))
-               goto out;
-       ret = -EINVAL;
-       if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
-               goto out;
-       ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
- out:
-       if (ret > 0)
-               add_rchar(current, ret);
-       inc_syscr(current);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
-                unsigned long vlen)
- {
-       struct fd f = fdget(fd);
-       ssize_t ret;
-       loff_t pos;
-       if (!f.file)
-               return -EBADF;
-       pos = f.file->f_pos;
-       ret = compat_readv(f.file, vec, vlen, &pos);
-       f.file->f_pos = pos;
-       fdput(f);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
-                   unsigned long vlen, loff_t pos)
- {
-       struct fd f;
-       ssize_t ret;
-       if (pos < 0)
-               return -EINVAL;
-       f = fdget(fd);
-       if (!f.file)
-               return -EBADF;
-       ret = -ESPIPE;
-       if (f.file->f_mode & FMODE_PREAD)
-               ret = compat_readv(f.file, vec, vlen, &pos);
-       fdput(f);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
-                 unsigned long vlen, u32 pos_low, u32 pos_high)
- {
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
-       return compat_sys_preadv64(fd, vec, vlen, pos);
- }
- static size_t compat_writev(struct file *file,
-                           const struct compat_iovec __user *vec,
-                           unsigned long vlen, loff_t *pos)
- {
-       ssize_t ret = -EBADF;
-       if (!(file->f_mode & FMODE_WRITE))
-               goto out;
-       ret = -EINVAL;
-       if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
-               goto out;
-       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
- out:
-       if (ret > 0)
-               add_wchar(current, ret);
-       inc_syscw(current);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
-                 unsigned long vlen)
- {
-       struct fd f = fdget(fd);
-       ssize_t ret;
-       loff_t pos;
-       if (!f.file)
-               return -EBADF;
-       pos = f.file->f_pos;
-       ret = compat_writev(f.file, vec, vlen, &pos);
-       f.file->f_pos = pos;
-       fdput(f);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
-                    unsigned long vlen, loff_t pos)
- {
-       struct fd f;
-       ssize_t ret;
-       if (pos < 0)
-               return -EINVAL;
-       f = fdget(fd);
-       if (!f.file)
-               return -EBADF;
-       ret = -ESPIPE;
-       if (f.file->f_mode & FMODE_PWRITE)
-               ret = compat_writev(f.file, vec, vlen, &pos);
-       fdput(f);
-       return ret;
- }
- asmlinkage ssize_t
- compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
-                  unsigned long vlen, u32 pos_low, u32 pos_high)
- {
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
-       return compat_sys_pwritev64(fd, vec, vlen, pos);
- }
 -asmlinkage long
 -compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
 -                  unsigned int nr_segs, unsigned int flags)
 -{
 -      unsigned i;
 -      struct iovec __user *iov;
 -      if (nr_segs > UIO_MAXIOV)
 -              return -EINVAL;
 -      iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
 -      for (i = 0; i < nr_segs; i++) {
 -              struct compat_iovec v;
 -              if (get_user(v.iov_base, &iov32[i].iov_base) ||
 -                  get_user(v.iov_len, &iov32[i].iov_len) ||
 -                  put_user(compat_ptr(v.iov_base), &iov[i].iov_base) ||
 -                  put_user(v.iov_len, &iov[i].iov_len))
 -                      return -EFAULT;
 -      }
 -      return sys_vmsplice(fd, iov, nr_segs, flags);
 -}
 -
  /*
   * Exactly like fs/open.c:sys_open(), except that it doesn't set the
   * O_LARGEFILE flag.
diff --cc fs/coredump.c
@@@ -419,22 -407,9 +419,20 @@@ static void coredump_finish(struct mm_s
        mm->core_state = NULL;
  }
  
 +static bool dump_interrupted(void)
 +{
 +      /*
 +       * SIGKILL or freezing() interrupt the coredumping. Perhaps we
 +       * can do try_to_freeze() and check __fatal_signal_pending(),
 +       * but then we need to teach dump_write() to restart and clear
 +       * TIF_SIGPENDING.
 +       */
 +      return signal_pending(current);
 +}
 +
  static void wait_for_dump_helpers(struct file *file)
  {
-       struct pipe_inode_info *pipe;
-       pipe = file_inode(file)->i_pipe;
+       struct pipe_inode_info *pipe = file->private_data;
  
        pipe_lock(pipe);
        pipe->readers++;
@@@ -656,7 -627,11 +654,9 @@@ void do_coredump(siginfo_t *siginfo
                goto close_fail;
        if (displaced)
                put_files_struct(displaced);
+       file_start_write(cprm.file);
 -      retval = binfmt->core_dump(&cprm);
 -      if (retval)
 -              current->signal->group_exit_code |= 0x80;
 +      core_dumped = !dump_interrupted() && binfmt->core_dump(&cprm);
+       file_end_write(cprm.file);
  
        if (ispipe && core_pipe_limit)
                wait_for_dump_helpers(cprm.file);
index ede07fc,0000000..bfb5315
mode 100644,000000..100644
--- /dev/null
@@@ -1,105 -1,0 +1,106 @@@
 +/*
 + * Copyright (C) 2012 Red Hat, Inc.
 + * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include <linux/efi.h>
 +#include <linux/fs.h>
++#include <linux/slab.h>
 +
 +#include "internal.h"
 +
 +static ssize_t efivarfs_file_write(struct file *file,
 +              const char __user *userbuf, size_t count, loff_t *ppos)
 +{
 +      struct efivar_entry *var = file->private_data;
 +      void *data;
 +      u32 attributes;
 +      struct inode *inode = file->f_mapping->host;
 +      unsigned long datasize = count - sizeof(attributes);
 +      ssize_t bytes = 0;
 +      bool set = false;
 +
 +      if (count < sizeof(attributes))
 +              return -EINVAL;
 +
 +      if (copy_from_user(&attributes, userbuf, sizeof(attributes)))
 +              return -EFAULT;
 +
 +      if (attributes & ~(EFI_VARIABLE_MASK))
 +              return -EINVAL;
 +
 +      data = kmalloc(datasize, GFP_KERNEL);
 +      if (!data)
 +              return -ENOMEM;
 +
 +      if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
 +              bytes = -EFAULT;
 +              goto out;
 +      }
 +
 +      bytes = efivar_entry_set_get_size(var, attributes, &datasize,
 +                                        data, &set);
 +      if (!set && bytes)
 +              goto out;
 +
 +      if (bytes == -ENOENT) {
 +              drop_nlink(inode);
 +              d_delete(file->f_dentry);
 +              dput(file->f_dentry);
 +      } else {
 +              mutex_lock(&inode->i_mutex);
 +              i_size_write(inode, datasize + sizeof(attributes));
 +              mutex_unlock(&inode->i_mutex);
 +      }
 +
 +      bytes = count;
 +
 +out:
 +      kfree(data);
 +
 +      return bytes;
 +}
 +
 +static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
 +              size_t count, loff_t *ppos)
 +{
 +      struct efivar_entry *var = file->private_data;
 +      unsigned long datasize = 0;
 +      u32 attributes;
 +      void *data;
 +      ssize_t size = 0;
 +      int err;
 +
 +      err = efivar_entry_size(var, &datasize);
 +      if (err)
 +              return err;
 +
 +      data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);
 +
 +      if (!data)
 +              return -ENOMEM;
 +
 +      size = efivar_entry_get(var, &attributes, &datasize,
 +                              data + sizeof(attributes));
 +      if (size)
 +              goto out_free;
 +
 +      memcpy(data, &attributes, sizeof(attributes));
 +      size = simple_read_from_buffer(userbuf, count, ppos,
 +                                     data, datasize + sizeof(attributes));
 +out_free:
 +      kfree(data);
 +
 +      return size;
 +}
 +
 +const struct file_operations efivarfs_file_operations = {
 +      .open   = simple_open,
 +      .read   = efivarfs_file_read,
 +      .write  = efivarfs_file_write,
 +      .llseek = no_llseek,
 +};
index 640e289,0000000..7e787fb
mode 100644,000000..100644
--- /dev/null
@@@ -1,173 -1,0 +1,174 @@@
 +/*
 + * Copyright (C) 2012 Red Hat, Inc.
 + * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include <linux/efi.h>
 +#include <linux/fs.h>
 +#include <linux/ctype.h>
++#include <linux/slab.h>
 +
 +#include "internal.h"
 +
 +struct inode *efivarfs_get_inode(struct super_block *sb,
 +                              const struct inode *dir, int mode, dev_t dev)
 +{
 +      struct inode *inode = new_inode(sb);
 +
 +      if (inode) {
 +              inode->i_ino = get_next_ino();
 +              inode->i_mode = mode;
 +              inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 +              switch (mode & S_IFMT) {
 +              case S_IFREG:
 +                      inode->i_fop = &efivarfs_file_operations;
 +                      break;
 +              case S_IFDIR:
 +                      inode->i_op = &efivarfs_dir_inode_operations;
 +                      inode->i_fop = &simple_dir_operations;
 +                      inc_nlink(inode);
 +                      break;
 +              }
 +      }
 +      return inode;
 +}
 +
 +/*
 + * Return true if 'str' is a valid efivarfs filename of the form,
 + *
 + *    VariableName-12345678-1234-1234-1234-1234567891bc
 + */
 +bool efivarfs_valid_name(const char *str, int len)
 +{
 +      static const char dashes[EFI_VARIABLE_GUID_LEN] = {
 +              [8] = 1, [13] = 1, [18] = 1, [23] = 1
 +      };
 +      const char *s = str + len - EFI_VARIABLE_GUID_LEN;
 +      int i;
 +
 +      /*
 +       * We need a GUID, plus at least one letter for the variable name,
 +       * plus the '-' separator
 +       */
 +      if (len < EFI_VARIABLE_GUID_LEN + 2)
 +              return false;
 +
 +      /* GUID must be preceded by a '-' */
 +      if (*(s - 1) != '-')
 +              return false;
 +
 +      /*
 +       * Validate that 's' is of the correct format, e.g.
 +       *
 +       *      12345678-1234-1234-1234-123456789abc
 +       */
 +      for (i = 0; i < EFI_VARIABLE_GUID_LEN; i++) {
 +              if (dashes[i]) {
 +                      if (*s++ != '-')
 +                              return false;
 +              } else {
 +                      if (!isxdigit(*s++))
 +                              return false;
 +              }
 +      }
 +
 +      return true;
 +}
 +
 +static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
 +{
 +      guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]);
 +      guid->b[1] = hex_to_bin(str[4]) << 4 | hex_to_bin(str[5]);
 +      guid->b[2] = hex_to_bin(str[2]) << 4 | hex_to_bin(str[3]);
 +      guid->b[3] = hex_to_bin(str[0]) << 4 | hex_to_bin(str[1]);
 +      guid->b[4] = hex_to_bin(str[11]) << 4 | hex_to_bin(str[12]);
 +      guid->b[5] = hex_to_bin(str[9]) << 4 | hex_to_bin(str[10]);
 +      guid->b[6] = hex_to_bin(str[16]) << 4 | hex_to_bin(str[17]);
 +      guid->b[7] = hex_to_bin(str[14]) << 4 | hex_to_bin(str[15]);
 +      guid->b[8] = hex_to_bin(str[19]) << 4 | hex_to_bin(str[20]);
 +      guid->b[9] = hex_to_bin(str[21]) << 4 | hex_to_bin(str[22]);
 +      guid->b[10] = hex_to_bin(str[24]) << 4 | hex_to_bin(str[25]);
 +      guid->b[11] = hex_to_bin(str[26]) << 4 | hex_to_bin(str[27]);
 +      guid->b[12] = hex_to_bin(str[28]) << 4 | hex_to_bin(str[29]);
 +      guid->b[13] = hex_to_bin(str[30]) << 4 | hex_to_bin(str[31]);
 +      guid->b[14] = hex_to_bin(str[32]) << 4 | hex_to_bin(str[33]);
 +      guid->b[15] = hex_to_bin(str[34]) << 4 | hex_to_bin(str[35]);
 +}
 +
 +static int efivarfs_create(struct inode *dir, struct dentry *dentry,
 +                        umode_t mode, bool excl)
 +{
 +      struct inode *inode;
 +      struct efivar_entry *var;
 +      int namelen, i = 0, err = 0;
 +
 +      if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
 +              return -EINVAL;
 +
 +      inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
 +      if (!inode)
 +              return -ENOMEM;
 +
 +      var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
 +      if (!var) {
 +              err = -ENOMEM;
 +              goto out;
 +      }
 +
 +      /* length of the variable name itself: remove GUID and separator */
 +      namelen = dentry->d_name.len - EFI_VARIABLE_GUID_LEN - 1;
 +
 +      efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
 +                      &var->var.VendorGuid);
 +
 +      for (i = 0; i < namelen; i++)
 +              var->var.VariableName[i] = dentry->d_name.name[i];
 +
 +      var->var.VariableName[i] = '\0';
 +
 +      inode->i_private = var;
 +
 +      efivar_entry_add(var, &efivarfs_list);
 +      d_instantiate(dentry, inode);
 +      dget(dentry);
 +out:
 +      if (err) {
 +              kfree(var);
 +              iput(inode);
 +      }
 +      return err;
 +}
 +
 +static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
 +{
 +      struct efivar_entry *var = dentry->d_inode->i_private;
 +
 +      if (efivar_entry_delete(var))
 +              return -EINVAL;
 +
 +      drop_nlink(dentry->d_inode);
 +      dput(dentry);
 +      return 0;
 +};
 +
 +/*
 + * Handle negative dentry.
 + */
 +static struct dentry *efivarfs_lookup(struct inode *dir, struct dentry *dentry,
 +                                    unsigned int flags)
 +{
 +      if (dentry->d_name.len > NAME_MAX)
 +              return ERR_PTR(-ENAMETOOLONG);
 +      d_add(dentry, NULL);
 +      return NULL;
 +}
 +
 +const struct inode_operations efivarfs_dir_inode_operations = {
 +      .lookup = efivarfs_lookup,
 +      .unlink = efivarfs_unlink,
 +      .create = efivarfs_create,
 +};
index 525a2a1,0000000..141aee3
mode 100644,000000..100644
--- /dev/null
@@@ -1,268 -1,0 +1,270 @@@
 +/*
 + * Copyright (C) 2012 Red Hat, Inc.
 + * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include <linux/ctype.h>
 +#include <linux/efi.h>
 +#include <linux/fs.h>
 +#include <linux/module.h>
 +#include <linux/pagemap.h>
 +#include <linux/ucs2_string.h>
++#include <linux/slab.h>
++#include <linux/magic.h>
 +
 +#include "internal.h"
 +
 +LIST_HEAD(efivarfs_list);
 +
 +static void efivarfs_evict_inode(struct inode *inode)
 +{
 +      clear_inode(inode);
 +}
 +
 +static const struct super_operations efivarfs_ops = {
 +      .statfs = simple_statfs,
 +      .drop_inode = generic_delete_inode,
 +      .evict_inode = efivarfs_evict_inode,
 +      .show_options = generic_show_options,
 +};
 +
 +static struct super_block *efivarfs_sb;
 +
 +/*
 + * Compare two efivarfs file names.
 + *
 + * An efivarfs filename is composed of two parts,
 + *
 + *    1. A case-sensitive variable name
 + *    2. A case-insensitive GUID
 + *
 + * So we need to perform a case-sensitive match on part 1 and a
 + * case-insensitive match on part 2.
 + */
 +static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode,
 +                            const struct dentry *dentry, const struct inode *inode,
 +                            unsigned int len, const char *str,
 +                            const struct qstr *name)
 +{
 +      int guid = len - EFI_VARIABLE_GUID_LEN;
 +
 +      if (name->len != len)
 +              return 1;
 +
 +      /* Case-sensitive compare for the variable name */
 +      if (memcmp(str, name->name, guid))
 +              return 1;
 +
 +      /* Case-insensitive compare for the GUID */
 +      return strncasecmp(name->name + guid, str + guid, EFI_VARIABLE_GUID_LEN);
 +}
 +
 +static int efivarfs_d_hash(const struct dentry *dentry,
 +                         const struct inode *inode, struct qstr *qstr)
 +{
 +      unsigned long hash = init_name_hash();
 +      const unsigned char *s = qstr->name;
 +      unsigned int len = qstr->len;
 +
 +      if (!efivarfs_valid_name(s, len))
 +              return -EINVAL;
 +
 +      while (len-- > EFI_VARIABLE_GUID_LEN)
 +              hash = partial_name_hash(*s++, hash);
 +
 +      /* GUID is case-insensitive. */
 +      while (len--)
 +              hash = partial_name_hash(tolower(*s++), hash);
 +
 +      qstr->hash = end_name_hash(hash);
 +      return 0;
 +}
 +
 +/*
 + * Retaining negative dentries for an in-memory filesystem just wastes
 + * memory and lookup time: arrange for them to be deleted immediately.
 + */
 +static int efivarfs_delete_dentry(const struct dentry *dentry)
 +{
 +      return 1;
 +}
 +
 +static struct dentry_operations efivarfs_d_ops = {
 +      .d_compare = efivarfs_d_compare,
 +      .d_hash = efivarfs_d_hash,
 +      .d_delete = efivarfs_delete_dentry,
 +};
 +
 +static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
 +{
 +      struct dentry *d;
 +      struct qstr q;
 +      int err;
 +
 +      q.name = name;
 +      q.len = strlen(name);
 +
 +      err = efivarfs_d_hash(NULL, NULL, &q);
 +      if (err)
 +              return ERR_PTR(err);
 +
 +      d = d_alloc(parent, &q);
 +      if (d)
 +              return d;
 +
 +      return ERR_PTR(-ENOMEM);
 +}
 +
 +static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
 +                           unsigned long name_size, void *data)
 +{
 +      struct super_block *sb = (struct super_block *)data;
 +      struct efivar_entry *entry;
 +      struct inode *inode = NULL;
 +      struct dentry *dentry, *root = sb->s_root;
 +      unsigned long size = 0;
 +      char *name;
 +      int len, i;
 +      int err = -ENOMEM;
 +
 +      entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry)
 +              return err;
 +
 +      memcpy(entry->var.VariableName, name16, name_size);
 +      memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 +
 +      len = ucs2_strlen(entry->var.VariableName);
 +
 +      /* name, plus '-', plus GUID, plus NUL*/
 +      name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
 +      if (!name)
 +              goto fail;
 +
 +      for (i = 0; i < len; i++)
 +              name[i] = entry->var.VariableName[i] & 0xFF;
 +
 +      name[len] = '-';
 +
 +      efi_guid_unparse(&entry->var.VendorGuid, name + len + 1);
 +
 +      name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
 +
 +      inode = efivarfs_get_inode(sb, root->d_inode, S_IFREG | 0644, 0);
 +      if (!inode)
 +              goto fail_name;
 +
 +      dentry = efivarfs_alloc_dentry(root, name);
 +      if (IS_ERR(dentry)) {
 +              err = PTR_ERR(dentry);
 +              goto fail_inode;
 +      }
 +
 +      /* copied by the above to local storage in the dentry. */
 +      kfree(name);
 +
 +      efivar_entry_size(entry, &size);
 +      efivar_entry_add(entry, &efivarfs_list);
 +
 +      mutex_lock(&inode->i_mutex);
 +      inode->i_private = entry;
 +      i_size_write(inode, size + sizeof(entry->var.Attributes));
 +      mutex_unlock(&inode->i_mutex);
 +      d_add(dentry, inode);
 +
 +      return 0;
 +
 +fail_inode:
 +      iput(inode);
 +fail_name:
 +      kfree(name);
 +fail:
 +      kfree(entry);
 +      return err;
 +}
 +
 +static int efivarfs_destroy(struct efivar_entry *entry, void *data)
 +{
 +      efivar_entry_remove(entry);
 +      kfree(entry);
 +      return 0;
 +}
 +
 +static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
 +{
 +      struct inode *inode = NULL;
 +      struct dentry *root;
 +      int err;
 +
 +      efivarfs_sb = sb;
 +
 +      sb->s_maxbytes          = MAX_LFS_FILESIZE;
 +      sb->s_blocksize         = PAGE_CACHE_SIZE;
 +      sb->s_blocksize_bits    = PAGE_CACHE_SHIFT;
 +      sb->s_magic             = EFIVARFS_MAGIC;
 +      sb->s_op                = &efivarfs_ops;
 +      sb->s_d_op              = &efivarfs_d_ops;
 +      sb->s_time_gran         = 1;
 +
 +      inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
 +      if (!inode)
 +              return -ENOMEM;
 +      inode->i_op = &efivarfs_dir_inode_operations;
 +
 +      root = d_make_root(inode);
 +      sb->s_root = root;
 +      if (!root)
 +              return -ENOMEM;
 +
 +      INIT_LIST_HEAD(&efivarfs_list);
 +
 +      err = efivar_init(efivarfs_callback, (void *)sb, false,
 +                        true, &efivarfs_list);
 +      if (err)
 +              __efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL, NULL);
 +
 +      return err;
 +}
 +
 +static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
 +                                  int flags, const char *dev_name, void *data)
 +{
 +      return mount_single(fs_type, flags, data, efivarfs_fill_super);
 +}
 +
 +static void efivarfs_kill_sb(struct super_block *sb)
 +{
 +      kill_litter_super(sb);
 +      efivarfs_sb = NULL;
 +
 +      /* Remove all entries and destroy */
 +      __efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL, NULL);
 +}
 +
 +static struct file_system_type efivarfs_type = {
 +      .name    = "efivarfs",
 +      .mount   = efivarfs_mount,
 +      .kill_sb = efivarfs_kill_sb,
 +};
 +
 +static __init int efivarfs_init(void)
 +{
 +      if (!efi_enabled(EFI_RUNTIME_SERVICES))
 +              return 0;
 +
 +      if (!efivars_kobject())
 +              return 0;
 +
 +      return register_filesystem(&efivarfs_type);
 +}
 +
 +MODULE_AUTHOR("Matthew Garrett, Jeremy Kerr");
 +MODULE_DESCRIPTION("EFI Variable Filesystem");
 +MODULE_LICENSE("GPL");
 +MODULE_ALIAS_FS("efivarfs");
 +
 +module_init(efivarfs_init);
diff --cc fs/exec.c
Simple merge
Simple merge
diff --cc fs/ext4/super.c
Simple merge
diff --cc fs/inode.c
Simple merge
Simple merge
diff --cc fs/namespace.c
@@@ -21,7 -21,7 +21,8 @@@
  #include <linux/fs_struct.h>  /* get_fs_root et.al. */
  #include <linux/fsnotify.h>   /* fsnotify_vfsmount_delete */
  #include <linux/uaccess.h>
- #include <linux/proc_fs.h>
+ #include <linux/proc_ns.h>
++#include <linux/magic.h>
  #include "pnode.h"
  #include "internal.h"
  
@@@ -2346,10 -2384,10 +2392,10 @@@ static struct mnt_namespace *dup_mnt_ns
        /* First pass: copy the tree topology */
        copy_flags = CL_COPY_ALL | CL_EXPIRE;
        if (user_ns != mnt_ns->user_ns)
 -              copy_flags |= CL_SHARED_TO_SLAVE;
 +              copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED;
        new = copy_tree(old, old->mnt.mnt_root, copy_flags);
        if (IS_ERR(new)) {
-               up_write(&namespace_sem);
+               namespace_unlock();
                free_mnt_ns(new_ns);
                return ERR_CAST(new);
        }
Simple merge
diff --cc fs/pnode.c
@@@ -218,10 -217,9 +218,10 @@@ static struct mount *get_source(struct 
   * @source_mnt: source mount.
   * @tree_list : list of heads of trees to be attached.
   */
- int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
+ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
                    struct mount *source_mnt, struct list_head *tree_list)
  {
 +      struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
        struct mount *m, *child;
        int ret = 0;
        struct mount *prev_dest_mnt = dest_mnt;
diff --cc fs/pnode.h
Simple merge
diff --cc fs/proc/base.c
Simple merge
@@@ -154,36 -191,56 +191,35 @@@ static inline struct proc_dir_entry *pd
        atomic_inc(&pde->count);
        return pde;
  }
- void pde_put(struct proc_dir_entry *pde);
- int proc_fill_super(struct super_block *);
- struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
- int proc_remount(struct super_block *sb, int *flags, char *data);
+ extern void pde_put(struct proc_dir_entry *);
  
  /*
-  * These are generic /proc routines that use the internal
-  * "struct proc_dir_entry" tree to traverse the filesystem.
-  *
-  * The /proc root directory has extended versions to take care
-  * of the /proc/<pid> subdirectories.
+  * inode.c
   */
- int proc_readdir(struct file *, void *, filldir_t);
- struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
+ struct pde_opener {
+       struct file *file;
+       struct list_head lh;
+       int closing;
+       struct completion *c;
+ };
  
+ extern const struct inode_operations proc_pid_link_inode_operations;
  
+ extern void proc_init_inodecache(void);
+ extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
+ extern int proc_fill_super(struct super_block *);
+ extern void proc_entry_rundown(struct proc_dir_entry *);
  
- /* Lookups */
- typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
-                               struct task_struct *, const void *);
- int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-       const char *name, int len,
-       instantiate_t instantiate, struct task_struct *task, const void *ptr);
- int pid_revalidate(struct dentry *dentry, unsigned int flags);
- struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task);
- extern const struct dentry_operations pid_dentry_operations;
- int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
- int proc_setattr(struct dentry *dentry, struct iattr *attr);
+ /*
 - * mmu.c
 - */
 -struct vmalloc_info {
 -      unsigned long   used;
 -      unsigned long   largest_chunk;
 -};
 -
 -#ifdef CONFIG_MMU
 -#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
 -extern void get_vmalloc_info(struct vmalloc_info *);
 -
 -#else
 -#define VMALLOC_TOTAL 0UL
 -static inline void get_vmalloc_info(struct vmalloc_info *vmi)
 -{
 -      vmi->used = 0;
 -      vmi->largest_chunk = 0;
 -}
 -#endif
 -
 -/*
+  * proc_devtree.c
+  */
+ #ifdef CONFIG_PROC_DEVICETREE
+ extern void proc_device_tree_init(void);
+ #endif
  
+ /*
+  * proc_namespaces.c
+  */
  extern const struct inode_operations proc_ns_dir_inode_operations;
  extern const struct file_operations proc_ns_dir_operations;
  
diff --cc fs/proc/kcore.c
Simple merge
diff --cc fs/proc/root.c
Simple merge
diff --cc fs/read_write.c
@@@ -881,8 -900,203 +887,203 @@@ SYSCALL_DEFINE5(pwritev, unsigned long
        return ret;
  }
  
+ #ifdef CONFIG_COMPAT
+ static ssize_t compat_do_readv_writev(int type, struct file *file,
+                              const struct compat_iovec __user *uvector,
+                              unsigned long nr_segs, loff_t *pos)
+ {
+       compat_ssize_t tot_len;
+       struct iovec iovstack[UIO_FASTIOV];
+       struct iovec *iov = iovstack;
+       ssize_t ret;
+       io_fn_t fn;
+       iov_fn_t fnv;
+       ret = -EINVAL;
+       if (!file->f_op)
+               goto out;
+       ret = -EFAULT;
+       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+               goto out;
+       ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+                                              UIO_FASTIOV, iovstack, &iov);
+       if (ret <= 0)
+               goto out;
+       tot_len = ret;
+       ret = rw_verify_area(type, file, pos, tot_len);
+       if (ret < 0)
+               goto out;
+       fnv = NULL;
+       if (type == READ) {
+               fn = file->f_op->read;
+               fnv = file->f_op->aio_read;
+       } else {
+               fn = (io_fn_t)file->f_op->write;
+               fnv = file->f_op->aio_write;
+               file_start_write(file);
+       }
+       if (fnv)
+               ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
+                                               pos, fnv);
+       else
+               ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
+       if (type != READ)
+               file_end_write(file);
+ out:
+       if (iov != iovstack)
+               kfree(iov);
+       if ((ret + (type == READ)) > 0) {
+               if (type == READ)
+                       fsnotify_access(file);
+               else
+                       fsnotify_modify(file);
+       }
+       return ret;
+ }
+ static size_t compat_readv(struct file *file,
+                          const struct compat_iovec __user *vec,
+                          unsigned long vlen, loff_t *pos)
+ {
+       ssize_t ret = -EBADF;
+       if (!(file->f_mode & FMODE_READ))
+               goto out;
+       ret = -EINVAL;
+       if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
+               goto out;
+       ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
+ out:
+       if (ret > 0)
+               add_rchar(current, ret);
+       inc_syscr(current);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen)
+ {
+       struct fd f = fdget(fd);
+       ssize_t ret;
+       loff_t pos;
+       if (!f.file)
+               return -EBADF;
+       pos = f.file->f_pos;
+       ret = compat_readv(f.file, vec, vlen, &pos);
+       f.file->f_pos = pos;
+       fdput(f);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, loff_t, pos)
+ {
+       struct fd f;
+       ssize_t ret;
+       if (pos < 0)
+               return -EINVAL;
+       f = fdget(fd);
+       if (!f.file)
+               return -EBADF;
+       ret = -ESPIPE;
+       if (f.file->f_mode & FMODE_PREAD)
+               ret = compat_readv(f.file, vec, vlen, &pos);
+       fdput(f);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, u32, pos_low, u32, pos_high)
+ {
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_preadv64(fd, vec, vlen, pos);
+ }
+ static size_t compat_writev(struct file *file,
+                           const struct compat_iovec __user *vec,
+                           unsigned long vlen, loff_t *pos)
+ {
+       ssize_t ret = -EBADF;
+       if (!(file->f_mode & FMODE_WRITE))
+               goto out;
+       ret = -EINVAL;
+       if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
+               goto out;
+       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
+ out:
+       if (ret > 0)
+               add_wchar(current, ret);
+       inc_syscw(current);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd,
+               const struct compat_iovec __user *, vec,
+               unsigned long, vlen)
+ {
+       struct fd f = fdget(fd);
+       ssize_t ret;
+       loff_t pos;
+       if (!f.file)
+               return -EBADF;
+       pos = f.file->f_pos;
+       ret = compat_writev(f.file, vec, vlen, &pos);
+       f.file->f_pos = pos;
+       fdput(f);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, loff_t, pos)
+ {
+       struct fd f;
+       ssize_t ret;
+       if (pos < 0)
+               return -EINVAL;
+       f = fdget(fd);
+       if (!f.file)
+               return -EBADF;
+       ret = -ESPIPE;
+       if (f.file->f_mode & FMODE_PWRITE)
+               ret = compat_writev(f.file, vec, vlen, &pos);
+       fdput(f);
+       return ret;
+ }
+ COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, u32, pos_low, u32, pos_high)
+ {
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_pwritev64(fd, vec, vlen, pos);
+ }
+ #endif
 -ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
 -                  loff_t max)
 +static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
 +                         size_t count, loff_t max)
  {
        struct fd in, out;
        struct inode *in_inode, *out_inode;
diff --cc fs/read_write.h
@@@ -7,8 -7,6 +7,3 @@@
  typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
  typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
                unsigned long, loff_t);
--
- ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
-               unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
- ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
-               unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
 -ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
 -                  loff_t max);
diff --cc fs/splice.c
Simple merge
@@@ -39,27 -42,16 +39,27 @@@ extern int cgroupstats_build(struct cgr
  extern int cgroup_load_subsys(struct cgroup_subsys *ss);
  extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
  
- extern const struct file_operations proc_cgroup_operations;
+ extern int proc_cgroup_show(struct seq_file *, void *);
  
 -/* Define the enumeration of all builtin cgroup subsystems */
 +/*
 + * Define the enumeration of all cgroup subsystems.
 + *
 + * We define ids for builtin subsystems and then modular ones.
 + */
  #define SUBSYS(_x) _x ## _subsys_id,
 -#define IS_SUBSYS_ENABLED(option) IS_ENABLED(option)
  enum cgroup_subsys_id {
 +#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
  #include <linux/cgroup_subsys.h>
 +#undef IS_SUBSYS_ENABLED
 +      CGROUP_BUILTIN_SUBSYS_COUNT,
 +
 +      __CGROUP_SUBSYS_TEMP_PLACEHOLDER = CGROUP_BUILTIN_SUBSYS_COUNT - 1,
 +
 +#define IS_SUBSYS_ENABLED(option) IS_MODULE(option)
 +#include <linux/cgroup_subsys.h>
 +#undef IS_SUBSYS_ENABLED
        CGROUP_SUBSYS_COUNT,
  };
 -#undef IS_SUBSYS_ENABLED
  #undef SUBSYS
  
  /* Per-subsystem/per-cgroup state maintained by the system. */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc ipc/msgutil.c
@@@ -16,8 -16,8 +16,8 @@@
  #include <linux/msg.h>
  #include <linux/ipc_namespace.h>
  #include <linux/utsname.h>
- #include <linux/proc_fs.h>
+ #include <linux/proc_ns.h>
 -#include <asm/uaccess.h>
 +#include <linux/uaccess.h>
  
  #include "util.h"
  
diff --cc ipc/util.c
Simple merge
diff --cc kernel/cgroup.c
Simple merge
diff --cc kernel/cpuset.c
Simple merge
diff --cc kernel/exit.c
Simple merge
diff --cc kernel/pid.c
Simple merge
Simple merge
diff --cc kernel/user.c
Simple merge
Simple merge
diff --cc mm/filemap.c
Simple merge
diff --cc mm/vmalloc.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc net/ipv4/udp.c
Simple merge
diff --cc net/ipv6/proc.c
Simple merge
Simple merge
Simple merge
diff --cc net/socket.c
Simple merge
Simple merge