Commit 08615d7d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (Andrew's patch-bomb)

Merge misc patches from Andrew Morton:

 - the "misc" tree - stuff from all over the map

 - checkpatch updates

 - fatfs

 - kmod changes

 - procfs

 - cpumask

 - UML

 - kexec

 - mqueue

 - rapidio

 - pidns

 - some checkpoint-restore feature work.  Reluctantly.  Most of it
   delayed a release.  I'm still rather worried that we don't have a
   clear roadmap to completion for this work.

* emailed from Andrew Morton <akpm@linux-foundation.org>: (78 patches)
  kconfig: update compression algorithm info
  c/r: prctl: add ability to set new mm_struct::exe_file
  c/r: prctl: extend PR_SET_MM to set up more mm_struct entries
  c/r: procfs: add arg_start/end, env_start/end and exit_code members to /proc/$pid/stat
  syscalls, x86: add __NR_kcmp syscall
  fs, proc: introduce /proc/<pid>/task/<tid>/children entry
  sysctl: make kernel.ns_last_pid control dependent on CHECKPOINT_RESTORE
  aio/vfs: cleanup of rw_copy_check_uvector() and compat_rw_copy_check_uvector()
  eventfd: change int to __u64 in eventfd_signal()
  fs/nls: add Apple NLS
  pidns: make killed children autoreap
  pidns: use task_active_pid_ns in do_notify_parent
  rapidio/tsi721: add DMA engine support
  rapidio: add DMA engine support for RIO data transfers
  ipc/mqueue: add rbtree node caching support
  tools/selftests: add mq_perf_tests
  ipc/mqueue: strengthen checks on mqueue creation
  ipc/mqueue: correct mq_attr_ok test
  ipc/mqueue: improve performance of send/recv
  selftests: add mq_open_tests
  ...
parents 9fdadb2c 0a4dd35c
...@@ -113,3 +113,5 @@ Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> ...@@ -113,3 +113,5 @@ Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Takashi YOSHII <takashi.yoshii.zj@renesas.com> Takashi YOSHII <takashi.yoshii.zj@renesas.com>
Yusuke Goda <goda.yusuke@renesas.com> Yusuke Goda <goda.yusuke@renesas.com>
Gustavo Padovan <gustavo@las.ic.unicamp.br>
Gustavo Padovan <padovan@profusion.mobi>
...@@ -671,8 +671,9 @@ ones already enabled by DEBUG. ...@@ -671,8 +671,9 @@ ones already enabled by DEBUG.
Chapter 14: Allocating memory Chapter 14: Allocating memory
The kernel provides the following general purpose memory allocators: The kernel provides the following general purpose memory allocators:
kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc(). Please refer to kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), and
the API documentation for further information about them. vzalloc(). Please refer to the API documentation for further information
about them.
The preferred form for passing a size of a struct is the following: The preferred form for passing a size of a struct is the following:
...@@ -686,6 +687,17 @@ Casting the return value which is a void pointer is redundant. The conversion ...@@ -686,6 +687,17 @@ Casting the return value which is a void pointer is redundant. The conversion
from void pointer to any other pointer type is guaranteed by the C programming from void pointer to any other pointer type is guaranteed by the C programming
language. language.
The preferred form for allocating an array is the following:
p = kmalloc_array(n, sizeof(...), ...);
The preferred form for allocating a zeroed array is the following:
p = kcalloc(n, sizeof(...), ...);
Both forms check for overflow on the allocation size n * sizeof(...),
and return NULL if that occurred.
Chapter 15: The inline disease Chapter 15: The inline disease
......
...@@ -40,6 +40,7 @@ Table of Contents ...@@ -40,6 +40,7 @@ Table of Contents
3.4 /proc/<pid>/coredump_filter - Core dump filtering settings 3.4 /proc/<pid>/coredump_filter - Core dump filtering settings
3.5 /proc/<pid>/mountinfo - Information about mounts 3.5 /proc/<pid>/mountinfo - Information about mounts
3.6 /proc/<pid>/comm & /proc/<pid>/task/<tid>/comm 3.6 /proc/<pid>/comm & /proc/<pid>/task/<tid>/comm
3.7 /proc/<pid>/task/<tid>/children - Information about task children
4 Configuring procfs 4 Configuring procfs
4.1 Mount options 4.1 Mount options
...@@ -310,6 +311,11 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7) ...@@ -310,6 +311,11 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
start_data address above which program data+bss is placed start_data address above which program data+bss is placed
end_data address below which program data+bss is placed end_data address below which program data+bss is placed
start_brk address above which program heap can be expanded with brk() start_brk address above which program heap can be expanded with brk()
arg_start address above which program command line is placed
arg_end address below which program command line is placed
env_start address above which program environment is placed
env_end address below which program environment is placed
exit_code the thread's exit_code in the form reported by the waitpid system call
.............................................................................. ..............................................................................
The /proc/PID/maps file containing the currently mapped memory regions and The /proc/PID/maps file containing the currently mapped memory regions and
...@@ -1578,6 +1584,23 @@ then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated ...@@ -1578,6 +1584,23 @@ then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
comm value. comm value.
3.7 /proc/<pid>/task/<tid>/children - Information about task children
-------------------------------------------------------------------------
This file provides a fast way to retrieve first level children pids
of a task pointed by <pid>/<tid> pair. The format is a space separated
stream of pids.
Note the "first level" here -- if a child has own children they will
not be listed here, one needs to read /proc/<children-pid>/task/<tid>/children
to obtain the descendants.
Since this interface is intended to be fast and cheap it doesn't
guarantee to provide precise results and some children might be
skipped, especially if they've exited right after we printed their
pids, so one need to either stop or freeze processes being inspected
if precise results are needed.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Configuring procfs Configuring procfs
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
......
...@@ -225,6 +225,13 @@ a queue must be less or equal then msg_max. ...@@ -225,6 +225,13 @@ a queue must be less or equal then msg_max.
maximum message size value (it is every message queue's attribute set during maximum message size value (it is every message queue's attribute set during
its creation). its creation).
/proc/sys/fs/mqueue/msg_default is a read/write file for setting/getting the
default number of messages in a queue value if attr parameter of mq_open(2) is
NULL. If it exceed msg_max, the default value is initialized msg_max.
/proc/sys/fs/mqueue/msgsize_default is a read/write file for setting/getting
the default message size value if attr parameter of mq_open(2) is NULL. If it
exceed msgsize_max, the default value is initialized msgsize_max.
4. /proc/sys/fs/epoll - Configuration options for the epoll interface 4. /proc/sys/fs/epoll - Configuration options for the epoll interface
-------------------------------------------------------- --------------------------------------------------------
......
...@@ -16,7 +16,7 @@ There are three components to pagemap: ...@@ -16,7 +16,7 @@ There are three components to pagemap:
* Bits 0-4 swap type if swapped * Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped * Bits 5-54 swap offset if swapped
* Bits 55-60 page shift (page size = 1<<page shift) * Bits 55-60 page shift (page size = 1<<page shift)
* Bit 61 reserved for future use * Bit 61 page is file-page or shared-anon
* Bit 62 page swapped * Bit 62 page swapped
* Bit 63 page present * Bit 63 page present
......
...@@ -109,7 +109,6 @@ static void percpu_timer_stop(void); ...@@ -109,7 +109,6 @@ static void percpu_timer_stop(void);
int __cpu_disable(void) int __cpu_disable(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct task_struct *p;
int ret; int ret;
ret = platform_cpu_disable(cpu); ret = platform_cpu_disable(cpu);
...@@ -139,12 +138,7 @@ int __cpu_disable(void) ...@@ -139,12 +138,7 @@ int __cpu_disable(void)
flush_cache_all(); flush_cache_all();
local_flush_tlb_all(); local_flush_tlb_all();
read_lock(&tasklist_lock); clear_tasks_mm_cpumask(cpu);
for_each_process(p) {
if (p->mm)
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
}
read_unlock(&tasklist_lock);
return 0; return 0;
} }
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/oom.h>
#include <linux/sched.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
...@@ -27,8 +29,7 @@ void decode_address(char *buf, unsigned long address) ...@@ -27,8 +29,7 @@ void decode_address(char *buf, unsigned long address)
{ {
struct task_struct *p; struct task_struct *p;
struct mm_struct *mm; struct mm_struct *mm;
unsigned long flags, offset; unsigned long offset;
unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
struct rb_node *n; struct rb_node *n;
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
...@@ -112,17 +113,17 @@ void decode_address(char *buf, unsigned long address) ...@@ -112,17 +113,17 @@ void decode_address(char *buf, unsigned long address)
* mappings of all our processes and see if we can't be a whee * mappings of all our processes and see if we can't be a whee
* bit more specific * bit more specific
*/ */
write_lock_irqsave(&tasklist_lock, flags); read_lock(&tasklist_lock);
for_each_process(p) { for_each_process(p) {
mm = (in_atomic ? p->mm : get_task_mm(p)); struct task_struct *t;
if (!mm)
continue;
if (!down_read_trylock(&mm->mmap_sem)) { t = find_lock_task_mm(p);
if (!in_atomic) if (!t)
mmput(mm);
continue; continue;
}
mm = t->mm;
if (!down_read_trylock(&mm->mmap_sem))
goto __continue;
for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
struct vm_area_struct *vma; struct vm_area_struct *vma;
...@@ -131,7 +132,7 @@ void decode_address(char *buf, unsigned long address) ...@@ -131,7 +132,7 @@ void decode_address(char *buf, unsigned long address)
if (address >= vma->vm_start && address < vma->vm_end) { if (address >= vma->vm_start && address < vma->vm_end) {
char _tmpbuf[256]; char _tmpbuf[256];
char *name = p->comm; char *name = t->comm;
struct file *file = vma->vm_file; struct file *file = vma->vm_file;
if (file) { if (file) {
...@@ -164,8 +165,7 @@ void decode_address(char *buf, unsigned long address) ...@@ -164,8 +165,7 @@ void decode_address(char *buf, unsigned long address)
name, vma->vm_start, vma->vm_end); name, vma->vm_start, vma->vm_end);
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (!in_atomic) task_unlock(t);
mmput(mm);
if (buf[0] == '\0') if (buf[0] == '\0')
sprintf(buf, "[ %s ] dynamic memory", name); sprintf(buf, "[ %s ] dynamic memory", name);
...@@ -175,8 +175,8 @@ void decode_address(char *buf, unsigned long address) ...@@ -175,8 +175,8 @@ void decode_address(char *buf, unsigned long address)
} }
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (!in_atomic) __continue:
mmput(mm); task_unlock(t);
} }
/* /*
...@@ -186,7 +186,7 @@ void decode_address(char *buf, unsigned long address) ...@@ -186,7 +186,7 @@ void decode_address(char *buf, unsigned long address)
sprintf(buf, "/* kernel dynamic memory */"); sprintf(buf, "/* kernel dynamic memory */");
done: done:
write_unlock_irqrestore(&tasklist_lock, flags); read_unlock(&tasklist_lock);
} }
#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
......
...@@ -333,9 +333,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, ...@@ -333,9 +333,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu) unsigned long action, void *hcpu)
{ {
unsigned int cpu = (unsigned int)(long)hcpu; unsigned int cpu = (unsigned int)(long)hcpu;
#ifdef CONFIG_HOTPLUG_CPU
struct task_struct *p;
#endif
/* We don't touch CPU 0 map, it's allocated at aboot and kept /* We don't touch CPU 0 map, it's allocated at aboot and kept
* around forever * around forever
*/ */
...@@ -358,12 +356,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, ...@@ -358,12 +356,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
stale_map[cpu] = NULL; stale_map[cpu] = NULL;
/* We also clear the cpu_vm_mask bits of CPUs going away */ /* We also clear the cpu_vm_mask bits of CPUs going away */
read_lock(&tasklist_lock); clear_tasks_mm_cpumask(cpu);
for_each_process(p) {
if (p->mm)
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
}
read_unlock(&tasklist_lock);
break; break;
#endif /* CONFIG_HOTPLUG_CPU */ #endif /* CONFIG_HOTPLUG_CPU */
} }
......
...@@ -123,7 +123,6 @@ void native_play_dead(void) ...@@ -123,7 +123,6 @@ void native_play_dead(void)
int __cpu_disable(void) int __cpu_disable(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct task_struct *p;
int ret; int ret;
ret = mp_ops->cpu_disable(cpu); ret = mp_ops->cpu_disable(cpu);
...@@ -153,11 +152,7 @@ int __cpu_disable(void) ...@@ -153,11 +152,7 @@ int __cpu_disable(void)
flush_cache_all(); flush_cache_all();
local_flush_tlb_all(); local_flush_tlb_all();
read_lock(&tasklist_lock); clear_tasks_mm_cpumask(cpu);
for_each_process(p)
if (p->mm)
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
read_unlock(&tasklist_lock);
return 0; return 0;
} }
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
*/ */
#include "linux/sched.h" #include "linux/sched.h"
#include "linux/spinlock.h"
#include "linux/slab.h" #include "linux/slab.h"
#include "linux/oom.h"
#include "kern_util.h" #include "kern_util.h"
#include "os.h" #include "os.h"
#include "skas.h" #include "skas.h"
...@@ -22,13 +24,18 @@ static void kill_off_processes(void) ...@@ -22,13 +24,18 @@ static void kill_off_processes(void)
struct task_struct *p; struct task_struct *p;
int pid; int pid;
read_lock(&tasklist_lock);
for_each_process(p) { for_each_process(p) {
if (p->mm == NULL) struct task_struct *t;
continue;
pid = p->mm->context.id.u.pid; t = find_lock_task_mm(p);
if (!t)
continue;
pid = t->mm->context.id.u.pid;
task_unlock(t);
os_kill_ptraced_process(pid, 1); os_kill_ptraced_process(pid, 1);
} }
read_unlock(&tasklist_lock);
} }
} }
......
...@@ -30,6 +30,8 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -30,6 +30,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
int err = -EFAULT; int err = -EFAULT;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
(is_write ? FAULT_FLAG_WRITE : 0);
*code_out = SEGV_MAPERR; *code_out = SEGV_MAPERR;
...@@ -40,6 +42,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -40,6 +42,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
if (in_atomic()) if (in_atomic())
goto out_nosemaphore; goto out_nosemaphore;
retry:
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
vma = find_vma(mm, address); vma = find_vma(mm, address);
if (!vma) if (!vma)
...@@ -65,7 +68,11 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -65,7 +68,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
do { do {
int fault; int fault;
fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); fault = handle_mm_fault(mm, vma, address, flags);
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
goto out_nosemaphore;
if (unlikely(fault & VM_FAULT_ERROR)) { if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM) { if (fault & VM_FAULT_OOM) {
goto out_of_memory; goto out_of_memory;
...@@ -75,10 +82,17 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -75,10 +82,17 @@ int handle_page_fault(unsigned long address, unsigned long ip,
} }
BUG(); BUG();
} }
if (fault & VM_FAULT_MAJOR) if (flags & FAULT_FLAG_ALLOW_RETRY) {
current->maj_flt++; if (fault & VM_FAULT_MAJOR)
else current->maj_flt++;
current->min_flt++; else
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
goto retry;
}
}
pgd = pgd_offset(mm, address); pgd = pgd_offset(mm, address);
pud = pud_offset(pgd, address); pud = pud_offset(pgd, address);
......
...@@ -355,3 +355,4 @@ ...@@ -355,3 +355,4 @@
346 i386 setns sys_setns 346 i386 setns sys_setns
347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv 347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
349 i386 kcmp sys_kcmp
...@@ -318,6 +318,8 @@ ...@@ -318,6 +318,8 @@
309 common getcpu sys_getcpu 309 common getcpu sys_getcpu
310 64 process_vm_readv sys_process_vm_readv 310 64 process_vm_readv sys_process_vm_readv
311 64 process_vm_writev sys_process_vm_writev 311 64 process_vm_writev sys_process_vm_writev
312 64 kcmp sys_kcmp
# #
# x32-specific system call numbers start at 512 to avoid cache impact # x32-specific system call numbers start at 512 to avoid cache impact
# for native 64-bit operation. # for native 64-bit operation.
......
...@@ -1653,7 +1653,6 @@ mpt_mapresources(MPT_ADAPTER *ioc) ...@@ -1653,7 +1653,6 @@ mpt_mapresources(MPT_ADAPTER *ioc)
unsigned long port; unsigned long port;
u32 msize; u32 msize;
u32 psize; u32 psize;
u8 revision;
int r = -ENODEV; int r = -ENODEV;
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -1670,8 +1669,6 @@ mpt_mapresources(MPT_ADAPTER *ioc) ...@@ -1670,8 +1669,6 @@ mpt_mapresources(MPT_ADAPTER *ioc)
return r; return r;
} }
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
if (sizeof(dma_addr_t) > 4) { if (sizeof(dma_addr_t) > 4) {
const uint64_t required_mask = dma_get_required_mask const uint64_t required_mask = dma_get_required_mask
(&pdev->dev); (&pdev->dev);
...@@ -1779,7 +1776,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1779,7 +1776,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
u8 cb_idx; u8 cb_idx;
int r = -ENODEV; int r = -ENODEV;
u8 revision;
u8 pcixcmd; u8 pcixcmd;
static int mpt_ids = 0; static int mpt_ids = 0;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
...@@ -1887,8 +1883,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1887,8 +1883,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
ioc->name, &ioc->facts, &ioc->pfacts[0])); ioc->name, &ioc->facts, &ioc->pfacts[0]));
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); mpt_get_product_name(pdev->vendor, pdev->device, pdev->revision,
mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); ioc->prod_name);
switch (pdev->device) switch (pdev->device)
{ {
...@@ -1903,7 +1899,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1903,7 +1899,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
break; break;
case MPI_MANUFACTPAGE_DEVICEID_FC929X: case MPI_MANUFACTPAGE_DEVICEID_FC929X:
if (revision < XL_929) { if (pdev->revision < XL_929) {
/* 929X Chip Fix. Set Split transactions level /* 929X Chip Fix. Set Split transactions level
* for PCIX. Set MOST bits to zero. * for PCIX. Set MOST bits to zero.
*/ */
...@@ -1934,7 +1930,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1934,7 +1930,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* 1030 Chip Fix. Disable Split transactions /* 1030 Chip Fix. Disable Split transactions
* for PCIX. Set MOST bits to zero if Rev < C0( = 8). * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
*/ */
if (revision < C0_1030) { if (pdev->revision < C0_1030) {
pci_read_config_byte(pdev, 0x6a, &pcixcmd); pci_read_config_byte(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0x8F; pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd); pci_write_config_byte(pdev, 0x6a, pcixcmd);
......
...@@ -1250,7 +1250,6 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) ...@@ -1250,7 +1250,6 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
int iocnum; int iocnum;
unsigned int port; unsigned int port;
int cim_rev; int cim_rev;
u8 revision;
struct scsi_device *sdev; struct scsi_device *sdev;
VirtDevice *vdevice; VirtDevice *vdevice;
...@@ -1324,8 +1323,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) ...@@ -1324,8 +1323,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
pdev = (struct pci_dev *) ioc->pcidev; pdev = (struct pci_dev *) ioc->pcidev;
karg->pciId = pdev->device; karg->pciId = pdev->device;
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); karg->hwRev = pdev->revision;
karg->hwRev = revision;
karg->subSystemDevice = pdev->subsystem_device; karg->subSystemDevice = pdev->subsystem_device;
karg->subSystemVendor = pdev->subsystem_vendor; karg->subSystemVendor = pdev->subsystem_vendor;
......
...@@ -22,6 +22,20 @@ config RAPIDIO_ENABLE_RX_TX_PORTS ...@@ -22,6 +22,20 @@ config RAPIDIO_ENABLE_RX_TX_PORTS
ports for Input/Output direction to allow other traffic ports for Input/Output direction to allow other traffic
than Maintenance transfers. than Maintenance transfers.
config RAPIDIO_DMA_ENGINE
bool "DMA Engine support for RapidIO"
depends on RAPIDIO
select DMADEVICES
select DMA_ENGINE
help
Say Y here if you want to use DMA Engine frameork for RapidIO data
transfers to/from target RIO devices. RapidIO uses NREAD and
NWRITE (NWRITE_R, SWRITE) requests to transfer data between local
memory and memory on remote target device. You need a DMA controller
capable to perform data transfers to/from RapidIO.
If you are unsure about this, say Y here.
config RAPIDIO_DEBUG config RAPIDIO_DEBUG
bool "RapidIO subsystem debug messages" bool "RapidIO subsystem debug messages"
depends on RAPIDIO depends on RAPIDIO
......
...@@ -3,3 +3,6 @@ ...@@ -3,3 +3,6 @@
# #
obj-$(CONFIG_RAPIDIO_TSI721) += tsi721.o obj-$(CONFIG_RAPIDIO_TSI721) += tsi721.o
ifeq ($(CONFIG_RAPIDIO_DMA_ENGINE),y)
obj-$(CONFIG_RAPIDIO_TSI721) += tsi721_dma.o
endif
This diff is collapsed.
...@@ -167,6 +167,8 @@ ...@@ -167,6 +167,8 @@
#define TSI721_DEV_INTE 0x29840 #define TSI721_DEV_INTE 0x29840
#define TSI721_DEV_INT 0x29844 #define TSI721_DEV_INT 0x29844
#define TSI721_DEV_INTSET 0x29848 #define TSI721_DEV_INTSET 0x29848
#define TSI721_DEV_INT_BDMA_CH 0x00002000
#define TSI721_DEV_INT_BDMA_NCH 0x00001000
#define TSI721_DEV_INT_SMSG_CH 0x00000800 #define TSI721_DEV_INT_SMSG_CH 0x00000800
#define TSI721_DEV_INT_SMSG_NCH 0x00000400 #define TSI721_DEV_INT_SMSG_NCH 0x00000400
#define TSI721_DEV_INT_SR2PC_CH 0x00000200 #define TSI721_DEV_INT_SR2PC_CH 0x00000200
...@@ -181,6 +183,8 @@ ...@@ -181,6 +183,8 @@
#define TSI721_INT_IMSG_CHAN(x) (1 << (16 + (x))) #define TSI721_INT_IMSG_CHAN(x) (1 << (16 + (x)))
#define TSI721_INT_OMSG_CHAN_M 0x0000ff00 #define TSI721_INT_OMSG_CHAN_M 0x0000ff00
#define TSI721_INT_OMSG_CHAN(x) (1 << (8 + (x))) #define TSI721_INT_OMSG_CHAN(x) (1 << (8 + (x)))
#define TSI721_INT_BDMA_CHAN_M 0x000000ff
#define TSI721_INT_BDMA_CHAN(x) (1 << (x))
/* /*
* PC2SR block registers * PC2SR block registers
...@@ -235,14 +239,16 @@ ...@@ -235,14 +239,16 @@
* x = 0..7 * x = 0..7
*/ */
#define TSI721_DMAC_DWRCNT(x) (0x51000 + (x) * 0x1000) #define TSI721_DMAC_BASE(x) (0x51000 + (x) * 0x1000)
#define TSI721_DMAC_DRDCNT(x) (0x51004 + (x) * 0x1000)
#define TSI721_DMAC_CTL(x) (0x51008 + (x) * 0x1000) #define TSI721_DMAC_DWRCNT 0x000
#define TSI721_DMAC_DRDCNT 0x004
#define TSI721_DMAC_CTL 0x008
#define TSI721_DMAC_CTL_SUSP 0x00000002 #define TSI721_DMAC_CTL_SUSP 0x00000002
#define TSI721_DMAC_CTL_INIT 0x00000001 #define TSI721_DMAC_CTL_INIT 0x00000001
#define TSI721_DMAC_INT(x) (0x5100c + (x) * 0x1000) #define TSI721_DMAC_INT 0x00c
#define TSI721_DMAC_INT_STFULL 0x00000010 #define TSI721_DMAC_INT_STFULL 0x00000010
#define TSI721_DMAC_INT_DONE 0x00000008 #define TSI721_DMAC_INT_DONE 0x00000008
#define TSI721_DMAC_INT_SUSP 0x00000004 #define TSI721_DMAC_INT_SUSP 0x00000004
...@@ -250,34 +256,33 @@ ...@@ -250,34 +256,33 @@
#define TSI721_DMAC_INT_IOFDONE 0x00000001 #define TSI721_DMAC_INT_IOFDONE 0x00000001
#define TSI721_DMAC_INT_ALL 0x0000001f #define TSI721_DMAC_INT_ALL 0x0000001f
#define TSI721_DMAC_INTSET(x) (0x51010 + (x) * 0x1000) #define TSI721_DMAC_INTSET 0x010
#define TSI721_DMAC_STS(x) (0x51014 + (x) * 0x1000) #define TSI721_DMAC_STS 0x014
#define TSI721_DMAC_STS_ABORT 0x00400000 #define TSI721_DMAC_STS_ABORT 0x00400000
#define TSI721_DMAC_STS_RUN 0x00200000 #define TSI721_DMAC_STS_RUN 0x00200000
#define TSI721_DMAC_STS_CS 0x001f0000 #define TSI721_DMAC_STS_CS 0x001f0000
#define TSI721_DMAC_INTE(x) (0x51018 + (x) * 0x1000) #define TSI721_DMAC_INTE 0x018
#define TSI721_DMAC_DPTRL(x) (0x51024 + (x) * 0x1000) #define TSI721_DMAC_DPTRL 0x024
#define TSI721_DMAC_DPTRL_MASK 0xffffffe0 #define TSI721_DMAC_DPTRL_MASK 0xffffffe0
#define TSI721_DMAC_DPTRH(x) (0x51028 + (x) * 0x1000) #define TSI721_DMAC_DPTRH 0x028
#define TSI721_DMAC_DSBL(x) (0x5102c + (x) * 0x1000) #define TSI721_DMAC_DSBL 0x02c
#define TSI721_DMAC_DSBL_MASK 0xffffffc0 #define TSI721_DMAC_DSBL_MASK 0xffffffc0
#define TSI721_DMAC_DSBH(x) (0x51030 + (x) * 0x1000) #define TSI721_DMAC_DSBH 0x030
#define TSI721_DMAC_DSSZ(x) (0x51034 + (x) * 0x1000) #define TSI721_DMAC_DSSZ 0x034
#define TSI721_DMAC_DSSZ_SIZE_M 0x0000000f #define TSI721_DMAC_DSSZ_SIZE_M 0x0000000f
#define TSI721_DMAC_DSSZ_SIZE(size) (__fls(size) - 4) #define TSI721_DMAC_DSSZ_SIZE(size) (__fls(size) - 4)
#define TSI721_DMAC_DSRP 0x038
#define TSI721_DMAC_DSRP(x) (0x51038 + (x) * 0x1000)
#define TSI721_DMAC_DSRP_MASK 0x0007ffff #define TSI721_DMAC_DSRP_MASK 0x0007ffff
#define TSI721_DMAC_DSWP(x) (0x5103c + (x) * 0x1000) #define TSI721_DMAC_DSWP 0x03c
#define TSI721_DMAC_DSWP_MASK 0x0007ffff #define TSI721_DMAC_DSWP_MASK 0x0007ffff
#define TSI721_BDMA_INTE 0x5f000 #define TSI721_BDMA_INTE 0x5f000
...@@ -612,6 +617,8 @@ enum dma_rtype { ...@@ -612,6 +617,8 @@ enum dma_rtype {
#define TSI721_DMACH_MAINT 0 /* DMA channel for maint requests */ #define TSI721_DMACH_MAINT 0 /* DMA channel for maint requests */
#define TSI721_DMACH_MAINT_NBD 32 /* Number of BDs for maint requests */ #define TSI721_DMACH_MAINT_NBD 32 /* Number of BDs for maint requests */
#define TSI721_DMACH_DMA 1 /* DMA channel for data transfers */
#define MSG_DMA_ENTRY_INX_TO_SIZE(x) ((0x10 << (x)) & 0xFFFF0) #define MSG_DMA_ENTRY_INX_TO_SIZE(x) ((0x10 << (x)) & 0xFFFF0)
enum tsi721_smsg_int_flag { enum tsi721_smsg_int_flag {
...@@ -626,7 +633,48 @@ enum tsi721_smsg_int_flag { ...@@ -626,7 +633,48 @@ enum tsi721_smsg_int_flag {
/* Structures */ /* Structures */
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct tsi721_tx_desc {
struct dma_async_tx_descriptor txd;
struct tsi721_dma_desc *hw_desc;
u16 destid;
/* low 64-bits of 66-bit RIO address */
u64 rio_addr;
/* upper 2-bits of 66-bit RIO address */
u8 rio_addr_u;
bool interrupt;
struct list_head desc_node;
struct list_head tx_list;
};
struct tsi721_bdma_chan { struct tsi721_bdma_chan {
int id;
void __iomem *regs;
int bd_num; /* number of buffer descriptors */
void *bd_base; /* start of DMA descriptors */
dma_addr_t bd_phys;
void *sts_base; /* start of DMA BD status FIFO */
dma_addr_t sts_phys;
int sts_size;
u32 sts_rdptr;
u32 wr_count;
u32 wr_count_next;
struct dma_chan dchan;
struct tsi721_tx_desc *tx_desc;
spinlock_t lock;
struct list_head active_list;
struct list_head queue;
struct list_head free_list;
dma_cookie_t completed_cookie;
struct tasklet_struct tasklet;
};
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
struct tsi721_bdma_maint {
int ch_id; /* BDMA channel number */
int bd_num; /* number of buffer descriptors */ int bd_num; /* number of buffer descriptors */
void *bd_base; /* start of DMA descriptors */ void *bd_base; /* start of DMA descriptors */
dma_addr_t bd_phys; dma_addr_t bd_phys;
...@@ -721,6 +769,24 @@ enum tsi721_msix_vect { ...@@ -721,6 +769,24 @@ enum tsi721_msix_vect {
TSI721_VECT_IMB1_INT, TSI721_VECT_IMB1_INT,
TSI721_VECT_IMB2_INT, TSI721_VECT_IMB2_INT,
TSI721_VECT_IMB3_INT, TSI721_VECT_IMB3_INT,
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
TSI721_VECT_DMA0_DONE,
TSI721_VECT_DMA1_DONE,
TSI721_VECT_DMA2_DONE,
TSI721_VECT_DMA3_DONE,
TSI721_VECT_DMA4_DONE,
TSI721_VECT_DMA5_DONE,
TSI721_VECT_DMA6_DONE,
TSI721_VECT_DMA7_DONE,
TSI721_VECT_DMA0_INT,
TSI721_VECT_DMA1_INT,
TSI721_VECT_DMA2_INT,
TSI721_VECT_DMA3_INT,
TSI721_VECT_DMA4_INT,
TSI721_VECT_DMA5_INT,
TSI721_VECT_DMA6_INT,
TSI721_VECT_DMA7_INT,
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
TSI721_VECT_MAX TSI721_VECT_MAX
}; };
...@@ -754,7 +820,11 @@ struct tsi721_device { ...@@ -754,7 +820,11 @@ struct tsi721_device {
u32 pw_discard_count; u32 pw_discard_count;
/* BDMA Engine */ /* BDMA Engine */
struct tsi721_bdma_maint mdma; /* Maintenance rd/wr request channel */
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct tsi721_bdma_chan bdma[TSI721_DMA_CHNUM]; struct tsi721_bdma_chan bdma[TSI721_DMA_CHNUM];
#endif
/* Inbound Messaging */ /* Inbound Messaging */
int imsg_init[TSI721_IMSG_CHNUM]; int imsg_init[TSI721_IMSG_CHNUM];
...@@ -765,4 +835,9 @@ struct tsi721_device { ...@@ -765,4 +835,9 @@ struct tsi721_device {
struct tsi721_omsg_ring omsg_ring[TSI721_OMSG_CHNUM]; struct tsi721_omsg_ring omsg_ring[TSI721_OMSG_CHNUM];
}; };
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
extern void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan);
extern int __devinit tsi721_register_dma(struct tsi721_device *priv);
#endif
#endif #endif
This diff is collapsed.
...@@ -1121,6 +1121,87 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, ...@@ -1121,6 +1121,87 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
return 0; return 0;
} }
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
static bool rio_chan_filter(struct dma_chan *chan, void *arg)
{
struct rio_dev *rdev = arg;
/* Check that DMA device belongs to the right MPORT */
return (rdev->net->hport ==
container_of(chan->device, struct rio_mport, dma));
}
/**
* rio_request_dma - request RapidIO capable DMA channel that supports
* specified target RapidIO device.
* @rdev: RIO device control structure
*
* Returns pointer to allocated DMA channel or NULL if failed.
*/
struct dma_chan *rio_request_dma(struct rio_dev *rdev)
{
dma_cap_mask_t mask;
struct dma_chan *dchan;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dchan = dma_request_channel(mask, rio_chan_filter, rdev);
return dchan;
}
EXPORT_SYMBOL_GPL(rio_request_dma);
/**
* rio_release_dma - release specified DMA channel
* @dchan: DMA channel to release
*/
void rio_release_dma(struct dma_chan *dchan)
{
dma_release_channel(dchan);
}
EXPORT_SYMBOL_GPL(rio_release_dma);
/**
* rio_dma_prep_slave_sg - RapidIO specific wrapper
* for device_prep_slave_sg callback defined by DMAENGINE.
* @rdev: RIO device control structure
* @dchan: DMA channel to configure
* @data: RIO specific data descriptor
* @direction: DMA data transfer direction (TO or FROM the device)
* @flags: dmaengine defined flags
*
* Initializes RapidIO capable DMA channel for the specified data transfer.
* Uses DMA channel private extension to pass information related to remote
* target RIO device.
* Returns pointer to DMA transaction descriptor or NULL if failed.
*/
struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev,
struct dma_chan *dchan, struct rio_dma_data *data,
enum dma_transfer_direction direction, unsigned long flags)
{
struct dma_async_tx_descriptor *txd = NULL;
struct rio_dma_ext rio_ext;
if (dchan->device->device_prep_slave_sg == NULL) {
pr_err("%s: prep_rio_sg == NULL\n", __func__);
return NULL;
}
rio_ext.destid = rdev->destid;
rio_ext.rio_addr_u = data->rio_addr_u;
rio_ext.rio_addr = data->rio_addr;
rio_ext.wr_type = data->wr_type;
txd = dmaengine_prep_rio_sg(dchan, data->sg, data->sg_len,
direction, flags, &rio_ext);
return txd;
}
EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
static void rio_fixup_device(struct rio_dev *dev) static void rio_fixup_device(struct rio_dev *dev)
{ {
} }
......
...@@ -1446,13 +1446,13 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat) ...@@ -1446,13 +1446,13 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
ret = compat_rw_copy_check_uvector(type, ret = compat_rw_copy_check_uvector(type,
(struct compat_iovec __user *)kiocb->ki_buf, (struct compat_iovec __user *)kiocb->ki_buf,
kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec, kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,
&kiocb->ki_iovec, 1); &kiocb->ki_iovec);
else else
#endif #endif
ret = rw_copy_check_uvector(type, ret = rw_copy_check_uvector(type,
(struct iovec __user *)kiocb->ki_buf, (struct iovec __user *)kiocb->ki_buf,
kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec, kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,
&kiocb->ki_iovec, 1); &kiocb->ki_iovec);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -331,7 +331,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) ...@@ -331,7 +331,7 @@ static int build_snap_context(struct ceph_snap_realm *realm)
/* alloc new snap context */ /* alloc new snap context */
err = -ENOMEM; err = -ENOMEM;
if (num > (ULONG_MAX - sizeof(*snapc)) / sizeof(u64)) if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
goto fail; goto fail;
snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS); snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS);
if (!snapc) if (!snapc)
......
...@@ -532,7 +532,7 @@ compat_sys_io_getevents(aio_context_t ctx_id, ...@@ -532,7 +532,7 @@ compat_sys_io_getevents(aio_context_t ctx_id,
ssize_t compat_rw_copy_check_uvector(int type, ssize_t compat_rw_copy_check_uvector(int type,
const struct compat_iovec __user *uvector, unsigned long nr_segs, const struct compat_iovec __user *uvector, unsigned long nr_segs,
unsigned long fast_segs, struct iovec *fast_pointer, unsigned long fast_segs, struct iovec *fast_pointer,
struct iovec **ret_pointer, int check_access) struct iovec **ret_pointer)
{ {
compat_ssize_t tot_len; compat_ssize_t tot_len;
struct iovec *iov = *ret_pointer = fast_pointer; struct iovec *iov = *ret_pointer = fast_pointer;
...@@ -579,7 +579,7 @@ ssize_t compat_rw_copy_check_uvector(int type, ...@@ -579,7 +579,7 @@ ssize_t compat_rw_copy_check_uvector(int type,
} }
if (len < 0) /* size_t not fitting in compat_ssize_t .. */ if (len < 0) /* size_t not fitting in compat_ssize_t .. */
goto out; goto out;
if (check_access && if (type >= 0 &&
!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
...@@ -1094,7 +1094,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, ...@@ -1094,7 +1094,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
goto out; goto out;
tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs, tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
UIO_FASTIOV, iovstack, &iov, 1); UIO_FASTIOV, iovstack, &iov);
if (tot_len == 0) { if (tot_len == 0) {
ret = 0; ret = 0;
goto out; goto out;
......
...@@ -46,20 +46,16 @@ struct eventfd_ctx { ...@@ -46,20 +46,16 @@ struct eventfd_ctx {
* value, and we signal this as overflow condition by returining a POLLERR * value, and we signal this as overflow condition by returining a POLLERR
* to poll(2). * to poll(2).
* *
* Returns @n in case of success, a non-negative number lower than @n in case * Returns the amount by which the counter was incrememnted. This will be less
* of overflow, or the following error codes: * than @n if the counter has overflowed.
*
* -EINVAL : The value of @n is negative.
*/ */
int eventfd_signal(struct eventfd_ctx *ctx, int n) __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
{ {
unsigned long flags; unsigned long flags;
if (n < 0)
return -EINVAL;
spin_lock_irqsave(&ctx->wqh.lock, flags); spin_lock_irqsave(&ctx->wqh.lock, flags);
if (ULLONG_MAX - ctx->count < n) if (ULLONG_MAX - ctx->count < n)
n = (int) (ULLONG_MAX - ctx->count); n = ULLONG_MAX - ctx->count;
ctx->count += n; ctx->count += n;
if (waitqueue_active(&ctx->wqh)) if (waitqueue_active(&ctx->wqh))
wake_up_locked_poll(&ctx->wqh, POLLIN); wake_up_locked_poll(&ctx->wqh, POLLIN);
......
...@@ -98,8 +98,8 @@ static int fat__get_entry(struct inode *dir, loff_t *pos, ...@@ -98,8 +98,8 @@ static int fat__get_entry(struct inode *dir, loff_t *pos,
*bh = sb_bread(sb, phys); *bh = sb_bread(sb, phys);
if (*bh == NULL) { if (*bh == NULL) {
fat_msg(sb, KERN_ERR, "Directory bread(block %llu) failed", fat_msg_ratelimit(sb, KERN_ERR,
(llu)phys); "Directory bread(block %llu) failed", (llu)phys);
/* skip this block */ /* skip this block */
*pos = (iblock + 1) << sb->s_blocksize_bits; *pos = (iblock + 1) << sb->s_blocksize_bits;
goto next; goto next;
......
...@@ -82,6 +82,7 @@ struct msdos_sb_info { ...@@ -82,6 +82,7 @@ struct msdos_sb_info {
int fatent_shift; int fatent_shift;
struct fatent_operations *fatent_ops; struct fatent_operations *fatent_ops;
struct inode *fat_inode; struct inode *fat_inode;
struct inode *fsinfo_inode;
struct ratelimit_state ratelimit; struct ratelimit_state ratelimit;
...@@ -334,6 +335,11 @@ void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...); ...@@ -334,6 +335,11 @@ void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
__fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args)
__printf(3, 4) __cold __printf(3, 4) __cold
void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...);
#define fat_msg_ratelimit(sb, level, fmt, args...) \
do { \
if (__ratelimit(&MSDOS_SB(sb)->ratelimit)) \
fat_msg(sb, level, fmt, ## args); \
} while (0)
extern int fat_clusters_flush(struct super_block *sb); extern int fat_clusters_flush(struct super_block *sb);
extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
......
...@@ -308,6 +308,16 @@ void fat_ent_access_init(struct super_block *sb) ...@@ -308,6 +308,16 @@ void fat_ent_access_init(struct super_block *sb)
} }
} }
static void mark_fsinfo_dirty(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
if (sb->s_flags & MS_RDONLY || sbi->fat_bits != 32)
return;
__mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC);
}
static inline int fat_ent_update_ptr(struct super_block *sb, static inline int fat_ent_update_ptr(struct super_block *sb,
struct fat_entry *fatent, struct fat_entry *fatent,
int offset, sector_t blocknr) int offset, sector_t blocknr)
...@@ -498,7 +508,6 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster) ...@@ -498,7 +508,6 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
sbi->prev_free = entry; sbi->prev_free = entry;
if (sbi->free_clusters != -1) if (sbi->free_clusters != -1)
sbi->free_clusters--; sbi->free_clusters--;
sb->s_dirt = 1;
cluster[idx_clus] = entry; cluster[idx_clus] = entry;
idx_clus++; idx_clus++;
...@@ -520,11 +529,11 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster) ...@@ -520,11 +529,11 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
/* Couldn't allocate the free entries */ /* Couldn't allocate the free entries */
sbi->free_clusters = 0; sbi->free_clusters = 0;
sbi->free_clus_valid = 1; sbi->free_clus_valid = 1;
sb->s_dirt = 1;
err = -ENOSPC; err = -ENOSPC;
out: out:
unlock_fat(sbi); unlock_fat(sbi);
mark_fsinfo_dirty(sb);
fatent_brelse(&fatent); fatent_brelse(&fatent);
if (!err) { if (!err) {
if (inode_needs_sync(inode)) if (inode_needs_sync(inode))
...@@ -549,7 +558,7 @@ int fat_free_clusters(struct inode *inode, int cluster) ...@@ -549,7 +558,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
struct fat_entry fatent; struct fat_entry fatent;
struct buffer_head *bhs[MAX_BUF_PER_PAGE]; struct buffer_head *bhs[MAX_BUF_PER_PAGE];
int i, err, nr_bhs; int i, err, nr_bhs;
int first_cl = cluster; int first_cl = cluster, dirty_fsinfo = 0;
nr_bhs = 0; nr_bhs = 0;
fatent_init(&fatent); fatent_init(&fatent);
...@@ -587,7 +596,7 @@ int fat_free_clusters(struct inode *inode, int cluster) ...@@ -587,7 +596,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
ops->ent_put(&fatent, FAT_ENT_FREE); ops->ent_put(&fatent, FAT_ENT_FREE);
if (sbi->free_clusters != -1) { if (sbi->free_clusters != -1) {
sbi->free_clusters++; sbi->free_clusters++;
sb->s_dirt = 1; dirty_fsinfo = 1;
} }
if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) { if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
...@@ -617,6 +626,8 @@ int fat_free_clusters(struct inode *inode, int cluster) ...@@ -617,6 +626,8 @@ int fat_free_clusters(struct inode *inode, int cluster)
for (i = 0; i < nr_bhs; i++) for (i = 0; i < nr_bhs; i++)
brelse(bhs[i]); brelse(bhs[i]);
unlock_fat(sbi); unlock_fat(sbi);
if (dirty_fsinfo)
mark_fsinfo_dirty(sb);
return err; return err;
} }
...@@ -677,7 +688,7 @@ int fat_count_free_clusters(struct super_block *sb) ...@@ -677,7 +688,7 @@ int fat_count_free_clusters(struct super_block *sb)
} }
sbi->free_clusters = free; sbi->free_clusters = free;
sbi->free_clus_valid = 1; sbi->free_clus_valid = 1;
sb->s_dirt = 1; mark_fsinfo_dirty(sb);
fatent_brelse(&fatent); fatent_brelse(&fatent);
out: out:
unlock_fat(sbi); unlock_fat(sbi);
......
...@@ -459,37 +459,11 @@ static void fat_evict_inode(struct inode *inode) ...@@ -459,37 +459,11 @@ static void fat_evict_inode(struct inode *inode)
fat_detach(inode); fat_detach(inode);
} }
static void fat_write_super(struct super_block *sb)
{
lock_super(sb);
sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY))
fat_clusters_flush(sb);
unlock_super(sb);
}
static int fat_sync_fs(struct super_block *sb, int wait)
{
int err = 0;
if (sb->s_dirt) {
lock_super(sb);
sb->s_dirt = 0;
err = fat_clusters_flush(sb);
unlock_super(sb);
}
return err;
}
static void fat_put_super(struct super_block *sb) static void fat_put_super(struct super_block *sb)
{ {
struct msdos_sb_info *sbi = MSDOS_SB(sb); struct msdos_sb_info *sbi = MSDOS_SB(sb);
if (sb->s_dirt) iput(sbi->fsinfo_inode);
fat_write_super(sb);
iput(sbi->fat_inode); iput(sbi->fat_inode);
unload_nls(sbi->nls_disk); unload_nls(sbi->nls_disk);
...@@ -661,7 +635,18 @@ static int __fat_write_inode(struct inode *inode, int wait) ...@@ -661,7 +635,18 @@ static int __fat_write_inode(struct inode *inode, int wait)
static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
{ {
return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); int err;
if (inode->i_ino == MSDOS_FSINFO_INO) {
struct super_block *sb = inode->i_sb;
lock_super(sb);
err = fat_clusters_flush(sb);
unlock_super(sb);
} else
err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
return err;
} }
int fat_sync_inode(struct inode *inode) int fat_sync_inode(struct inode *inode)
...@@ -678,8 +663,6 @@ static const struct super_operations fat_sops = { ...@@ -678,8 +663,6 @@ static const struct super_operations fat_sops = {
.write_inode = fat_write_inode, .write_inode = fat_write_inode,
.evict_inode = fat_evict_inode, .evict_inode = fat_evict_inode,
.put_super = fat_put_super, .put_super = fat_put_super,
.write_super = fat_write_super,
.sync_fs = fat_sync_fs,
.statfs = fat_statfs, .statfs = fat_statfs,
.remount_fs = fat_remount, .remount_fs = fat_remount,
...@@ -1244,6 +1227,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, ...@@ -1244,6 +1227,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
void (*setup)(struct super_block *)) void (*setup)(struct super_block *))
{ {
struct inode *root_inode = NULL, *fat_inode = NULL; struct inode *root_inode = NULL, *fat_inode = NULL;
struct inode *fsinfo_inode = NULL;
struct buffer_head *bh; struct buffer_head *bh;
struct fat_boot_sector *b; struct fat_boot_sector *b;
struct msdos_sb_info *sbi; struct msdos_sb_info *sbi;
...@@ -1490,6 +1474,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, ...@@ -1490,6 +1474,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
goto out_fail; goto out_fail;
MSDOS_I(fat_inode)->i_pos = 0; MSDOS_I(fat_inode)->i_pos = 0;
sbi->fat_inode = fat_inode; sbi->fat_inode = fat_inode;
fsinfo_inode = new_inode(sb);
if (!fsinfo_inode)
goto out_fail;
fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
sbi->fsinfo_inode = fsinfo_inode;
insert_inode_hash(fsinfo_inode);
root_inode = new_inode(sb); root_inode = new_inode(sb);
if (!root_inode) if (!root_inode)
goto out_fail; goto out_fail;
...@@ -1516,6 +1508,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, ...@@ -1516,6 +1508,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem"); fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem");
out_fail: out_fail:
if (fsinfo_inode)
iput(fsinfo_inode);
if (fat_inode) if (fat_inode)
iput(fat_inode); iput(fat_inode);
unload_nls(sbi->nls_io); unload_nls(sbi->nls_io);
......
...@@ -156,7 +156,6 @@ void hpfs_brelse4(struct quad_buffer_head *qbh) ...@@ -156,7 +156,6 @@ void hpfs_brelse4(struct quad_buffer_head *qbh)
void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh) void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
{ {
PRINTK(("hpfs_mark_4buffers_dirty\n"));
memcpy(qbh->bh[0]->b_data, qbh->data, 512); memcpy(qbh->bh[0]->b_data, qbh->data, 512);
memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512); memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512);
memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
......
...@@ -35,13 +35,6 @@ ...@@ -35,13 +35,6 @@
#define CHKCOND(x,y) if (!(x)) printk y #define CHKCOND(x,y) if (!(x)) printk y
#ifdef DBG
#define PRINTK(x) printk x
#else
#undef PRINTK
#define PRINTK(x)
#endif
struct hpfs_inode_info { struct hpfs_inode_info {
loff_t mmu_private; loff_t mmu_private;
ino_t i_parent_dir; /* (directories) gives fnode of parent dir */ ino_t i_parent_dir; /* (directories) gives fnode of parent dir */
......
...@@ -37,6 +37,7 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -37,6 +37,7 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* This function should be implemented when the writeback function * This function should be implemented when the writeback function
* will be implemented. * will be implemented.
*/ */
struct the_nilfs *nilfs;
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
int err; int err;
...@@ -45,18 +46,21 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -45,18 +46,21 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
return err; return err;
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
if (!nilfs_inode_dirty(inode)) { if (nilfs_inode_dirty(inode)) {
mutex_unlock(&inode->i_mutex); if (datasync)
return 0; err = nilfs_construct_dsync_segment(inode->i_sb, inode,
0, LLONG_MAX);
else
err = nilfs_construct_segment(inode->i_sb);
} }
if (datasync)
err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0,
LLONG_MAX);
else
err = nilfs_construct_segment(inode->i_sb);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
nilfs = inode->i_sb->s_fs_info;
if (!err && nilfs_test_opt(nilfs, BARRIER)) {
err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (err != -EIO)
err = 0;
}
return err; return err;
} }
......
...@@ -692,8 +692,14 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, ...@@ -692,8 +692,14 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
if (ret < 0) if (ret < 0)
return ret; return ret;
nilfs = inode->i_sb->s_fs_info;
if (nilfs_test_opt(nilfs, BARRIER)) {
ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (ret == -EIO)
return ret;
}
if (argp != NULL) { if (argp != NULL) {
nilfs = inode->i_sb->s_fs_info;
down_read(&nilfs->ns_segctor_sem); down_read(&nilfs->ns_segctor_sem);
cno = nilfs->ns_cno - 1; cno = nilfs->ns_cno - 1;
up_read(&nilfs->ns_segctor_sem); up_read(&nilfs->ns_segctor_sem);
......
...@@ -30,7 +30,7 @@ config NLS_DEFAULT ...@@ -30,7 +30,7 @@ config NLS_DEFAULT
cp949, cp950, cp1251, cp1255, euc-jp, euc-kr, gb2312, iso8859-1, cp949, cp950, cp1251, cp1255, euc-jp, euc-kr, gb2312, iso8859-1,
iso8859-2, iso8859-3, iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-2, iso8859-3, iso8859-4, iso8859-5, iso8859-6, iso8859-7,
iso8859-8, iso8859-9, iso8859-13, iso8859-14, iso8859-15, iso8859-8, iso8859-9, iso8859-13, iso8859-14, iso8859-15,
koi8-r, koi8-ru, koi8-u, sjis, tis-620, utf8. koi8-r, koi8-ru, koi8-u, sjis, tis-620, macroman, utf8.
If you specify a wrong value, it will use the built-in NLS; If you specify a wrong value, it will use the built-in NLS;
compatible with iso8859-1. compatible with iso8859-1.
...@@ -452,6 +452,161 @@ config NLS_KOI8_U ...@@ -452,6 +452,161 @@ config NLS_KOI8_U
input/output character sets. Say Y here for the preferred Ukrainian input/output character sets. Say Y here for the preferred Ukrainian
(koi8-u) and Belarusian (koi8-ru) character sets. (koi8-u) and Belarusian (koi8-ru) character sets.
config NLS_CODEPAGE_MACROMAN
tristate "Codepage macroman"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
much of Europe -- United Kingdom, Germany, Spain, Italy, and [add
more countries here].
If unsure, say Y.
config NLS_CODEPAGE_MACCELTIC
tristate "Codepage macceltic"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Celtic.
If unsure, say Y.
config NLS_CODEPAGE_MACCENTEURO
tristate "Codepage maccenteuro"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Central Europe.
If unsure, say Y.
config NLS_CODEPAGE_MACCROATIAN
tristate "Codepage maccroatian"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Croatian.
If unsure, say Y.
config NLS_CODEPAGE_MACCYRILLIC
tristate "Codepage maccyrillic"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Cyrillic.
If unsure, say Y.
config NLS_CODEPAGE_MACGAELIC
tristate "Codepage macgaelic"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Gaelic.
If unsure, say Y.
config NLS_CODEPAGE_MACGREEK
tristate "Codepage macgreek"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Greek.
If unsure, say Y.
config NLS_CODEPAGE_MACICELAND
tristate "Codepage maciceland"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Iceland.
If unsure, say Y.
config NLS_CODEPAGE_MACINUIT
tristate "Codepage macinuit"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Inuit.
If unsure, say Y.
config NLS_CODEPAGE_MACROMANIAN
tristate "Codepage macromanian"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Romanian.
If unsure, say Y.
config NLS_CODEPAGE_MACTURKISH
tristate "Codepage macturkish"
---help---
The Apple HFS file system family can deal with filenames in
native language character sets. These character sets are stored in
so-called MAC codepages. You need to include the appropriate
codepage if you want to be able to read/write these filenames on
Mac partitions correctly. This does apply to the filenames
only, not to the file contents. You can include several codepages;
say Y here if you want to include the Mac codepage that is used for
Turkish.
If unsure, say Y.
config NLS_UTF8 config NLS_UTF8
tristate "NLS UTF-8" tristate "NLS UTF-8"
help help
......
...@@ -2,6 +2,18 @@ ...@@ -2,6 +2,18 @@
# Makefile for native language support # Makefile for native language support
# #
CONFIG_NLS_MACCELTIC=m
CONFIG_NLS_MACCENTEURO=m
CONFIG_NLS_MACCROATIAN=m
CONFIG_NLS_MACCYRILLIC=m
CONFIG_NLS_MACGAELIC=m
CONFIG_NLS_MACGREEK=m
CONFIG_NLS_MACICELAND=m
CONFIG_NLS_MACINUIT=m
CONFIG_NLS_MACROMANIAN=m
CONFIG_NLS_MACROMAN=m
CONFIG_NLS_MACTURKISH=m
obj-$(CONFIG_NLS) += nls_base.o obj-$(CONFIG_NLS) += nls_base.o
obj-$(CONFIG_NLS_CODEPAGE_437) += nls_cp437.o obj-$(CONFIG_NLS_CODEPAGE_437) += nls_cp437.o
...@@ -42,3 +54,14 @@ obj-$(CONFIG_NLS_ISO8859_15) += nls_iso8859-15.o ...@@ -42,3 +54,14 @@ obj-$(CONFIG_NLS_ISO8859_15) += nls_iso8859-15.o
obj-$(CONFIG_NLS_KOI8_R) += nls_koi8-r.o obj-$(CONFIG_NLS_KOI8_R) += nls_koi8-r.o
obj-$(CONFIG_NLS_KOI8_U) += nls_koi8-u.o nls_koi8-ru.o obj-$(CONFIG_NLS_KOI8_U) += nls_koi8-u.o nls_koi8-ru.o
obj-$(CONFIG_NLS_UTF8) += nls_utf8.o obj-$(CONFIG_NLS_UTF8) += nls_utf8.o
obj-$(CONFIG_NLS_MACCELTIC) += nls_macceltic.o
obj-$(CONFIG_NLS_MACCENTEURO) += nls_maccenteuro.o
obj-$(CONFIG_NLS_MACCROATIAN) += nls_maccroatian.o
obj-$(CONFIG_NLS_MACCYRILLIC) += nls_maccyrillic.o
obj-$(CONFIG_NLS_MACGAELIC) += nls_macgaelic.o
obj-$(CONFIG_NLS_MACGREEK) += nls_macgreek.o
obj-$(CONFIG_NLS_MACICELAND) += nls_maciceland.o
obj-$(CONFIG_NLS_MACINUIT) += nls_macinuit.o
obj-$(CONFIG_NLS_MACROMANIAN) += nls_macromanian.o
obj-$(CONFIG_NLS_MACROMAN) += nls_macroman.o
obj-$(CONFIG_NLS_MACTURKISH) += nls_macturkish.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -693,7 +693,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -693,7 +693,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return put_user(count, (int __user *)arg); return put_user(count, (int __user *)arg);
default: default:
return -EINVAL; return -ENOIOCTLCMD;
} }
} }
......
...@@ -370,7 +370,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, ...@@ -370,7 +370,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task, int whole) struct pid *pid, struct task_struct *task, int whole)
{ {
unsigned long vsize, eip, esp, wchan = ~0UL; unsigned long vsize, eip, esp, wchan = ~0UL;
long priority, nice; int priority, nice;
int tty_pgrp = -1, tty_nr = 0; int tty_pgrp = -1, tty_nr = 0;
sigset_t sigign, sigcatch; sigset_t sigign, sigcatch;
char state; char state;
...@@ -492,7 +492,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, ...@@ -492,7 +492,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
seq_put_decimal_ull(m, ' ', 0); seq_put_decimal_ull(m, ' ', 0);
seq_put_decimal_ull(m, ' ', start_time); seq_put_decimal_ull(m, ' ', start_time);
seq_put_decimal_ull(m, ' ', vsize); seq_put_decimal_ull(m, ' ', vsize);
seq_put_decimal_ll(m, ' ', mm ? get_mm_rss(mm) : 0); seq_put_decimal_ull(m, ' ', mm ? get_mm_rss(mm) : 0);
seq_put_decimal_ull(m, ' ', rsslim); seq_put_decimal_ull(m, ' ', rsslim);
seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0); seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0);
seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0); seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0);
...@@ -517,9 +517,23 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, ...@@ -517,9 +517,23 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task)); seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task));
seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime)); seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime));
seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime)); seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime));
seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_data : 0);
seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->end_data : 0); if (mm && permitted) {
seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_brk : 0); seq_put_decimal_ull(m, ' ', mm->start_data);
seq_put_decimal_ull(m, ' ', mm->end_data);
seq_put_decimal_ull(m, ' ', mm->start_brk);
seq_put_decimal_ull(m, ' ', mm->arg_start);
seq_put_decimal_ull(m, ' ', mm->arg_end);
seq_put_decimal_ull(m, ' ', mm->env_start);
seq_put_decimal_ull(m, ' ', mm->env_end);
} else
seq_printf(m, " 0 0 0 0 0 0 0");
if (permitted)
seq_put_decimal_ll(m, ' ', task->exit_code);
else
seq_put_decimal_ll(m, ' ', 0);
seq_putc(m, '\n'); seq_putc(m, '\n');
if (mm) if (mm)
mmput(mm); mmput(mm);
...@@ -565,3 +579,126 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, ...@@ -565,3 +579,126 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
return 0; return 0;
} }
#ifdef CONFIG_CHECKPOINT_RESTORE
static struct pid *
get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
{
struct task_struct *start, *task;
struct pid *pid = NULL;
read_lock(&tasklist_lock);
start = pid_task(proc_pid(inode), PIDTYPE_PID);
if (!start)
goto out;
/*
* Lets try to continue searching first, this gives
* us significant speedup on children-rich processes.
*/
if (pid_prev) {
task = pid_task(pid_prev, PIDTYPE_PID);
if (task && task->real_parent == start &&
!(list_empty(&task->sibling))) {
if (list_is_last(&task->sibling, &start->children))
goto out;
task = list_first_entry(&task->sibling,
struct task_struct, sibling);
pid = get_pid(task_pid(task));
goto out;
}
}
/*
* Slow search case.
*
* We might miss some children here if children
* are exited while we were not holding the lock,
* but it was never promised to be accurate that
* much.
*
* "Just suppose that the parent sleeps, but N children
* exit after we printed their tids. Now the slow paths
* skips N extra children, we miss N tasks." (c)
*
* So one need to stop or freeze the leader and all
* its children to get a precise result.
*/
list_for_each_entry(task, &start->children, sibling) {
if (pos-- == 0) {
pid = get_pid(task_pid(task));
break;
}
}
out:
read_unlock(&tasklist_lock);
return pid;
}
static int children_seq_show(struct seq_file *seq, void *v)
{
struct inode *inode = seq->private;
pid_t pid;
pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
return seq_printf(seq, "%d ", pid);
}
static void *children_seq_start(struct seq_file *seq, loff_t *pos)
{
return get_children_pid(seq->private, NULL, *pos);
}
static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct pid *pid;
pid = get_children_pid(seq->private, v, *pos + 1);
put_pid(v);
++*pos;
return pid;
}
static void children_seq_stop(struct seq_file *seq, void *v)
{
put_pid(v);
}
static const struct seq_operations children_seq_ops = {
.start = children_seq_start,
.next = children_seq_next,
.stop = children_seq_stop,
.show = children_seq_show,
};
static int children_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *m;
int ret;
ret = seq_open(file, &children_seq_ops);
if (ret)
return ret;
m = file->private_data;
m->private = inode;
return ret;
}
int children_seq_release(struct inode *inode, struct file *file)
{
seq_release(inode, file);
return 0;
}
const struct file_operations proc_tid_children_operations = {
.open = children_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = children_seq_release,
};
#endif /* CONFIG_CHECKPOINT_RESTORE */
This diff is collapsed.
...@@ -31,8 +31,6 @@ struct vmalloc_info { ...@@ -31,8 +31,6 @@ struct vmalloc_info {
unsigned long largest_chunk; unsigned long largest_chunk;
}; };
extern struct mm_struct *mm_for_maps(struct task_struct *);
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
extern void get_vmalloc_info(struct vmalloc_info *vmi); extern void get_vmalloc_info(struct vmalloc_info *vmi);
...@@ -56,6 +54,7 @@ extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, ...@@ -56,6 +54,7 @@ extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task); struct pid *pid, struct task_struct *task);
extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
extern const struct file_operations proc_tid_children_operations;
extern const struct file_operations proc_pid_maps_operations; extern const struct file_operations proc_pid_maps_operations;
extern const struct file_operations proc_tid_maps_operations; extern const struct file_operations proc_tid_maps_operations;
extern const struct file_operations proc_pid_numa_maps_operations; extern const struct file_operations proc_pid_numa_maps_operations;
......
This diff is collapsed.
...@@ -223,7 +223,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) ...@@ -223,7 +223,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
if (!priv->task) if (!priv->task)
return ERR_PTR(-ESRCH); return ERR_PTR(-ESRCH);
mm = mm_for_maps(priv->task); mm = mm_access(priv->task, PTRACE_MODE_READ);
if (!mm || IS_ERR(mm)) { if (!mm || IS_ERR(mm)) {
put_task_struct(priv->task); put_task_struct(priv->task);
priv->task = NULL; priv->task = NULL;
......
...@@ -633,8 +633,7 @@ ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, ...@@ -633,8 +633,7 @@ ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
unsigned long nr_segs, unsigned long fast_segs, unsigned long nr_segs, unsigned long fast_segs,
struct iovec *fast_pointer, struct iovec *fast_pointer,
struct iovec **ret_pointer, struct iovec **ret_pointer)
int check_access)
{ {
unsigned long seg; unsigned long seg;
ssize_t ret; ssize_t ret;
...@@ -690,7 +689,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, ...@@ -690,7 +689,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (check_access if (type >= 0
&& unlikely(!access_ok(vrfy_dir(type), buf, len))) { && unlikely(!access_ok(vrfy_dir(type), buf, len))) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
...@@ -723,7 +722,7 @@ static ssize_t do_readv_writev(int type, struct file *file, ...@@ -723,7 +722,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
} }
ret = rw_copy_check_uvector(type, uvector, nr_segs, ret = rw_copy_check_uvector(type, uvector, nr_segs,
ARRAY_SIZE(iovstack), iovstack, &iov, 1); ARRAY_SIZE(iovstack), iovstack, &iov);
if (ret <= 0) if (ret <= 0)
goto out; goto out;
......
...@@ -28,5 +28,9 @@ ...@@ -28,5 +28,9 @@
#error Inconsistent word size. Check asm/bitsperlong.h #error Inconsistent word size. Check asm/bitsperlong.h
#endif #endif
#ifndef BITS_PER_LONG_LONG
#define BITS_PER_LONG_LONG 64
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __ASM_GENERIC_BITS_PER_LONG */ #endif /* __ASM_GENERIC_BITS_PER_LONG */
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
{ {
if (size != 0 && nmemb > ULONG_MAX / size) if (size != 0 && nmemb > SIZE_MAX / size)
return NULL; return NULL;
if (size * nmemb <= PAGE_SIZE) if (size * nmemb <= PAGE_SIZE)
...@@ -44,7 +44,7 @@ static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) ...@@ -44,7 +44,7 @@ static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ /* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
{ {
if (size != 0 && nmemb > ULONG_MAX / size) if (size != 0 && nmemb > SIZE_MAX / size)
return NULL; return NULL;
if (size * nmemb <= PAGE_SIZE) if (size * nmemb <= PAGE_SIZE)
......
...@@ -226,6 +226,7 @@ header-y += kdev_t.h ...@@ -226,6 +226,7 @@ header-y += kdev_t.h
header-y += kernel.h header-y += kernel.h
header-y += kernelcapi.h header-y += kernelcapi.h
header-y += kernel-page-flags.h header-y += kernel-page-flags.h
header-y += kexec.h
header-y += keyboard.h header-y += keyboard.h
header-y += keyctl.h header-y += keyctl.h
header-y += l2tp.h header-y += l2tp.h
......
...@@ -577,8 +577,7 @@ extern ssize_t compat_rw_copy_check_uvector(int type, ...@@ -577,8 +577,7 @@ extern ssize_t compat_rw_copy_check_uvector(int type,
const struct compat_iovec __user *uvector, const struct compat_iovec __user *uvector,
unsigned long nr_segs, unsigned long nr_segs,
unsigned long fast_segs, struct iovec *fast_pointer, unsigned long fast_segs, struct iovec *fast_pointer,
struct iovec **ret_pointer, struct iovec **ret_pointer);
int check_access);
extern void __user *compat_alloc_user_space(unsigned long len); extern void __user *compat_alloc_user_space(unsigned long len);
......
...@@ -177,6 +177,7 @@ extern void put_online_cpus(void); ...@@ -177,6 +177,7 @@ extern void put_online_cpus(void);
#define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri)
#define register_hotcpu_notifier(nb) register_cpu_notifier(nb) #define register_hotcpu_notifier(nb) register_cpu_notifier(nb)
#define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu); int cpu_down(unsigned int cpu);
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
......
...@@ -277,17 +277,13 @@ static inline void put_cred(const struct cred *_cred) ...@@ -277,17 +277,13 @@ static inline void put_cred(const struct cred *_cred)
* @task: The task to query * @task: The task to query
* *
* Access the objective credentials of a task. The caller must hold the RCU * Access the objective credentials of a task. The caller must hold the RCU
* readlock or the task must be dead and unable to change its own credentials. * readlock.
* *
* The result of this function should not be passed directly to get_cred(); * The result of this function should not be passed directly to get_cred();
* rather get_task_cred() should be used instead. * rather get_task_cred() should be used instead.
*/ */
#define __task_cred(task) \ #define __task_cred(task) \
({ \ rcu_dereference((task)->real_cred)
const struct task_struct *__t = (task); \
rcu_dereference_check(__t->real_cred, \
task_is_dead(__t)); \
})
/** /**
* get_current_cred - Get the current task's subjective credentials * get_current_cred - Get the current task's subjective credentials
......
...@@ -635,6 +635,18 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( ...@@ -635,6 +635,18 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
dir, flags, NULL); dir, flags, NULL);
} }
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct rio_dma_ext;
static inline struct dma_async_tx_descriptor *dmaengine_prep_rio_sg(
struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
enum dma_transfer_direction dir, unsigned long flags,
struct rio_dma_ext *rio_ext)
{
return chan->device->device_prep_slave_sg(chan, sgl, sg_len,
dir, flags, rio_ext);
}
#endif
static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction dir) size_t period_len, enum dma_transfer_direction dir)
......
...@@ -34,7 +34,7 @@ void eventfd_ctx_put(struct eventfd_ctx *ctx); ...@@ -34,7 +34,7 @@ void eventfd_ctx_put(struct eventfd_ctx *ctx);
struct file *eventfd_fget(int fd); struct file *eventfd_fget(int fd);
struct eventfd_ctx *eventfd_ctx_fdget(int fd); struct eventfd_ctx *eventfd_ctx_fdget(int fd);
struct eventfd_ctx *eventfd_ctx_fileget(struct file *file); struct eventfd_ctx *eventfd_ctx_fileget(struct file *file);
int eventfd_signal(struct eventfd_ctx *ctx, int n); __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n);
ssize_t eventfd_ctx_read(struct eventfd_ctx *ctx, int no_wait, __u64 *cnt); ssize_t eventfd_ctx_read(struct eventfd_ctx *ctx, int no_wait, __u64 *cnt);
int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_t *wait, int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_t *wait,
__u64 *cnt); __u64 *cnt);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment