diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-23 22:42:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-23 22:42:28 -0400 |
commit | 84787c572d402644dca4874aba73324d9f8e3948 (patch) | |
tree | 31783e50b09fee00ee7ff87c0c9708a3c7106482 | |
parent | d62a0234c87f1457a3d2ba519ef90cf164a5eb23 (diff) | |
parent | c5d2cac0f1caaf7dd21350146fb29c55b3e74249 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge yet more updates from Andrew Morton:
- Oleg's "wait/ptrace: assume __WALL if the child is traced". It's a
kernel-based workaround for existing userspace issues.
- A few hotfixes
- befs cleanups
- nilfs2 updates
- sys_wait() changes
- kexec updates
- kdump
- scripts/gdb updates
- the last of the MM queue
- a few other misc things
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (84 commits)
kgdb: depends on VT
drm/amdgpu: make amdgpu_mn_get wait for mmap_sem killable
drm/radeon: make radeon_mn_get wait for mmap_sem killable
drm/i915: make i915_gem_mmap_ioctl wait for mmap_sem killable
uprobes: wait for mmap_sem for write killable
prctl: make PR_SET_THP_DISABLE wait for mmap_sem killable
exec: make exec path waiting for mmap_sem killable
aio: make aio_setup_ring killable
coredump: make coredump_wait wait for mmap_sem for write killable
vdso: make arch_setup_additional_pages wait for mmap_sem for write killable
ipc, shm: make shmem attach/detach wait for mmap_sem killable
mm, fork: make dup_mmap wait for mmap_sem for write killable
mm, proc: make clear_refs killable
mm: make vm_brk killable
mm, elf: handle vm_brk error
mm, aout: handle vm_brk failures
mm: make vm_munmap killable
mm: make vm_mmap killable
mm: make mmap_sem for write waits killable for mm syscalls
MAINTAINERS: add co-maintainer for scripts/gdb
...
129 files changed, 1355 insertions, 786 deletions
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index 41c3d332acc9..5b21ef76f751 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt | |||
@@ -268,3 +268,8 @@ among NILFS2 files can be depicted as follows: | |||
268 | ( regular file, directory, or symlink ) | 268 | ( regular file, directory, or symlink ) |
269 | 269 | ||
270 | For detail on the format of each file, please see include/linux/nilfs2_fs.h. | 270 | For detail on the format of each file, please see include/linux/nilfs2_fs.h. |
271 | |||
272 | There are no patents or other intellectual property that we protect | ||
273 | with regard to the design of NILFS2. It is allowed to replicate the | ||
274 | design in hopes that other operating systems could share (mount, read, | ||
275 | write, etc.) data stored in this format. | ||
diff --git a/Documentation/gdb-kernel-debugging.txt b/Documentation/gdb-kernel-debugging.txt index 7050ce8794b9..4ab7d43d0754 100644 --- a/Documentation/gdb-kernel-debugging.txt +++ b/Documentation/gdb-kernel-debugging.txt | |||
@@ -139,6 +139,27 @@ Examples of using the Linux-provided gdb helpers | |||
139 | start_comm = "swapper/2\000\000\000\000\000\000" | 139 | start_comm = "swapper/2\000\000\000\000\000\000" |
140 | } | 140 | } |
141 | 141 | ||
142 | o Dig into a radix tree data structure, such as the IRQ descriptors: | ||
143 | (gdb) print (struct irq_desc)$lx_radix_tree_lookup(irq_desc_tree, 18) | ||
144 | $6 = { | ||
145 | irq_common_data = { | ||
146 | state_use_accessors = 67584, | ||
147 | handler_data = 0x0 <__vectors_start>, | ||
148 | msi_desc = 0x0 <__vectors_start>, | ||
149 | affinity = {{ | ||
150 | bits = {65535} | ||
151 | }} | ||
152 | }, | ||
153 | irq_data = { | ||
154 | mask = 0, | ||
155 | irq = 18, | ||
156 | hwirq = 27, | ||
157 | common = 0xee803d80, | ||
158 | chip = 0xc0eb0854 <gic_data>, | ||
159 | domain = 0xee808000, | ||
160 | parent_data = 0x0 <__vectors_start>, | ||
161 | chip_data = 0xc0eb0854 <gic_data> | ||
162 | } <... trimmed ...> | ||
142 | 163 | ||
143 | List of commands and functions | 164 | List of commands and functions |
144 | ------------------------------ | 165 | ------------------------------ |
diff --git a/Documentation/kdump/gdbmacros.txt b/Documentation/kdump/gdbmacros.txt index 9b9b454b048a..35f6a982a0d5 100644 --- a/Documentation/kdump/gdbmacros.txt +++ b/Documentation/kdump/gdbmacros.txt | |||
@@ -15,15 +15,16 @@ | |||
15 | 15 | ||
16 | define bttnobp | 16 | define bttnobp |
17 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | 17 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
18 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | 18 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
19 | set $init_t=&init_task | 19 | set $init_t=&init_task |
20 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | 20 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
21 | set var $stacksize = sizeof(union thread_union) | ||
21 | while ($next_t != $init_t) | 22 | while ($next_t != $init_t) |
22 | set $next_t=(struct task_struct *)$next_t | 23 | set $next_t=(struct task_struct *)$next_t |
23 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | 24 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm |
24 | printf "===================\n" | 25 | printf "===================\n" |
25 | set var $stackp = $next_t.thread.esp | 26 | set var $stackp = $next_t.thread.sp |
26 | set var $stack_top = ($stackp & ~4095) + 4096 | 27 | set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize |
27 | 28 | ||
28 | while ($stackp < $stack_top) | 29 | while ($stackp < $stack_top) |
29 | if (*($stackp) > _stext && *($stackp) < _sinittext) | 30 | if (*($stackp) > _stext && *($stackp) < _sinittext) |
@@ -31,13 +32,13 @@ define bttnobp | |||
31 | end | 32 | end |
32 | set $stackp += 4 | 33 | set $stackp += 4 |
33 | end | 34 | end |
34 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | 35 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
35 | while ($next_th != $next_t) | 36 | while ($next_th != $next_t) |
36 | set $next_th=(struct task_struct *)$next_th | 37 | set $next_th=(struct task_struct *)$next_th |
37 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | 38 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm |
38 | printf "===================\n" | 39 | printf "===================\n" |
39 | set var $stackp = $next_t.thread.esp | 40 | set var $stackp = $next_t.thread.sp |
40 | set var $stack_top = ($stackp & ~4095) + 4096 | 41 | set var $stack_top = ($stackp & ~($stacksize - 1)) + stacksize |
41 | 42 | ||
42 | while ($stackp < $stack_top) | 43 | while ($stackp < $stack_top) |
43 | if (*($stackp) > _stext && *($stackp) < _sinittext) | 44 | if (*($stackp) > _stext && *($stackp) < _sinittext) |
@@ -45,7 +46,7 @@ define bttnobp | |||
45 | end | 46 | end |
46 | set $stackp += 4 | 47 | set $stackp += 4 |
47 | end | 48 | end |
48 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | 49 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
49 | end | 50 | end |
50 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | 51 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
51 | end | 52 | end |
@@ -54,42 +55,44 @@ document bttnobp | |||
54 | dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER | 55 | dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER |
55 | end | 56 | end |
56 | 57 | ||
58 | define btthreadstack | ||
59 | set var $pid_task = $arg0 | ||
60 | |||
61 | printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm | ||
62 | printf "task struct: " | ||
63 | print $pid_task | ||
64 | printf "===================\n" | ||
65 | set var $stackp = $pid_task.thread.sp | ||
66 | set var $stacksize = sizeof(union thread_union) | ||
67 | set var $stack_top = ($stackp & ~($stacksize - 1)) + $stacksize | ||
68 | set var $stack_bot = ($stackp & ~($stacksize - 1)) | ||
69 | |||
70 | set $stackp = *((unsigned long *) $stackp) | ||
71 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
72 | set var $addr = *(((unsigned long *) $stackp) + 1) | ||
73 | info symbol $addr | ||
74 | set $stackp = *((unsigned long *) $stackp) | ||
75 | end | ||
76 | end | ||
77 | document btthreadstack | ||
78 | dump a thread stack using the given task structure pointer | ||
79 | end | ||
80 | |||
81 | |||
57 | define btt | 82 | define btt |
58 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | 83 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
59 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | 84 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
60 | set $init_t=&init_task | 85 | set $init_t=&init_task |
61 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | 86 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
62 | while ($next_t != $init_t) | 87 | while ($next_t != $init_t) |
63 | set $next_t=(struct task_struct *)$next_t | 88 | set $next_t=(struct task_struct *)$next_t |
64 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | 89 | btthreadstack $next_t |
65 | printf "===================\n" | ||
66 | set var $stackp = $next_t.thread.esp | ||
67 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
68 | set var $stack_bot = ($stackp & ~4095) | ||
69 | |||
70 | set $stackp = *($stackp) | ||
71 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
72 | set var $addr = *($stackp + 4) | ||
73 | info symbol $addr | ||
74 | set $stackp = *($stackp) | ||
75 | end | ||
76 | 90 | ||
77 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | 91 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
78 | while ($next_th != $next_t) | 92 | while ($next_th != $next_t) |
79 | set $next_th=(struct task_struct *)$next_th | 93 | set $next_th=(struct task_struct *)$next_th |
80 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | 94 | btthreadstack $next_th |
81 | printf "===================\n" | 95 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
82 | set var $stackp = $next_t.thread.esp | ||
83 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
84 | set var $stack_bot = ($stackp & ~4095) | ||
85 | |||
86 | set $stackp = *($stackp) | ||
87 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
88 | set var $addr = *($stackp + 4) | ||
89 | info symbol $addr | ||
90 | set $stackp = *($stackp) | ||
91 | end | ||
92 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | ||
93 | end | 96 | end |
94 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | 97 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
95 | end | 98 | end |
@@ -101,7 +104,7 @@ end | |||
101 | define btpid | 104 | define btpid |
102 | set var $pid = $arg0 | 105 | set var $pid = $arg0 |
103 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | 106 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
104 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | 107 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
105 | set $init_t=&init_task | 108 | set $init_t=&init_task |
106 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | 109 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
107 | set var $pid_task = 0 | 110 | set var $pid_task = 0 |
@@ -113,29 +116,18 @@ define btpid | |||
113 | set $pid_task = $next_t | 116 | set $pid_task = $next_t |
114 | end | 117 | end |
115 | 118 | ||
116 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | 119 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
117 | while ($next_th != $next_t) | 120 | while ($next_th != $next_t) |
118 | set $next_th=(struct task_struct *)$next_th | 121 | set $next_th=(struct task_struct *)$next_th |
119 | if ($next_th.pid == $pid) | 122 | if ($next_th.pid == $pid) |
120 | set $pid_task = $next_th | 123 | set $pid_task = $next_th |
121 | end | 124 | end |
122 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | 125 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
123 | end | 126 | end |
124 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | 127 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
125 | end | 128 | end |
126 | 129 | ||
127 | printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm | 130 | btthreadstack $pid_task |
128 | printf "===================\n" | ||
129 | set var $stackp = $pid_task.thread.esp | ||
130 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
131 | set var $stack_bot = ($stackp & ~4095) | ||
132 | |||
133 | set $stackp = *($stackp) | ||
134 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
135 | set var $addr = *($stackp + 4) | ||
136 | info symbol $addr | ||
137 | set $stackp = *($stackp) | ||
138 | end | ||
139 | end | 131 | end |
140 | document btpid | 132 | document btpid |
141 | backtrace of pid | 133 | backtrace of pid |
@@ -145,7 +137,7 @@ end | |||
145 | define trapinfo | 137 | define trapinfo |
146 | set var $pid = $arg0 | 138 | set var $pid = $arg0 |
147 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | 139 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) |
148 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | 140 | set $pid_off=((size_t)&((struct task_struct *)0)->thread_group.next) |
149 | set $init_t=&init_task | 141 | set $init_t=&init_task |
150 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | 142 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) |
151 | set var $pid_task = 0 | 143 | set var $pid_task = 0 |
@@ -157,13 +149,13 @@ define trapinfo | |||
157 | set $pid_task = $next_t | 149 | set $pid_task = $next_t |
158 | end | 150 | end |
159 | 151 | ||
160 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | 152 | set $next_th=(((char *)$next_t->thread_group.next) - $pid_off) |
161 | while ($next_th != $next_t) | 153 | while ($next_th != $next_t) |
162 | set $next_th=(struct task_struct *)$next_th | 154 | set $next_th=(struct task_struct *)$next_th |
163 | if ($next_th.pid == $pid) | 155 | if ($next_th.pid == $pid) |
164 | set $pid_task = $next_th | 156 | set $pid_task = $next_th |
165 | end | 157 | end |
166 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | 158 | set $next_th=(((char *)$next_th->thread_group.next) - $pid_off) |
167 | end | 159 | end |
168 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | 160 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off |
169 | end | 161 | end |
@@ -5,6 +5,7 @@ | |||
5 | # 2) Generate timeconst.h | 5 | # 2) Generate timeconst.h |
6 | # 3) Generate asm-offsets.h (may need bounds.h and timeconst.h) | 6 | # 3) Generate asm-offsets.h (may need bounds.h and timeconst.h) |
7 | # 4) Check for missing system calls | 7 | # 4) Check for missing system calls |
8 | # 5) Generate constants.py (may need bounds.h) | ||
8 | 9 | ||
9 | # Default sed regexp - multiline due to syntax constraints | 10 | # Default sed regexp - multiline due to syntax constraints |
10 | define sed-y | 11 | define sed-y |
@@ -96,5 +97,14 @@ quiet_cmd_syscalls = CALL $< | |||
96 | missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE | 97 | missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE |
97 | $(call cmd,syscalls) | 98 | $(call cmd,syscalls) |
98 | 99 | ||
100 | ##### | ||
101 | # 5) Generate constants for Python GDB integration | ||
102 | # | ||
103 | |||
104 | extra-$(CONFIG_GDB_SCRIPTS) += build_constants_py | ||
105 | |||
106 | build_constants_py: $(obj)/$(timeconst-file) $(obj)/$(bounds-file) | ||
107 | @$(MAKE) $(build)=scripts/gdb/linux $@ | ||
108 | |||
99 | # Keep these three files during make clean | 109 | # Keep these three files during make clean |
100 | no-clean-files := $(bounds-file) $(offsets-file) $(timeconst-file) | 110 | no-clean-files := $(bounds-file) $(offsets-file) $(timeconst-file) |
diff --git a/MAINTAINERS b/MAINTAINERS index f27ff1b32757..330200688228 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4993,6 +4993,7 @@ F: drivers/scsi/gdt* | |||
4993 | 4993 | ||
4994 | GDB KERNEL DEBUGGING HELPER SCRIPTS | 4994 | GDB KERNEL DEBUGGING HELPER SCRIPTS |
4995 | M: Jan Kiszka <jan.kiszka@siemens.com> | 4995 | M: Jan Kiszka <jan.kiszka@siemens.com> |
4996 | M: Kieran Bingham <kieran@bingham.xyz> | ||
4996 | S: Supported | 4997 | S: Supported |
4997 | F: scripts/gdb/ | 4998 | F: scripts/gdb/ |
4998 | 4999 | ||
@@ -8038,6 +8039,7 @@ NILFS2 FILESYSTEM | |||
8038 | M: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 8039 | M: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> |
8039 | L: linux-nilfs@vger.kernel.org | 8040 | L: linux-nilfs@vger.kernel.org |
8040 | W: http://nilfs.sourceforge.net/ | 8041 | W: http://nilfs.sourceforge.net/ |
8042 | W: http://nilfs.osdn.jp/ | ||
8041 | T: git git://github.com/konis/nilfs2.git | 8043 | T: git git://github.com/konis/nilfs2.git |
8042 | S: Supported | 8044 | S: Supported |
8043 | F: Documentation/filesystems/nilfs2.txt | 8045 | F: Documentation/filesystems/nilfs2.txt |
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index 7117662bab2e..909049a280ec 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig | |||
@@ -12,7 +12,6 @@ CONFIG_CGROUPS=y | |||
12 | CONFIG_CGROUP_FREEZER=y | 12 | CONFIG_CGROUP_FREEZER=y |
13 | CONFIG_CGROUP_DEVICE=y | 13 | CONFIG_CGROUP_DEVICE=y |
14 | CONFIG_CGROUP_CPUACCT=y | 14 | CONFIG_CGROUP_CPUACCT=y |
15 | CONFIG_RESOURCE_COUNTERS=y | ||
16 | CONFIG_CGROUP_SCHED=y | 15 | CONFIG_CGROUP_SCHED=y |
17 | CONFIG_BLK_CGROUP=y | 16 | CONFIG_BLK_CGROUP=y |
18 | CONFIG_NAMESPACES=y | 17 | CONFIG_NAMESPACES=y |
diff --git a/arch/arm/configs/zx_defconfig b/arch/arm/configs/zx_defconfig index ab683fbbb954..d6253a48a9fa 100644 --- a/arch/arm/configs/zx_defconfig +++ b/arch/arm/configs/zx_defconfig | |||
@@ -7,7 +7,6 @@ CONFIG_CGROUPS=y | |||
7 | CONFIG_CGROUP_DEBUG=y | 7 | CONFIG_CGROUP_DEBUG=y |
8 | CONFIG_CGROUP_FREEZER=y | 8 | CONFIG_CGROUP_FREEZER=y |
9 | CONFIG_CGROUP_CPUACCT=y | 9 | CONFIG_CGROUP_CPUACCT=y |
10 | CONFIG_RESOURCE_COUNTERS=y | ||
11 | CONFIG_CGROUP_SCHED=y | 10 | CONFIG_CGROUP_SCHED=y |
12 | CONFIG_RT_GROUP_SCHED=y | 11 | CONFIG_RT_GROUP_SCHED=y |
13 | CONFIG_NAMESPACES=y | 12 | CONFIG_NAMESPACES=y |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index a647d6642f3e..4a803c5a1ff7 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -420,7 +420,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
420 | npages = 1; /* for sigpage */ | 420 | npages = 1; /* for sigpage */ |
421 | npages += vdso_total_pages; | 421 | npages += vdso_total_pages; |
422 | 422 | ||
423 | down_write(&mm->mmap_sem); | 423 | if (down_write_killable(&mm->mmap_sem)) |
424 | return -EINTR; | ||
424 | hint = sigpage_addr(mm, npages); | 425 | hint = sigpage_addr(mm, npages); |
425 | addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0); | 426 | addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0); |
426 | if (IS_ERR_VALUE(addr)) { | 427 | if (IS_ERR_VALUE(addr)) { |
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 64fc030be0f2..9fefb005812a 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
@@ -95,7 +95,8 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) | |||
95 | }; | 95 | }; |
96 | void *ret; | 96 | void *ret; |
97 | 97 | ||
98 | down_write(&mm->mmap_sem); | 98 | if (down_write_killable(&mm->mmap_sem)) |
99 | return -EINTR; | ||
99 | current->mm->context.vdso = (void *)addr; | 100 | current->mm->context.vdso = (void *)addr; |
100 | 101 | ||
101 | /* Map vectors page at the high address. */ | 102 | /* Map vectors page at the high address. */ |
@@ -163,7 +164,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
163 | /* Be sure to map the data page */ | 164 | /* Be sure to map the data page */ |
164 | vdso_mapping_len = vdso_text_len + PAGE_SIZE; | 165 | vdso_mapping_len = vdso_text_len + PAGE_SIZE; |
165 | 166 | ||
166 | down_write(&mm->mmap_sem); | 167 | if (down_write_killable(&mm->mmap_sem)) |
168 | return -EINTR; | ||
167 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); | 169 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); |
168 | if (IS_ERR_VALUE(vdso_base)) { | 170 | if (IS_ERR_VALUE(vdso_base)) { |
169 | ret = ERR_PTR(vdso_base); | 171 | ret = ERR_PTR(vdso_base); |
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c index 0bf5a87e4d0a..3ea968415539 100644 --- a/arch/hexagon/kernel/vdso.c +++ b/arch/hexagon/kernel/vdso.c | |||
@@ -65,7 +65,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
65 | unsigned long vdso_base; | 65 | unsigned long vdso_base; |
66 | struct mm_struct *mm = current->mm; | 66 | struct mm_struct *mm = current->mm; |
67 | 67 | ||
68 | down_write(&mm->mmap_sem); | 68 | if (down_write_killable(&mm->mmap_sem)) |
69 | return -EINTR; | ||
69 | 70 | ||
70 | /* Try to get it loaded right near ld.so/glibc. */ | 71 | /* Try to get it loaded right near ld.so/glibc. */ |
71 | vdso_base = STACK_TOP; | 72 | vdso_base = STACK_TOP; |
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index 62d6961e7f2b..564052e3d3a0 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c | |||
@@ -164,6 +164,7 @@ void smp_flush_cache_all(void) | |||
164 | spin_unlock(&flushcache_lock); | 164 | spin_unlock(&flushcache_lock); |
165 | preempt_enable(); | 165 | preempt_enable(); |
166 | } | 166 | } |
167 | EXPORT_SYMBOL(smp_flush_cache_all); | ||
167 | 168 | ||
168 | void smp_flush_cache_all_interrupt(void) | 169 | void smp_flush_cache_all_interrupt(void) |
169 | { | 170 | { |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8040fb1845b4..46938847e794 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -3117,6 +3117,7 @@ config MIPS32_N32 | |||
3117 | config BINFMT_ELF32 | 3117 | config BINFMT_ELF32 |
3118 | bool | 3118 | bool |
3119 | default y if MIPS32_O32 || MIPS32_N32 | 3119 | default y if MIPS32_O32 || MIPS32_N32 |
3120 | select ELFCORE | ||
3120 | 3121 | ||
3121 | endmenu | 3122 | endmenu |
3122 | 3123 | ||
diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig index 3bdb72a70364..f0c8971030c4 100644 --- a/arch/mips/configs/db1xxx_defconfig +++ b/arch/mips/configs/db1xxx_defconfig | |||
@@ -18,7 +18,6 @@ CONFIG_CGROUP_FREEZER=y | |||
18 | CONFIG_CGROUP_DEVICE=y | 18 | CONFIG_CGROUP_DEVICE=y |
19 | CONFIG_CPUSETS=y | 19 | CONFIG_CPUSETS=y |
20 | CONFIG_CGROUP_CPUACCT=y | 20 | CONFIG_CGROUP_CPUACCT=y |
21 | CONFIG_RESOURCE_COUNTERS=y | ||
22 | CONFIG_MEMCG=y | 21 | CONFIG_MEMCG=y |
23 | CONFIG_MEMCG_SWAP=y | 22 | CONFIG_MEMCG_SWAP=y |
24 | CONFIG_MEMCG_KMEM=y | 23 | CONFIG_MEMCG_KMEM=y |
diff --git a/arch/mips/configs/loongson3_defconfig b/arch/mips/configs/loongson3_defconfig index f8bf915c6d6b..7f95c4b3ab2c 100644 --- a/arch/mips/configs/loongson3_defconfig +++ b/arch/mips/configs/loongson3_defconfig | |||
@@ -25,7 +25,6 @@ CONFIG_TASK_XACCT=y | |||
25 | CONFIG_TASK_IO_ACCOUNTING=y | 25 | CONFIG_TASK_IO_ACCOUNTING=y |
26 | CONFIG_LOG_BUF_SHIFT=14 | 26 | CONFIG_LOG_BUF_SHIFT=14 |
27 | CONFIG_CPUSETS=y | 27 | CONFIG_CPUSETS=y |
28 | CONFIG_RESOURCE_COUNTERS=y | ||
29 | CONFIG_MEMCG=y | 28 | CONFIG_MEMCG=y |
30 | CONFIG_MEMCG_SWAP=y | 29 | CONFIG_MEMCG_SWAP=y |
31 | CONFIG_BLK_CGROUP=y | 30 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 975e99759bab..54e1663ce639 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c | |||
@@ -104,7 +104,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
104 | struct resource gic_res; | 104 | struct resource gic_res; |
105 | int ret; | 105 | int ret; |
106 | 106 | ||
107 | down_write(&mm->mmap_sem); | 107 | if (down_write_killable(&mm->mmap_sem)) |
108 | return -EINTR; | ||
108 | 109 | ||
109 | /* | 110 | /* |
110 | * Determine total area size. This includes the VDSO data itself, the | 111 | * Determine total area size. This includes the VDSO data itself, the |
diff --git a/arch/mn10300/configs/asb2364_defconfig b/arch/mn10300/configs/asb2364_defconfig index fbb96ae3122a..cd0a6cb17dee 100644 --- a/arch/mn10300/configs/asb2364_defconfig +++ b/arch/mn10300/configs/asb2364_defconfig | |||
@@ -11,7 +11,6 @@ CONFIG_CGROUPS=y | |||
11 | CONFIG_CGROUP_FREEZER=y | 11 | CONFIG_CGROUP_FREEZER=y |
12 | CONFIG_CGROUP_DEVICE=y | 12 | CONFIG_CGROUP_DEVICE=y |
13 | CONFIG_CGROUP_CPUACCT=y | 13 | CONFIG_CGROUP_CPUACCT=y |
14 | CONFIG_RESOURCE_COUNTERS=y | ||
15 | CONFIG_RELAY=y | 14 | CONFIG_RELAY=y |
16 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 15 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
17 | CONFIG_EXPERT=y | 16 | CONFIG_EXPERT=y |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index def1b8b5e6c1..6767605ea8da 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -195,7 +195,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
195 | * and end up putting it elsewhere. | 195 | * and end up putting it elsewhere. |
196 | * Add enough to the size so that the result can be aligned. | 196 | * Add enough to the size so that the result can be aligned. |
197 | */ | 197 | */ |
198 | down_write(&mm->mmap_sem); | 198 | if (down_write_killable(&mm->mmap_sem)) |
199 | return -EINTR; | ||
199 | vdso_base = get_unmapped_area(NULL, vdso_base, | 200 | vdso_base = get_unmapped_area(NULL, vdso_base, |
200 | (vdso_pages << PAGE_SHIFT) + | 201 | (vdso_pages << PAGE_SHIFT) + |
201 | ((VDSO_ALIGNMENT - 1) & PAGE_MASK), | 202 | ((VDSO_ALIGNMENT - 1) & PAGE_MASK), |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 2f1b7217c25c..0e64f08d3d69 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -43,13 +43,13 @@ static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, | |||
43 | switch (action) { | 43 | switch (action) { |
44 | case PM_SUSPEND_PREPARE: | 44 | case PM_SUSPEND_PREPARE: |
45 | case PM_HIBERNATION_PREPARE: | 45 | case PM_HIBERNATION_PREPARE: |
46 | if (crashk_res.start) | 46 | if (kexec_crash_image) |
47 | crash_map_reserved_pages(); | 47 | arch_kexec_unprotect_crashkres(); |
48 | break; | 48 | break; |
49 | case PM_POST_SUSPEND: | 49 | case PM_POST_SUSPEND: |
50 | case PM_POST_HIBERNATION: | 50 | case PM_POST_HIBERNATION: |
51 | if (crashk_res.start) | 51 | if (kexec_crash_image) |
52 | crash_unmap_reserved_pages(); | 52 | arch_kexec_protect_crashkres(); |
53 | break; | 53 | break; |
54 | default: | 54 | default: |
55 | return NOTIFY_DONE; | 55 | return NOTIFY_DONE; |
@@ -60,6 +60,8 @@ static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, | |||
60 | static int __init machine_kdump_pm_init(void) | 60 | static int __init machine_kdump_pm_init(void) |
61 | { | 61 | { |
62 | pm_notifier(machine_kdump_pm_cb, 0); | 62 | pm_notifier(machine_kdump_pm_cb, 0); |
63 | /* Create initial mapping for crashkernel memory */ | ||
64 | arch_kexec_unprotect_crashkres(); | ||
63 | return 0; | 65 | return 0; |
64 | } | 66 | } |
65 | arch_initcall(machine_kdump_pm_init); | 67 | arch_initcall(machine_kdump_pm_init); |
@@ -146,6 +148,8 @@ static int kdump_csum_valid(struct kimage *image) | |||
146 | #endif | 148 | #endif |
147 | } | 149 | } |
148 | 150 | ||
151 | #ifdef CONFIG_CRASH_DUMP | ||
152 | |||
149 | /* | 153 | /* |
150 | * Map or unmap crashkernel memory | 154 | * Map or unmap crashkernel memory |
151 | */ | 155 | */ |
@@ -167,21 +171,25 @@ static void crash_map_pages(int enable) | |||
167 | } | 171 | } |
168 | 172 | ||
169 | /* | 173 | /* |
170 | * Map crashkernel memory | 174 | * Unmap crashkernel memory |
171 | */ | 175 | */ |
172 | void crash_map_reserved_pages(void) | 176 | void arch_kexec_protect_crashkres(void) |
173 | { | 177 | { |
174 | crash_map_pages(1); | 178 | if (crashk_res.end) |
179 | crash_map_pages(0); | ||
175 | } | 180 | } |
176 | 181 | ||
177 | /* | 182 | /* |
178 | * Unmap crashkernel memory | 183 | * Map crashkernel memory |
179 | */ | 184 | */ |
180 | void crash_unmap_reserved_pages(void) | 185 | void arch_kexec_unprotect_crashkres(void) |
181 | { | 186 | { |
182 | crash_map_pages(0); | 187 | if (crashk_res.end) |
188 | crash_map_pages(1); | ||
183 | } | 189 | } |
184 | 190 | ||
191 | #endif | ||
192 | |||
185 | /* | 193 | /* |
186 | * Give back memory to hypervisor before new kdump is loaded | 194 | * Give back memory to hypervisor before new kdump is loaded |
187 | */ | 195 | */ |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 94495cac8be3..5904abf6b1ae 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -216,7 +216,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
216 | * it at vdso_base which is the "natural" base for it, but we might | 216 | * it at vdso_base which is the "natural" base for it, but we might |
217 | * fail and end up putting it elsewhere. | 217 | * fail and end up putting it elsewhere. |
218 | */ | 218 | */ |
219 | down_write(&mm->mmap_sem); | 219 | if (down_write_killable(&mm->mmap_sem)) |
220 | return -EINTR; | ||
220 | vdso_base = get_unmapped_area(NULL, 0, vdso_pages << PAGE_SHIFT, 0, 0); | 221 | vdso_base = get_unmapped_area(NULL, 0, vdso_pages << PAGE_SHIFT, 0, 0); |
221 | if (IS_ERR_VALUE(vdso_base)) { | 222 | if (IS_ERR_VALUE(vdso_base)) { |
222 | rc = vdso_base; | 223 | rc = vdso_base; |
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index a8d975793b6d..fe45d2c9b151 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig | |||
@@ -10,7 +10,6 @@ CONFIG_CGROUPS=y | |||
10 | CONFIG_CGROUP_FREEZER=y | 10 | CONFIG_CGROUP_FREEZER=y |
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
13 | CONFIG_RESOURCE_COUNTERS=y | ||
14 | CONFIG_CGROUP_MEMCG=y | 13 | CONFIG_CGROUP_MEMCG=y |
15 | CONFIG_BLK_CGROUP=y | 14 | CONFIG_BLK_CGROUP=y |
16 | CONFIG_NAMESPACES=y | 15 | CONFIG_NAMESPACES=y |
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index e7e56a4131b4..36642ec2cb97 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig | |||
@@ -17,7 +17,6 @@ CONFIG_CGROUP_DEVICE=y | |||
17 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
18 | # CONFIG_PROC_PID_CPUSET is not set | 18 | # CONFIG_PROC_PID_CPUSET is not set |
19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
20 | CONFIG_RESOURCE_COUNTERS=y | ||
21 | CONFIG_CGROUP_MEMCG=y | 20 | CONFIG_CGROUP_MEMCG=y |
22 | CONFIG_CGROUP_MEMCG_SWAP=y | 21 | CONFIG_CGROUP_MEMCG_SWAP=y |
23 | CONFIG_CGROUP_SCHED=y | 22 | CONFIG_CGROUP_SCHED=y |
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 6bc30ab9fd18..91853a67ec34 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig | |||
@@ -10,7 +10,6 @@ CONFIG_CGROUPS=y | |||
10 | CONFIG_CGROUP_DEBUG=y | 10 | CONFIG_CGROUP_DEBUG=y |
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
13 | CONFIG_RESOURCE_COUNTERS=y | ||
14 | CONFIG_CGROUP_MEMCG=y | 13 | CONFIG_CGROUP_MEMCG=y |
15 | CONFIG_RELAY=y | 14 | CONFIG_RELAY=y |
16 | CONFIG_NAMESPACES=y | 15 | CONFIG_NAMESPACES=y |
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index cd6c519f8fad..4a4269ad5b04 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig | |||
@@ -12,7 +12,6 @@ CONFIG_CGROUPS=y | |||
12 | CONFIG_CGROUP_FREEZER=y | 12 | CONFIG_CGROUP_FREEZER=y |
13 | CONFIG_CGROUP_DEVICE=y | 13 | CONFIG_CGROUP_DEVICE=y |
14 | CONFIG_CGROUP_CPUACCT=y | 14 | CONFIG_CGROUP_CPUACCT=y |
15 | CONFIG_RESOURCE_COUNTERS=y | ||
16 | CONFIG_CGROUP_MEMCG=y | 15 | CONFIG_CGROUP_MEMCG=y |
17 | CONFIG_RELAY=y | 16 | CONFIG_RELAY=y |
18 | CONFIG_NAMESPACES=y | 17 | CONFIG_NAMESPACES=y |
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 1e843dbed5f0..01c9a91ee896 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig | |||
@@ -14,7 +14,6 @@ CONFIG_CGROUP_DEVICE=y | |||
14 | CONFIG_CPUSETS=y | 14 | CONFIG_CPUSETS=y |
15 | # CONFIG_PROC_PID_CPUSET is not set | 15 | # CONFIG_PROC_PID_CPUSET is not set |
16 | CONFIG_CGROUP_CPUACCT=y | 16 | CONFIG_CGROUP_CPUACCT=y |
17 | CONFIG_RESOURCE_COUNTERS=y | ||
18 | CONFIG_CGROUP_MEMCG=y | 17 | CONFIG_CGROUP_MEMCG=y |
19 | CONFIG_CGROUP_MEMCG_SWAP=y | 18 | CONFIG_CGROUP_MEMCG_SWAP=y |
20 | CONFIG_CGROUP_SCHED=y | 19 | CONFIG_CGROUP_SCHED=y |
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index ea2aa1393b87..cc0cc5b4ff18 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c | |||
@@ -64,7 +64,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
64 | unsigned long addr; | 64 | unsigned long addr; |
65 | int ret; | 65 | int ret; |
66 | 66 | ||
67 | down_write(&mm->mmap_sem); | 67 | if (down_write_killable(&mm->mmap_sem)) |
68 | return -EINTR; | ||
69 | |||
68 | addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); | 70 | addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); |
69 | if (IS_ERR_VALUE(addr)) { | 71 | if (IS_ERR_VALUE(addr)) { |
70 | ret = addr; | 72 | ret = addr; |
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index dea47c31ab16..fd122ef45b00 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig | |||
@@ -16,7 +16,6 @@ CONFIG_CGROUP_DEBUG=y | |||
16 | CONFIG_CGROUP_DEVICE=y | 16 | CONFIG_CGROUP_DEVICE=y |
17 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
18 | CONFIG_CGROUP_CPUACCT=y | 18 | CONFIG_CGROUP_CPUACCT=y |
19 | CONFIG_RESOURCE_COUNTERS=y | ||
20 | CONFIG_CGROUP_SCHED=y | 19 | CONFIG_CGROUP_SCHED=y |
21 | CONFIG_RT_GROUP_SCHED=y | 20 | CONFIG_RT_GROUP_SCHED=y |
22 | CONFIG_BLK_CGROUP=y | 21 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 95743eedf747..eb6a55944191 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig | |||
@@ -15,7 +15,6 @@ CONFIG_CGROUP_DEBUG=y | |||
15 | CONFIG_CGROUP_DEVICE=y | 15 | CONFIG_CGROUP_DEVICE=y |
16 | CONFIG_CPUSETS=y | 16 | CONFIG_CPUSETS=y |
17 | CONFIG_CGROUP_CPUACCT=y | 17 | CONFIG_CGROUP_CPUACCT=y |
18 | CONFIG_RESOURCE_COUNTERS=y | ||
19 | CONFIG_CGROUP_SCHED=y | 18 | CONFIG_CGROUP_SCHED=y |
20 | CONFIG_RT_GROUP_SCHED=y | 19 | CONFIG_RT_GROUP_SCHED=y |
21 | CONFIG_BLK_CGROUP=y | 20 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index a12bf68c9f3a..5636221b8785 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig | |||
@@ -17,7 +17,6 @@ CONFIG_CGROUP_FREEZER=y | |||
17 | CONFIG_CGROUP_DEVICE=y | 17 | CONFIG_CGROUP_DEVICE=y |
18 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
20 | CONFIG_RESOURCE_COUNTERS=y | ||
21 | CONFIG_CGROUP_SCHED=y | 20 | CONFIG_CGROUP_SCHED=y |
22 | CONFIG_BLK_CGROUP=y | 21 | CONFIG_BLK_CGROUP=y |
23 | # CONFIG_PID_NS is not set | 22 | # CONFIG_PID_NS is not set |
diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index 3aab117bd553..7a67b7ac1a7e 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig | |||
@@ -15,7 +15,6 @@ CONFIG_CGROUP_FREEZER=y | |||
15 | CONFIG_CGROUP_DEVICE=y | 15 | CONFIG_CGROUP_DEVICE=y |
16 | CONFIG_CPUSETS=y | 16 | CONFIG_CPUSETS=y |
17 | CONFIG_CGROUP_CPUACCT=y | 17 | CONFIG_CGROUP_CPUACCT=y |
18 | CONFIG_RESOURCE_COUNTERS=y | ||
19 | CONFIG_CGROUP_SCHED=y | 18 | CONFIG_CGROUP_SCHED=y |
20 | CONFIG_BLK_CGROUP=y | 19 | CONFIG_BLK_CGROUP=y |
21 | # CONFIG_PID_NS is not set | 20 | # CONFIG_PID_NS is not set |
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 265901a84f3f..5fa6ee2c2dde 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig | |||
@@ -17,7 +17,6 @@ CONFIG_CGROUPS=y | |||
17 | CONFIG_CGROUP_FREEZER=y | 17 | CONFIG_CGROUP_FREEZER=y |
18 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
20 | CONFIG_RESOURCE_COUNTERS=y | ||
21 | CONFIG_CGROUP_SCHED=y | 20 | CONFIG_CGROUP_SCHED=y |
22 | CONFIG_BLK_DEV_INITRD=y | 21 | CONFIG_BLK_DEV_INITRD=y |
23 | # CONFIG_COMPAT_BRK is not set | 22 | # CONFIG_COMPAT_BRK is not set |
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 0c8d7963483c..d28bdabcc87e 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig | |||
@@ -16,7 +16,6 @@ CONFIG_CGROUPS=y | |||
16 | CONFIG_CGROUP_FREEZER=y | 16 | CONFIG_CGROUP_FREEZER=y |
17 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
18 | CONFIG_CGROUP_CPUACCT=y | 18 | CONFIG_CGROUP_CPUACCT=y |
19 | CONFIG_RESOURCE_COUNTERS=y | ||
20 | CONFIG_CGROUP_SCHED=y | 19 | CONFIG_CGROUP_SCHED=y |
21 | CONFIG_BLK_DEV_INITRD=y | 20 | CONFIG_BLK_DEV_INITRD=y |
22 | # CONFIG_COMPAT_BRK is not set | 21 | # CONFIG_COMPAT_BRK is not set |
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index b3cf81333a54..ab220ac9b3b9 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c | |||
@@ -163,7 +163,8 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) | |||
163 | addr = 0; | 163 | addr = 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | down_write(&mm->mmap_sem); | 166 | if (down_write_killable(&mm->mmap_sem)) |
167 | return -EINTR; | ||
167 | 168 | ||
168 | addr = get_unmapped_area(NULL, addr, | 169 | addr = get_unmapped_area(NULL, addr, |
169 | image->size - image->sym_vvar_start, 0, 0); | 170 | image->size - image->sym_vvar_start, 0, 0); |
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index ae6aad1d24f7..f5e737ff0022 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
@@ -116,13 +116,13 @@ static struct linux_binfmt aout_format = { | |||
116 | .min_coredump = PAGE_SIZE | 116 | .min_coredump = PAGE_SIZE |
117 | }; | 117 | }; |
118 | 118 | ||
119 | static void set_brk(unsigned long start, unsigned long end) | 119 | static unsigned long set_brk(unsigned long start, unsigned long end) |
120 | { | 120 | { |
121 | start = PAGE_ALIGN(start); | 121 | start = PAGE_ALIGN(start); |
122 | end = PAGE_ALIGN(end); | 122 | end = PAGE_ALIGN(end); |
123 | if (end <= start) | 123 | if (end <= start) |
124 | return; | 124 | return start; |
125 | vm_brk(start, end - start); | 125 | return vm_brk(start, end - start); |
126 | } | 126 | } |
127 | 127 | ||
128 | #ifdef CONFIG_COREDUMP | 128 | #ifdef CONFIG_COREDUMP |
@@ -349,7 +349,10 @@ static int load_aout_binary(struct linux_binprm *bprm) | |||
349 | #endif | 349 | #endif |
350 | 350 | ||
351 | if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { | 351 | if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { |
352 | vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); | 352 | error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); |
353 | if (IS_ERR_VALUE(error)) | ||
354 | return error; | ||
355 | |||
353 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, | 356 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, |
354 | ex.a_text+ex.a_data); | 357 | ex.a_text+ex.a_data); |
355 | goto beyond_if; | 358 | goto beyond_if; |
@@ -372,10 +375,13 @@ static int load_aout_binary(struct linux_binprm *bprm) | |||
372 | if (error != N_DATADDR(ex)) | 375 | if (error != N_DATADDR(ex)) |
373 | return error; | 376 | return error; |
374 | } | 377 | } |
378 | |||
375 | beyond_if: | 379 | beyond_if: |
376 | set_binfmt(&aout_format); | 380 | error = set_brk(current->mm->start_brk, current->mm->brk); |
381 | if (IS_ERR_VALUE(error)) | ||
382 | return error; | ||
377 | 383 | ||
378 | set_brk(current->mm->start_brk, current->mm->brk); | 384 | set_binfmt(&aout_format); |
379 | 385 | ||
380 | current->mm->start_stack = | 386 | current->mm->start_stack = |
381 | (unsigned long)create_aout_tables((char __user *)bprm->p, bprm); | 387 | (unsigned long)create_aout_tables((char __user *)bprm->p, bprm); |
@@ -434,7 +440,9 @@ static int load_aout_library(struct file *file) | |||
434 | error_time = jiffies; | 440 | error_time = jiffies; |
435 | } | 441 | } |
436 | #endif | 442 | #endif |
437 | vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); | 443 | retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); |
444 | if (IS_ERR_VALUE(retval)) | ||
445 | goto out; | ||
438 | 446 | ||
439 | read_code(file, start_addr, N_TXTOFF(ex), | 447 | read_code(file, start_addr, N_TXTOFF(ex), |
440 | ex.a_text + ex.a_data); | 448 | ex.a_text + ex.a_data); |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index ba7fbba9831b..5a294e48b185 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
@@ -538,3 +538,48 @@ overflow: | |||
538 | return -ENOEXEC; | 538 | return -ENOEXEC; |
539 | } | 539 | } |
540 | #endif /* CONFIG_KEXEC_FILE */ | 540 | #endif /* CONFIG_KEXEC_FILE */ |
541 | |||
542 | static int | ||
543 | kexec_mark_range(unsigned long start, unsigned long end, bool protect) | ||
544 | { | ||
545 | struct page *page; | ||
546 | unsigned int nr_pages; | ||
547 | |||
548 | /* | ||
549 | * For physical range: [start, end]. We must skip the unassigned | ||
550 | * crashk resource with zero-valued "end" member. | ||
551 | */ | ||
552 | if (!end || start > end) | ||
553 | return 0; | ||
554 | |||
555 | page = pfn_to_page(start >> PAGE_SHIFT); | ||
556 | nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1; | ||
557 | if (protect) | ||
558 | return set_pages_ro(page, nr_pages); | ||
559 | else | ||
560 | return set_pages_rw(page, nr_pages); | ||
561 | } | ||
562 | |||
563 | static void kexec_mark_crashkres(bool protect) | ||
564 | { | ||
565 | unsigned long control; | ||
566 | |||
567 | kexec_mark_range(crashk_low_res.start, crashk_low_res.end, protect); | ||
568 | |||
569 | /* Don't touch the control code page used in crash_kexec().*/ | ||
570 | control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page)); | ||
571 | /* Control code page is located in the 2nd page. */ | ||
572 | kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect); | ||
573 | control += KEXEC_CONTROL_PAGE_SIZE; | ||
574 | kexec_mark_range(control, crashk_res.end, protect); | ||
575 | } | ||
576 | |||
577 | void arch_kexec_protect_crashkres(void) | ||
578 | { | ||
579 | kexec_mark_crashkres(true); | ||
580 | } | ||
581 | |||
582 | void arch_kexec_unprotect_crashkres(void) | ||
583 | { | ||
584 | kexec_mark_crashkres(false); | ||
585 | } | ||
diff --git a/arch/x86/um/vdso/vma.c b/arch/x86/um/vdso/vma.c index 237c6831e095..6be22f991b59 100644 --- a/arch/x86/um/vdso/vma.c +++ b/arch/x86/um/vdso/vma.c | |||
@@ -61,7 +61,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
61 | if (!vdso_enabled) | 61 | if (!vdso_enabled) |
62 | return 0; | 62 | return 0; |
63 | 63 | ||
64 | down_write(&mm->mmap_sem); | 64 | if (down_write_killable(&mm->mmap_sem)) |
65 | return -EINTR; | ||
65 | 66 | ||
66 | err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, | 67 | err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, |
67 | VM_READ|VM_EXEC| | 68 | VM_READ|VM_EXEC| |
diff --git a/arch/xtensa/configs/generic_kc705_defconfig b/arch/xtensa/configs/generic_kc705_defconfig index f4b7b3888da8..d9444f01f4da 100644 --- a/arch/xtensa/configs/generic_kc705_defconfig +++ b/arch/xtensa/configs/generic_kc705_defconfig | |||
@@ -11,7 +11,6 @@ CONFIG_CGROUP_FREEZER=y | |||
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CPUSETS=y | 12 | CONFIG_CPUSETS=y |
13 | CONFIG_CGROUP_CPUACCT=y | 13 | CONFIG_CGROUP_CPUACCT=y |
14 | CONFIG_RESOURCE_COUNTERS=y | ||
15 | CONFIG_MEMCG=y | 14 | CONFIG_MEMCG=y |
16 | CONFIG_NAMESPACES=y | 15 | CONFIG_NAMESPACES=y |
17 | CONFIG_SCHED_AUTOGROUP=y | 16 | CONFIG_SCHED_AUTOGROUP=y |
diff --git a/arch/xtensa/configs/smp_lx200_defconfig b/arch/xtensa/configs/smp_lx200_defconfig index 22eeacba37cc..61f943c95619 100644 --- a/arch/xtensa/configs/smp_lx200_defconfig +++ b/arch/xtensa/configs/smp_lx200_defconfig | |||
@@ -11,7 +11,6 @@ CONFIG_CGROUP_FREEZER=y | |||
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CPUSETS=y | 12 | CONFIG_CPUSETS=y |
13 | CONFIG_CGROUP_CPUACCT=y | 13 | CONFIG_CGROUP_CPUACCT=y |
14 | CONFIG_RESOURCE_COUNTERS=y | ||
15 | CONFIG_MEMCG=y | 14 | CONFIG_MEMCG=y |
16 | CONFIG_NAMESPACES=y | 15 | CONFIG_NAMESPACES=y |
17 | CONFIG_SCHED_AUTOGROUP=y | 16 | CONFIG_SCHED_AUTOGROUP=y |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index 9f4a45cd2aab..32fa7b7913f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | |||
@@ -232,7 +232,10 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) | |||
232 | int r; | 232 | int r; |
233 | 233 | ||
234 | mutex_lock(&adev->mn_lock); | 234 | mutex_lock(&adev->mn_lock); |
235 | down_write(&mm->mmap_sem); | 235 | if (down_write_killable(&mm->mmap_sem)) { |
236 | mutex_unlock(&adev->mn_lock); | ||
237 | return ERR_PTR(-EINTR); | ||
238 | } | ||
236 | 239 | ||
237 | hash_for_each_possible(adev->mn_hash, rmn, node, (unsigned long)mm) | 240 | hash_for_each_possible(adev->mn_hash, rmn, node, (unsigned long)mm) |
238 | if (rmn->mm == mm) | 241 | if (rmn->mm == mm) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 94bbc4314ac5..9b99490e8367 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1721,7 +1721,10 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1721 | struct mm_struct *mm = current->mm; | 1721 | struct mm_struct *mm = current->mm; |
1722 | struct vm_area_struct *vma; | 1722 | struct vm_area_struct *vma; |
1723 | 1723 | ||
1724 | down_write(&mm->mmap_sem); | 1724 | if (down_write_killable(&mm->mmap_sem)) { |
1725 | drm_gem_object_unreference_unlocked(obj); | ||
1726 | return -EINTR; | ||
1727 | } | ||
1725 | vma = find_vma(mm, addr); | 1728 | vma = find_vma(mm, addr); |
1726 | if (vma) | 1729 | if (vma) |
1727 | vma->vm_page_prot = | 1730 | vma->vm_page_prot = |
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c index eef006c48584..896f2cf51e4e 100644 --- a/drivers/gpu/drm/radeon/radeon_mn.c +++ b/drivers/gpu/drm/radeon/radeon_mn.c | |||
@@ -186,7 +186,9 @@ static struct radeon_mn *radeon_mn_get(struct radeon_device *rdev) | |||
186 | struct radeon_mn *rmn; | 186 | struct radeon_mn *rmn; |
187 | int r; | 187 | int r; |
188 | 188 | ||
189 | down_write(&mm->mmap_sem); | 189 | if (down_write_killable(&mm->mmap_sem)) |
190 | return ERR_PTR(-EINTR); | ||
191 | |||
190 | mutex_lock(&rdev->mn_lock); | 192 | mutex_lock(&rdev->mn_lock); |
191 | 193 | ||
192 | hash_for_each_possible(rdev->mn_hash, rmn, node, (unsigned long)mm) | 194 | hash_for_each_possible(rdev->mn_hash, rmn, node, (unsigned long)mm) |
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 922a750640e8..0fb27d338811 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c | |||
@@ -1033,12 +1033,11 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1033 | } | 1033 | } |
1034 | msb->attr_group.name = "media_attributes"; | 1034 | msb->attr_group.name = "media_attributes"; |
1035 | 1035 | ||
1036 | buffer = kmalloc(attr_len, GFP_KERNEL); | 1036 | buffer = kmemdup(attr, attr_len, GFP_KERNEL); |
1037 | if (!buffer) { | 1037 | if (!buffer) { |
1038 | rc = -ENOMEM; | 1038 | rc = -ENOMEM; |
1039 | goto out_free_attr; | 1039 | goto out_free_attr; |
1040 | } | 1040 | } |
1041 | memcpy(buffer, (char *)attr, attr_len); | ||
1042 | 1041 | ||
1043 | for (cnt = 0; cnt < attr_count; ++cnt) { | 1042 | for (cnt = 0; cnt < attr_count; ++cnt) { |
1044 | s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL); | 1043 | s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL); |
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index 1105db2355d2..d34bc3530385 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c | |||
@@ -706,7 +706,7 @@ poll_again: | |||
706 | if (host->eject) | 706 | if (host->eject) |
707 | break; | 707 | break; |
708 | 708 | ||
709 | msleep(1000); | 709 | schedule_timeout_idle(HZ); |
710 | } | 710 | } |
711 | 711 | ||
712 | complete(&host->detect_ms_exit); | 712 | complete(&host->detect_ms_exit); |
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 2d0cbbd14cfc..72c03354c14b 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -1,6 +1,7 @@ | |||
1 | config BINFMT_ELF | 1 | config BINFMT_ELF |
2 | bool "Kernel support for ELF binaries" | 2 | bool "Kernel support for ELF binaries" |
3 | depends on MMU && (BROKEN || !FRV) | 3 | depends on MMU && (BROKEN || !FRV) |
4 | select ELFCORE | ||
4 | default y | 5 | default y |
5 | ---help--- | 6 | ---help--- |
6 | ELF (Executable and Linkable Format) is a format for libraries and | 7 | ELF (Executable and Linkable Format) is a format for libraries and |
@@ -26,6 +27,7 @@ config BINFMT_ELF | |||
26 | config COMPAT_BINFMT_ELF | 27 | config COMPAT_BINFMT_ELF |
27 | bool | 28 | bool |
28 | depends on COMPAT && BINFMT_ELF | 29 | depends on COMPAT && BINFMT_ELF |
30 | select ELFCORE | ||
29 | 31 | ||
30 | config ARCH_BINFMT_ELF_STATE | 32 | config ARCH_BINFMT_ELF_STATE |
31 | bool | 33 | bool |
@@ -34,6 +36,7 @@ config BINFMT_ELF_FDPIC | |||
34 | bool "Kernel support for FDPIC ELF binaries" | 36 | bool "Kernel support for FDPIC ELF binaries" |
35 | default y | 37 | default y |
36 | depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || C6X) | 38 | depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || C6X) |
39 | select ELFCORE | ||
37 | help | 40 | help |
38 | ELF FDPIC binaries are based on ELF, but allow the individual load | 41 | ELF FDPIC binaries are based on ELF, but allow the individual load |
39 | segments of a binary to be located in memory independently of each | 42 | segments of a binary to be located in memory independently of each |
@@ -43,6 +46,11 @@ config BINFMT_ELF_FDPIC | |||
43 | 46 | ||
44 | It is also possible to run FDPIC ELF binaries on MMU linux also. | 47 | It is also possible to run FDPIC ELF binaries on MMU linux also. |
45 | 48 | ||
49 | config ELFCORE | ||
50 | bool | ||
51 | help | ||
52 | This option enables kernel/elfcore.o. | ||
53 | |||
46 | config CORE_DUMP_DEFAULT_ELF_HEADERS | 54 | config CORE_DUMP_DEFAULT_ELF_HEADERS |
47 | bool "Write ELF core dumps with partial segments" | 55 | bool "Write ELF core dumps with partial segments" |
48 | default y | 56 | default y |
@@ -496,7 +496,12 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
496 | ctx->mmap_size = nr_pages * PAGE_SIZE; | 496 | ctx->mmap_size = nr_pages * PAGE_SIZE; |
497 | pr_debug("attempting mmap of %lu bytes\n", ctx->mmap_size); | 497 | pr_debug("attempting mmap of %lu bytes\n", ctx->mmap_size); |
498 | 498 | ||
499 | down_write(&mm->mmap_sem); | 499 | if (down_write_killable(&mm->mmap_sem)) { |
500 | ctx->mmap_size = 0; | ||
501 | aio_free_ring(ctx); | ||
502 | return -EINTR; | ||
503 | } | ||
504 | |||
500 | ctx->mmap_base = do_mmap_pgoff(ctx->aio_ring_file, 0, ctx->mmap_size, | 505 | ctx->mmap_base = do_mmap_pgoff(ctx->aio_ring_file, 0, ctx->mmap_size, |
501 | PROT_READ | PROT_WRITE, | 506 | PROT_READ | PROT_WRITE, |
502 | MAP_SHARED, 0, &unused); | 507 | MAP_SHARED, 0, &unused); |
diff --git a/fs/befs/datastream.c b/fs/befs/datastream.c index dde0b79f3948..af1bc19b7c85 100644 --- a/fs/befs/datastream.c +++ b/fs/befs/datastream.c | |||
@@ -48,7 +48,7 @@ struct buffer_head * | |||
48 | befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, | 48 | befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, |
49 | befs_off_t pos, uint * off) | 49 | befs_off_t pos, uint * off) |
50 | { | 50 | { |
51 | struct buffer_head *bh = NULL; | 51 | struct buffer_head *bh; |
52 | befs_block_run run; | 52 | befs_block_run run; |
53 | befs_blocknr_t block; /* block coresponding to pos */ | 53 | befs_blocknr_t block; /* block coresponding to pos */ |
54 | 54 | ||
@@ -127,7 +127,7 @@ befs_read_lsymlink(struct super_block *sb, const befs_data_stream *ds, | |||
127 | { | 127 | { |
128 | befs_off_t bytes_read = 0; /* bytes readed */ | 128 | befs_off_t bytes_read = 0; /* bytes readed */ |
129 | u16 plen; | 129 | u16 plen; |
130 | struct buffer_head *bh = NULL; | 130 | struct buffer_head *bh; |
131 | befs_debug(sb, "---> %s length: %llu", __func__, len); | 131 | befs_debug(sb, "---> %s length: %llu", __func__, len); |
132 | 132 | ||
133 | while (bytes_read < len) { | 133 | while (bytes_read < len) { |
@@ -429,7 +429,7 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
429 | struct buffer_head *dbl_indir_block; | 429 | struct buffer_head *dbl_indir_block; |
430 | struct buffer_head *indir_block; | 430 | struct buffer_head *indir_block; |
431 | befs_block_run indir_run; | 431 | befs_block_run indir_run; |
432 | befs_disk_inode_addr *iaddr_array = NULL; | 432 | befs_disk_inode_addr *iaddr_array; |
433 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 433 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
434 | 434 | ||
435 | befs_blocknr_t indir_start_blk = | 435 | befs_blocknr_t indir_start_blk = |
@@ -488,7 +488,6 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
488 | iaddr_array = (befs_disk_inode_addr *) dbl_indir_block->b_data; | 488 | iaddr_array = (befs_disk_inode_addr *) dbl_indir_block->b_data; |
489 | indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]); | 489 | indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]); |
490 | brelse(dbl_indir_block); | 490 | brelse(dbl_indir_block); |
491 | iaddr_array = NULL; | ||
492 | 491 | ||
493 | /* Read indirect block */ | 492 | /* Read indirect block */ |
494 | which_block = indir_indx / befs_iaddrs_per_block(sb); | 493 | which_block = indir_indx / befs_iaddrs_per_block(sb); |
@@ -513,7 +512,6 @@ befs_find_brun_dblindirect(struct super_block *sb, | |||
513 | iaddr_array = (befs_disk_inode_addr *) indir_block->b_data; | 512 | iaddr_array = (befs_disk_inode_addr *) indir_block->b_data; |
514 | *run = fsrun_to_cpu(sb, iaddr_array[block_indx]); | 513 | *run = fsrun_to_cpu(sb, iaddr_array[block_indx]); |
515 | brelse(indir_block); | 514 | brelse(indir_block); |
516 | iaddr_array = NULL; | ||
517 | 515 | ||
518 | blockno_at_run_start = indir_start_blk; | 516 | blockno_at_run_start = indir_start_blk; |
519 | blockno_at_run_start += diblklen * dblindir_indx; | 517 | blockno_at_run_start += diblklen * dblindir_indx; |
diff --git a/fs/befs/io.c b/fs/befs/io.c index 7a5b4ec21c56..523c8af2d770 100644 --- a/fs/befs/io.c +++ b/fs/befs/io.c | |||
@@ -26,7 +26,7 @@ | |||
26 | struct buffer_head * | 26 | struct buffer_head * |
27 | befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) | 27 | befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) |
28 | { | 28 | { |
29 | struct buffer_head *bh = NULL; | 29 | struct buffer_head *bh; |
30 | befs_blocknr_t block = 0; | 30 | befs_blocknr_t block = 0; |
31 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 31 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
32 | 32 | ||
@@ -63,7 +63,7 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) | |||
63 | struct buffer_head * | 63 | struct buffer_head * |
64 | befs_bread(struct super_block *sb, befs_blocknr_t block) | 64 | befs_bread(struct super_block *sb, befs_blocknr_t block) |
65 | { | 65 | { |
66 | struct buffer_head *bh = NULL; | 66 | struct buffer_head *bh; |
67 | 67 | ||
68 | befs_debug(sb, "---> Enter %s %lu", __func__, (unsigned long)block); | 68 | befs_debug(sb, "---> Enter %s %lu", __func__, (unsigned long)block); |
69 | 69 | ||
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 71112aa07d84..7da05b159ade 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -155,7 +155,7 @@ befs_get_block(struct inode *inode, sector_t block, | |||
155 | static struct dentry * | 155 | static struct dentry * |
156 | befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | 156 | befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
157 | { | 157 | { |
158 | struct inode *inode = NULL; | 158 | struct inode *inode; |
159 | struct super_block *sb = dir->i_sb; | 159 | struct super_block *sb = dir->i_sb; |
160 | const befs_data_stream *ds = &BEFS_I(dir)->i_data.ds; | 160 | const befs_data_stream *ds = &BEFS_I(dir)->i_data.ds; |
161 | befs_off_t offset; | 161 | befs_off_t offset; |
@@ -294,10 +294,10 @@ static void init_once(void *foo) | |||
294 | 294 | ||
295 | static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | 295 | static struct inode *befs_iget(struct super_block *sb, unsigned long ino) |
296 | { | 296 | { |
297 | struct buffer_head *bh = NULL; | 297 | struct buffer_head *bh; |
298 | befs_inode *raw_inode = NULL; | 298 | befs_inode *raw_inode; |
299 | struct befs_sb_info *befs_sb = BEFS_SB(sb); | 299 | struct befs_sb_info *befs_sb = BEFS_SB(sb); |
300 | struct befs_inode_info *befs_ino = NULL; | 300 | struct befs_inode_info *befs_ino; |
301 | struct inode *inode; | 301 | struct inode *inode; |
302 | long ret = -EIO; | 302 | long ret = -EIO; |
303 | 303 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 4c556680fa74..2fab9f130e51 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -297,7 +297,10 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
297 | } | 297 | } |
298 | 298 | ||
299 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { | 299 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { |
300 | vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); | 300 | error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); |
301 | if (IS_ERR_VALUE(error)) | ||
302 | return error; | ||
303 | |||
301 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, | 304 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, |
302 | ex.a_text + ex.a_data); | 305 | ex.a_text + ex.a_data); |
303 | goto beyond_if; | 306 | goto beyond_if; |
@@ -378,8 +381,10 @@ static int load_aout_library(struct file *file) | |||
378 | "N_TXTOFF is not page aligned. Please convert library: %pD\n", | 381 | "N_TXTOFF is not page aligned. Please convert library: %pD\n", |
379 | file); | 382 | file); |
380 | } | 383 | } |
381 | vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); | 384 | retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); |
382 | 385 | if (IS_ERR_VALUE(retval)) | |
386 | goto out; | ||
387 | |||
383 | read_code(file, start_addr, N_TXTOFF(ex), | 388 | read_code(file, start_addr, N_TXTOFF(ex), |
384 | ex.a_text + ex.a_data); | 389 | ex.a_text + ex.a_data); |
385 | retval = 0; | 390 | retval = 0; |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 56224ffa94d2..938fc4ede764 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1176,8 +1176,11 @@ static int load_elf_library(struct file *file) | |||
1176 | len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + | 1176 | len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + |
1177 | ELF_MIN_ALIGN - 1); | 1177 | ELF_MIN_ALIGN - 1); |
1178 | bss = eppnt->p_memsz + eppnt->p_vaddr; | 1178 | bss = eppnt->p_memsz + eppnt->p_vaddr; |
1179 | if (bss > len) | 1179 | if (bss > len) { |
1180 | vm_brk(len, bss - len); | 1180 | error = vm_brk(len, bss - len); |
1181 | if (BAD_ADDR(error)) | ||
1182 | goto out_free_ph; | ||
1183 | } | ||
1181 | error = 0; | 1184 | error = 0; |
1182 | 1185 | ||
1183 | out_free_ph: | 1186 | out_free_ph: |
diff --git a/fs/coredump.c b/fs/coredump.c index 492c2db25dc9..38a7ab87e10a 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -413,7 +413,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state) | |||
413 | core_state->dumper.task = tsk; | 413 | core_state->dumper.task = tsk; |
414 | core_state->dumper.next = NULL; | 414 | core_state->dumper.next = NULL; |
415 | 415 | ||
416 | down_write(&mm->mmap_sem); | 416 | if (down_write_killable(&mm->mmap_sem)) |
417 | return -EINTR; | ||
418 | |||
417 | if (!mm->core_state) | 419 | if (!mm->core_state) |
418 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); | 420 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); |
419 | up_write(&mm->mmap_sem); | 421 | up_write(&mm->mmap_sem); |
@@ -243,10 +243,6 @@ static void put_arg_page(struct page *page) | |||
243 | put_page(page); | 243 | put_page(page); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void free_arg_page(struct linux_binprm *bprm, int i) | ||
247 | { | ||
248 | } | ||
249 | |||
250 | static void free_arg_pages(struct linux_binprm *bprm) | 246 | static void free_arg_pages(struct linux_binprm *bprm) |
251 | { | 247 | { |
252 | } | 248 | } |
@@ -267,7 +263,10 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
267 | if (!vma) | 263 | if (!vma) |
268 | return -ENOMEM; | 264 | return -ENOMEM; |
269 | 265 | ||
270 | down_write(&mm->mmap_sem); | 266 | if (down_write_killable(&mm->mmap_sem)) { |
267 | err = -EINTR; | ||
268 | goto err_free; | ||
269 | } | ||
271 | vma->vm_mm = mm; | 270 | vma->vm_mm = mm; |
272 | 271 | ||
273 | /* | 272 | /* |
@@ -294,6 +293,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
294 | return 0; | 293 | return 0; |
295 | err: | 294 | err: |
296 | up_write(&mm->mmap_sem); | 295 | up_write(&mm->mmap_sem); |
296 | err_free: | ||
297 | bprm->vma = NULL; | 297 | bprm->vma = NULL; |
298 | kmem_cache_free(vm_area_cachep, vma); | 298 | kmem_cache_free(vm_area_cachep, vma); |
299 | return err; | 299 | return err; |
@@ -700,7 +700,9 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
700 | bprm->loader -= stack_shift; | 700 | bprm->loader -= stack_shift; |
701 | bprm->exec -= stack_shift; | 701 | bprm->exec -= stack_shift; |
702 | 702 | ||
703 | down_write(&mm->mmap_sem); | 703 | if (down_write_killable(&mm->mmap_sem)) |
704 | return -EINTR; | ||
705 | |||
704 | vm_flags = VM_STACK_FLAGS; | 706 | vm_flags = VM_STACK_FLAGS; |
705 | 707 | ||
706 | /* | 708 | /* |
@@ -1499,9 +1501,6 @@ int remove_arg_zero(struct linux_binprm *bprm) | |||
1499 | 1501 | ||
1500 | kunmap_atomic(kaddr); | 1502 | kunmap_atomic(kaddr); |
1501 | put_arg_page(page); | 1503 | put_arg_page(page); |
1502 | |||
1503 | if (offset == PAGE_SIZE) | ||
1504 | free_arg_page(bprm, (bprm->p >> PAGE_SHIFT) - 1); | ||
1505 | } while (offset == PAGE_SIZE); | 1504 | } while (offset == PAGE_SIZE); |
1506 | 1505 | ||
1507 | bprm->p++; | 1506 | bprm->p++; |
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 2ccbf5531554..1a85d94f5b25 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
@@ -13,13 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Originally written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | 17 | * Two allocators were unified by Ryusuke Konishi and Amagai Yoshiji. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Original code was written by Koji Sato <koji@osrg.net>. | ||
21 | * Two allocators were unified by Ryusuke Konishi <ryusuke@osrg.net>, | ||
22 | * Amagai Yoshiji <amagai@osrg.net>. | ||
23 | */ | 18 | */ |
24 | 19 | ||
25 | #include <linux/types.h> | 20 | #include <linux/types.h> |
@@ -58,7 +53,7 @@ nilfs_palloc_groups_count(const struct inode *inode) | |||
58 | * @inode: inode of metadata file using this allocator | 53 | * @inode: inode of metadata file using this allocator |
59 | * @entry_size: size of the persistent object | 54 | * @entry_size: size of the persistent object |
60 | */ | 55 | */ |
61 | int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size) | 56 | int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned int entry_size) |
62 | { | 57 | { |
63 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); | 58 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); |
64 | 59 | ||
@@ -73,13 +68,17 @@ int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size) | |||
73 | mi->mi_blocks_per_group = | 68 | mi->mi_blocks_per_group = |
74 | DIV_ROUND_UP(nilfs_palloc_entries_per_group(inode), | 69 | DIV_ROUND_UP(nilfs_palloc_entries_per_group(inode), |
75 | mi->mi_entries_per_block) + 1; | 70 | mi->mi_entries_per_block) + 1; |
76 | /* Number of blocks in a group including entry blocks and | 71 | /* |
77 | a bitmap block */ | 72 | * Number of blocks in a group including entry blocks |
73 | * and a bitmap block | ||
74 | */ | ||
78 | mi->mi_blocks_per_desc_block = | 75 | mi->mi_blocks_per_desc_block = |
79 | nilfs_palloc_groups_per_desc_block(inode) * | 76 | nilfs_palloc_groups_per_desc_block(inode) * |
80 | mi->mi_blocks_per_group + 1; | 77 | mi->mi_blocks_per_group + 1; |
81 | /* Number of blocks per descriptor including the | 78 | /* |
82 | descriptor block */ | 79 | * Number of blocks per descriptor including the |
80 | * descriptor block | ||
81 | */ | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
85 | 84 | ||
@@ -389,7 +388,7 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, | |||
389 | */ | 388 | */ |
390 | static int nilfs_palloc_find_available_slot(unsigned char *bitmap, | 389 | static int nilfs_palloc_find_available_slot(unsigned char *bitmap, |
391 | unsigned long target, | 390 | unsigned long target, |
392 | unsigned bsize, | 391 | unsigned int bsize, |
393 | spinlock_t *lock) | 392 | spinlock_t *lock) |
394 | { | 393 | { |
395 | int pos, end = bsize; | 394 | int pos, end = bsize; |
@@ -624,7 +623,7 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, | |||
624 | 623 | ||
625 | if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap)) | 624 | if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap)) |
626 | nilfs_warning(inode->i_sb, __func__, | 625 | nilfs_warning(inode->i_sb, __func__, |
627 | "entry number %llu already freed: ino=%lu\n", | 626 | "entry number %llu already freed: ino=%lu", |
628 | (unsigned long long)req->pr_entry_nr, | 627 | (unsigned long long)req->pr_entry_nr, |
629 | (unsigned long)inode->i_ino); | 628 | (unsigned long)inode->i_ino); |
630 | else | 629 | else |
@@ -665,7 +664,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, | |||
665 | 664 | ||
666 | if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap)) | 665 | if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap)) |
667 | nilfs_warning(inode->i_sb, __func__, | 666 | nilfs_warning(inode->i_sb, __func__, |
668 | "entry number %llu already freed: ino=%lu\n", | 667 | "entry number %llu already freed: ino=%lu", |
669 | (unsigned long long)req->pr_entry_nr, | 668 | (unsigned long long)req->pr_entry_nr, |
670 | (unsigned long)inode->i_ino); | 669 | (unsigned long)inode->i_ino); |
671 | else | 670 | else |
@@ -740,8 +739,8 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | |||
740 | unsigned long group, group_offset; | 739 | unsigned long group, group_offset; |
741 | __u64 group_min_nr, last_nrs[8]; | 740 | __u64 group_min_nr, last_nrs[8]; |
742 | const unsigned long epg = nilfs_palloc_entries_per_group(inode); | 741 | const unsigned long epg = nilfs_palloc_entries_per_group(inode); |
743 | const unsigned epb = NILFS_MDT(inode)->mi_entries_per_block; | 742 | const unsigned int epb = NILFS_MDT(inode)->mi_entries_per_block; |
744 | unsigned entry_start, end, pos; | 743 | unsigned int entry_start, end, pos; |
745 | spinlock_t *lock; | 744 | spinlock_t *lock; |
746 | int i, j, k, ret; | 745 | int i, j, k, ret; |
747 | u32 nfree; | 746 | u32 nfree; |
@@ -774,7 +773,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | |||
774 | if (!nilfs_clear_bit_atomic(lock, group_offset, | 773 | if (!nilfs_clear_bit_atomic(lock, group_offset, |
775 | bitmap)) { | 774 | bitmap)) { |
776 | nilfs_warning(inode->i_sb, __func__, | 775 | nilfs_warning(inode->i_sb, __func__, |
777 | "entry number %llu already freed: ino=%lu\n", | 776 | "entry number %llu already freed: ino=%lu", |
778 | (unsigned long long)entry_nrs[j], | 777 | (unsigned long long)entry_nrs[j], |
779 | (unsigned long)inode->i_ino); | 778 | (unsigned long)inode->i_ino); |
780 | } else { | 779 | } else { |
@@ -819,7 +818,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | |||
819 | last_nrs[k]); | 818 | last_nrs[k]); |
820 | if (ret && ret != -ENOENT) { | 819 | if (ret && ret != -ENOENT) { |
821 | nilfs_warning(inode->i_sb, __func__, | 820 | nilfs_warning(inode->i_sb, __func__, |
822 | "failed to delete block of entry %llu: ino=%lu, err=%d\n", | 821 | "failed to delete block of entry %llu: ino=%lu, err=%d", |
823 | (unsigned long long)last_nrs[k], | 822 | (unsigned long long)last_nrs[k], |
824 | (unsigned long)inode->i_ino, ret); | 823 | (unsigned long)inode->i_ino, ret); |
825 | } | 824 | } |
@@ -838,7 +837,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | |||
838 | ret = nilfs_palloc_delete_bitmap_block(inode, group); | 837 | ret = nilfs_palloc_delete_bitmap_block(inode, group); |
839 | if (ret && ret != -ENOENT) { | 838 | if (ret && ret != -ENOENT) { |
840 | nilfs_warning(inode->i_sb, __func__, | 839 | nilfs_warning(inode->i_sb, __func__, |
841 | "failed to delete bitmap block of group %lu: ino=%lu, err=%d\n", | 840 | "failed to delete bitmap block of group %lu: ino=%lu, err=%d", |
842 | group, | 841 | group, |
843 | (unsigned long)inode->i_ino, ret); | 842 | (unsigned long)inode->i_ino, ret); |
844 | } | 843 | } |
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h index 6e6f49aa53df..05149e606a78 100644 --- a/fs/nilfs2/alloc.h +++ b/fs/nilfs2/alloc.h | |||
@@ -13,13 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Originally written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | 17 | * Two allocators were unified by Ryusuke Konishi and Amagai Yoshiji. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Original code was written by Koji Sato <koji@osrg.net>. | ||
21 | * Two allocators were unified by Ryusuke Konishi <ryusuke@osrg.net>, | ||
22 | * Amagai Yoshiji <amagai@osrg.net>. | ||
23 | */ | 18 | */ |
24 | 19 | ||
25 | #ifndef _NILFS_ALLOC_H | 20 | #ifndef _NILFS_ALLOC_H |
@@ -42,7 +37,7 @@ nilfs_palloc_entries_per_group(const struct inode *inode) | |||
42 | return 1UL << (inode->i_blkbits + 3 /* log2(8 = CHAR_BITS) */); | 37 | return 1UL << (inode->i_blkbits + 3 /* log2(8 = CHAR_BITS) */); |
43 | } | 38 | } |
44 | 39 | ||
45 | int nilfs_palloc_init_blockgroup(struct inode *, unsigned); | 40 | int nilfs_palloc_init_blockgroup(struct inode *, unsigned int); |
46 | int nilfs_palloc_get_entry_block(struct inode *, __u64, int, | 41 | int nilfs_palloc_get_entry_block(struct inode *, __u64, int, |
47 | struct buffer_head **); | 42 | struct buffer_head **); |
48 | void *nilfs_palloc_block_get_entry(const struct inode *, __u64, | 43 | void *nilfs_palloc_block_get_entry(const struct inode *, __u64, |
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index a9fb3636c142..f2a7877e0c8c 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
@@ -46,7 +42,7 @@ static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap, | |||
46 | 42 | ||
47 | if (err == -EINVAL) { | 43 | if (err == -EINVAL) { |
48 | nilfs_error(inode->i_sb, fname, | 44 | nilfs_error(inode->i_sb, fname, |
49 | "broken bmap (inode number=%lu)\n", inode->i_ino); | 45 | "broken bmap (inode number=%lu)", inode->i_ino); |
50 | err = -EIO; | 46 | err = -EIO; |
51 | } | 47 | } |
52 | return err; | 48 | return err; |
@@ -97,7 +93,7 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, | |||
97 | } | 93 | } |
98 | 94 | ||
99 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, | 95 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, |
100 | unsigned maxblocks) | 96 | unsigned int maxblocks) |
101 | { | 97 | { |
102 | int ret; | 98 | int ret; |
103 | 99 | ||
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h index bfa817ce40b3..b6a4c8f93ac8 100644 --- a/fs/nilfs2/bmap.h +++ b/fs/nilfs2/bmap.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_BMAP_H | 19 | #ifndef _NILFS_BMAP_H |
@@ -61,7 +57,7 @@ struct nilfs_bmap_stats { | |||
61 | struct nilfs_bmap_operations { | 57 | struct nilfs_bmap_operations { |
62 | int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *); | 58 | int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *); |
63 | int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *, | 59 | int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *, |
64 | unsigned); | 60 | unsigned int); |
65 | int (*bop_insert)(struct nilfs_bmap *, __u64, __u64); | 61 | int (*bop_insert)(struct nilfs_bmap *, __u64, __u64); |
66 | int (*bop_delete)(struct nilfs_bmap *, __u64); | 62 | int (*bop_delete)(struct nilfs_bmap *, __u64); |
67 | void (*bop_clear)(struct nilfs_bmap *); | 63 | void (*bop_clear)(struct nilfs_bmap *); |
@@ -126,10 +122,14 @@ struct nilfs_bmap { | |||
126 | 122 | ||
127 | /* pointer type */ | 123 | /* pointer type */ |
128 | #define NILFS_BMAP_PTR_P 0 /* physical block number (i.e. LBN) */ | 124 | #define NILFS_BMAP_PTR_P 0 /* physical block number (i.e. LBN) */ |
129 | #define NILFS_BMAP_PTR_VS 1 /* virtual block number (single | 125 | #define NILFS_BMAP_PTR_VS 1 /* |
130 | version) */ | 126 | * virtual block number (single |
131 | #define NILFS_BMAP_PTR_VM 2 /* virtual block number (has multiple | 127 | * version) |
132 | versions) */ | 128 | */ |
129 | #define NILFS_BMAP_PTR_VM 2 /* | ||
130 | * virtual block number (has multiple | ||
131 | * versions) | ||
132 | */ | ||
133 | #define NILFS_BMAP_PTR_U (-1) /* never perform pointer operations */ | 133 | #define NILFS_BMAP_PTR_U (-1) /* never perform pointer operations */ |
134 | 134 | ||
135 | #define NILFS_BMAP_USE_VBN(bmap) ((bmap)->b_ptr_type > 0) | 135 | #define NILFS_BMAP_USE_VBN(bmap) ((bmap)->b_ptr_type > 0) |
@@ -154,7 +154,7 @@ struct nilfs_bmap_store { | |||
154 | int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); | 154 | int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); |
155 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); | 155 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); |
156 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); | 156 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); |
157 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); | 157 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned int); |
158 | int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec); | 158 | int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec); |
159 | int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key); | 159 | int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key); |
160 | int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp); | 160 | int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp); |
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c index e0c9daf9aa22..0576033699bc 100644 --- a/fs/nilfs2/btnode.c +++ b/fs/nilfs2/btnode.c | |||
@@ -13,13 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Originally written by Seiji Kihara. |
17 | * along with this program; if not, write to the Free Software | 17 | * Fully revised by Ryusuke Konishi for stabilization and simplification. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * This file was originally written by Seiji Kihara <kihara@osrg.net> | ||
21 | * and fully revised by Ryusuke Konishi <ryusuke@osrg.net> for | ||
22 | * stabilization and simplification. | ||
23 | * | 18 | * |
24 | */ | 19 | */ |
25 | 20 | ||
diff --git a/fs/nilfs2/btnode.h b/fs/nilfs2/btnode.h index d876b565ce64..2cc1b80e18f7 100644 --- a/fs/nilfs2/btnode.h +++ b/fs/nilfs2/btnode.h | |||
@@ -13,12 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Seiji Kihara. |
17 | * along with this program; if not, write to the Free Software | 17 | * Revised by Ryusuke Konishi. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Seiji Kihara <kihara@osrg.net> | ||
21 | * Revised by Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | */ | 18 | */ |
23 | 19 | ||
24 | #ifndef _NILFS_BTNODE_H | 20 | #ifndef _NILFS_BTNODE_H |
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 3a3821b00486..eccb1c89ccbb 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -689,7 +685,8 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *btree, | |||
689 | } | 685 | } |
690 | 686 | ||
691 | static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree, | 687 | static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree, |
692 | __u64 key, __u64 *ptrp, unsigned maxblocks) | 688 | __u64 key, __u64 *ptrp, |
689 | unsigned int maxblocks) | ||
693 | { | 690 | { |
694 | struct nilfs_btree_path *path; | 691 | struct nilfs_btree_path *path; |
695 | struct nilfs_btree_node *node; | 692 | struct nilfs_btree_node *node; |
@@ -1032,12 +1029,12 @@ static __u64 nilfs_btree_find_target_v(const struct nilfs_bmap *btree, | |||
1032 | if (ptr != NILFS_BMAP_INVALID_PTR) | 1029 | if (ptr != NILFS_BMAP_INVALID_PTR) |
1033 | /* sequential access */ | 1030 | /* sequential access */ |
1034 | return ptr; | 1031 | return ptr; |
1035 | else { | 1032 | |
1036 | ptr = nilfs_btree_find_near(btree, path); | 1033 | ptr = nilfs_btree_find_near(btree, path); |
1037 | if (ptr != NILFS_BMAP_INVALID_PTR) | 1034 | if (ptr != NILFS_BMAP_INVALID_PTR) |
1038 | /* near */ | 1035 | /* near */ |
1039 | return ptr; | 1036 | return ptr; |
1040 | } | 1037 | |
1041 | /* block group */ | 1038 | /* block group */ |
1042 | return nilfs_bmap_find_target_in_group(btree); | 1039 | return nilfs_bmap_find_target_in_group(btree); |
1043 | } | 1040 | } |
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h index 22c02e35b6ef..df1a25faa83b 100644 --- a/fs/nilfs2/btree.h +++ b/fs/nilfs2/btree.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_BTREE_H | 19 | #ifndef _NILFS_BTREE_H |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index b6596cab9e99..8a3d3b65af3f 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -41,6 +37,7 @@ static unsigned long | |||
41 | nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno) | 37 | nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno) |
42 | { | 38 | { |
43 | __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; | 39 | __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; |
40 | |||
44 | do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); | 41 | do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); |
45 | return (unsigned long)tcno; | 42 | return (unsigned long)tcno; |
46 | } | 43 | } |
@@ -50,6 +47,7 @@ static unsigned long | |||
50 | nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) | 47 | nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) |
51 | { | 48 | { |
52 | __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; | 49 | __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; |
50 | |||
53 | return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); | 51 | return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); |
54 | } | 52 | } |
55 | 53 | ||
@@ -433,7 +431,8 @@ static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile, | |||
433 | } | 431 | } |
434 | 432 | ||
435 | static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | 433 | static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, |
436 | void *buf, unsigned cisz, size_t nci) | 434 | void *buf, unsigned int cisz, |
435 | size_t nci) | ||
437 | { | 436 | { |
438 | struct nilfs_checkpoint *cp; | 437 | struct nilfs_checkpoint *cp; |
439 | struct nilfs_cpinfo *ci = buf; | 438 | struct nilfs_cpinfo *ci = buf; |
@@ -484,7 +483,8 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | |||
484 | } | 483 | } |
485 | 484 | ||
486 | static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, | 485 | static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, |
487 | void *buf, unsigned cisz, size_t nci) | 486 | void *buf, unsigned int cisz, |
487 | size_t nci) | ||
488 | { | 488 | { |
489 | struct buffer_head *bh; | 489 | struct buffer_head *bh; |
490 | struct nilfs_cpfile_header *header; | 490 | struct nilfs_cpfile_header *header; |
@@ -570,7 +570,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, | |||
570 | */ | 570 | */ |
571 | 571 | ||
572 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, | 572 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, |
573 | void *buf, unsigned cisz, size_t nci) | 573 | void *buf, unsigned int cisz, size_t nci) |
574 | { | 574 | { |
575 | switch (mode) { | 575 | switch (mode) { |
576 | case NILFS_CHECKPOINT: | 576 | case NILFS_CHECKPOINT: |
@@ -870,8 +870,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) | |||
870 | void *kaddr; | 870 | void *kaddr; |
871 | int ret; | 871 | int ret; |
872 | 872 | ||
873 | /* CP number is invalid if it's zero or larger than the | 873 | /* |
874 | largest exist one.*/ | 874 | * CP number is invalid if it's zero or larger than the |
875 | * largest existing one. | ||
876 | */ | ||
875 | if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) | 877 | if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) |
876 | return -ENOENT; | 878 | return -ENOENT; |
877 | down_read(&NILFS_MDT(cpfile)->mi_sem); | 879 | down_read(&NILFS_MDT(cpfile)->mi_sem); |
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h index a242b9a314f9..0249744ae234 100644 --- a/fs/nilfs2/cpfile.h +++ b/fs/nilfs2/cpfile.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_CPFILE_H | 19 | #ifndef _NILFS_CPFILE_H |
@@ -37,8 +33,8 @@ int nilfs_cpfile_delete_checkpoint(struct inode *, __u64); | |||
37 | int nilfs_cpfile_change_cpmode(struct inode *, __u64, int); | 33 | int nilfs_cpfile_change_cpmode(struct inode *, __u64, int); |
38 | int nilfs_cpfile_is_snapshot(struct inode *, __u64); | 34 | int nilfs_cpfile_is_snapshot(struct inode *, __u64); |
39 | int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *); | 35 | int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *); |
40 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, | 36 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, |
41 | size_t); | 37 | unsigned int, size_t); |
42 | 38 | ||
43 | int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, | 39 | int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, |
44 | struct nilfs_inode *raw_inode, struct inode **inodep); | 40 | struct nilfs_inode *raw_inode, struct inode **inodep); |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 7dc23f100e57..7367610ea807 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/types.h> | 19 | #include <linux/types.h> |
@@ -428,7 +424,7 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp) | |||
428 | return ret; | 424 | return ret; |
429 | } | 425 | } |
430 | 426 | ||
431 | ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz, | 427 | ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned int visz, |
432 | size_t nvi) | 428 | size_t nvi) |
433 | { | 429 | { |
434 | struct buffer_head *entry_bh; | 430 | struct buffer_head *entry_bh; |
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h index cbd8e9732503..abbfdabcabea 100644 --- a/fs/nilfs2/dat.h +++ b/fs/nilfs2/dat.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_DAT_H | 19 | #ifndef _NILFS_DAT_H |
@@ -51,7 +47,7 @@ void nilfs_dat_abort_update(struct inode *, struct nilfs_palloc_req *, | |||
51 | int nilfs_dat_mark_dirty(struct inode *, __u64); | 47 | int nilfs_dat_mark_dirty(struct inode *, __u64); |
52 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); | 48 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); |
53 | int nilfs_dat_move(struct inode *, __u64, sector_t); | 49 | int nilfs_dat_move(struct inode *, __u64, sector_t); |
54 | ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); | 50 | ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned int, size_t); |
55 | 51 | ||
56 | int nilfs_dat_read(struct super_block *sb, size_t entry_size, | 52 | int nilfs_dat_read(struct super_block *sb, size_t entry_size, |
57 | struct nilfs_inode *raw_inode, struct inode **inodep); | 53 | struct nilfs_inode *raw_inode, struct inode **inodep); |
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 6723d45a631a..e506f4f7120a 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Modified for NILFS by Amagai Yoshiji. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Modified for NILFS by Amagai Yoshiji <amagai@osrg.net> | ||
21 | */ | 17 | */ |
22 | /* | 18 | /* |
23 | * linux/fs/ext2/dir.c | 19 | * linux/fs/ext2/dir.c |
@@ -50,7 +46,7 @@ | |||
50 | * nilfs uses block-sized chunks. Arguably, sector-sized ones would be | 46 | * nilfs uses block-sized chunks. Arguably, sector-sized ones would be |
51 | * more robust, but we have what we have | 47 | * more robust, but we have what we have |
52 | */ | 48 | */ |
53 | static inline unsigned nilfs_chunk_size(struct inode *inode) | 49 | static inline unsigned int nilfs_chunk_size(struct inode *inode) |
54 | { | 50 | { |
55 | return inode->i_sb->s_blocksize; | 51 | return inode->i_sb->s_blocksize; |
56 | } | 52 | } |
@@ -65,9 +61,9 @@ static inline void nilfs_put_page(struct page *page) | |||
65 | * Return the offset into page `page_nr' of the last valid | 61 | * Return the offset into page `page_nr' of the last valid |
66 | * byte in that page, plus one. | 62 | * byte in that page, plus one. |
67 | */ | 63 | */ |
68 | static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr) | 64 | static unsigned int nilfs_last_byte(struct inode *inode, unsigned long page_nr) |
69 | { | 65 | { |
70 | unsigned last_byte = inode->i_size; | 66 | unsigned int last_byte = inode->i_size; |
71 | 67 | ||
72 | last_byte -= page_nr << PAGE_SHIFT; | 68 | last_byte -= page_nr << PAGE_SHIFT; |
73 | if (last_byte > PAGE_SIZE) | 69 | if (last_byte > PAGE_SIZE) |
@@ -75,20 +71,22 @@ static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr) | |||
75 | return last_byte; | 71 | return last_byte; |
76 | } | 72 | } |
77 | 73 | ||
78 | static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to) | 74 | static int nilfs_prepare_chunk(struct page *page, unsigned int from, |
75 | unsigned int to) | ||
79 | { | 76 | { |
80 | loff_t pos = page_offset(page) + from; | 77 | loff_t pos = page_offset(page) + from; |
78 | |||
81 | return __block_write_begin(page, pos, to - from, nilfs_get_block); | 79 | return __block_write_begin(page, pos, to - from, nilfs_get_block); |
82 | } | 80 | } |
83 | 81 | ||
84 | static void nilfs_commit_chunk(struct page *page, | 82 | static void nilfs_commit_chunk(struct page *page, |
85 | struct address_space *mapping, | 83 | struct address_space *mapping, |
86 | unsigned from, unsigned to) | 84 | unsigned int from, unsigned int to) |
87 | { | 85 | { |
88 | struct inode *dir = mapping->host; | 86 | struct inode *dir = mapping->host; |
89 | loff_t pos = page_offset(page) + from; | 87 | loff_t pos = page_offset(page) + from; |
90 | unsigned len = to - from; | 88 | unsigned int len = to - from; |
91 | unsigned nr_dirty, copied; | 89 | unsigned int nr_dirty, copied; |
92 | int err; | 90 | int err; |
93 | 91 | ||
94 | nr_dirty = nilfs_page_count_clean_buffers(page, from, to); | 92 | nr_dirty = nilfs_page_count_clean_buffers(page, from, to); |
@@ -106,10 +104,10 @@ static bool nilfs_check_page(struct page *page) | |||
106 | { | 104 | { |
107 | struct inode *dir = page->mapping->host; | 105 | struct inode *dir = page->mapping->host; |
108 | struct super_block *sb = dir->i_sb; | 106 | struct super_block *sb = dir->i_sb; |
109 | unsigned chunk_size = nilfs_chunk_size(dir); | 107 | unsigned int chunk_size = nilfs_chunk_size(dir); |
110 | char *kaddr = page_address(page); | 108 | char *kaddr = page_address(page); |
111 | unsigned offs, rec_len; | 109 | unsigned int offs, rec_len; |
112 | unsigned limit = PAGE_SIZE; | 110 | unsigned int limit = PAGE_SIZE; |
113 | struct nilfs_dir_entry *p; | 111 | struct nilfs_dir_entry *p; |
114 | char *error; | 112 | char *error; |
115 | 113 | ||
@@ -259,7 +257,6 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx) | |||
259 | unsigned int offset = pos & ~PAGE_MASK; | 257 | unsigned int offset = pos & ~PAGE_MASK; |
260 | unsigned long n = pos >> PAGE_SHIFT; | 258 | unsigned long n = pos >> PAGE_SHIFT; |
261 | unsigned long npages = dir_pages(inode); | 259 | unsigned long npages = dir_pages(inode); |
262 | /* unsigned chunk_mask = ~(nilfs_chunk_size(inode)-1); */ | ||
263 | 260 | ||
264 | if (pos > inode->i_size - NILFS_DIR_REC_LEN(1)) | 261 | if (pos > inode->i_size - NILFS_DIR_REC_LEN(1)) |
265 | return 0; | 262 | return 0; |
@@ -321,7 +318,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, | |||
321 | { | 318 | { |
322 | const unsigned char *name = qstr->name; | 319 | const unsigned char *name = qstr->name; |
323 | int namelen = qstr->len; | 320 | int namelen = qstr->len; |
324 | unsigned reclen = NILFS_DIR_REC_LEN(namelen); | 321 | unsigned int reclen = NILFS_DIR_REC_LEN(namelen); |
325 | unsigned long start, n; | 322 | unsigned long start, n; |
326 | unsigned long npages = dir_pages(dir); | 323 | unsigned long npages = dir_pages(dir); |
327 | struct page *page = NULL; | 324 | struct page *page = NULL; |
@@ -340,6 +337,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, | |||
340 | n = start; | 337 | n = start; |
341 | do { | 338 | do { |
342 | char *kaddr; | 339 | char *kaddr; |
340 | |||
343 | page = nilfs_get_page(dir, n); | 341 | page = nilfs_get_page(dir, n); |
344 | if (!IS_ERR(page)) { | 342 | if (!IS_ERR(page)) { |
345 | kaddr = page_address(page); | 343 | kaddr = page_address(page); |
@@ -410,8 +408,8 @@ ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr) | |||
410 | void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, | 408 | void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, |
411 | struct page *page, struct inode *inode) | 409 | struct page *page, struct inode *inode) |
412 | { | 410 | { |
413 | unsigned from = (char *) de - (char *) page_address(page); | 411 | unsigned int from = (char *)de - (char *)page_address(page); |
414 | unsigned to = from + nilfs_rec_len_from_disk(de->rec_len); | 412 | unsigned int to = from + nilfs_rec_len_from_disk(de->rec_len); |
415 | struct address_space *mapping = page->mapping; | 413 | struct address_space *mapping = page->mapping; |
416 | int err; | 414 | int err; |
417 | 415 | ||
@@ -433,15 +431,15 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) | |||
433 | struct inode *dir = d_inode(dentry->d_parent); | 431 | struct inode *dir = d_inode(dentry->d_parent); |
434 | const unsigned char *name = dentry->d_name.name; | 432 | const unsigned char *name = dentry->d_name.name; |
435 | int namelen = dentry->d_name.len; | 433 | int namelen = dentry->d_name.len; |
436 | unsigned chunk_size = nilfs_chunk_size(dir); | 434 | unsigned int chunk_size = nilfs_chunk_size(dir); |
437 | unsigned reclen = NILFS_DIR_REC_LEN(namelen); | 435 | unsigned int reclen = NILFS_DIR_REC_LEN(namelen); |
438 | unsigned short rec_len, name_len; | 436 | unsigned short rec_len, name_len; |
439 | struct page *page = NULL; | 437 | struct page *page = NULL; |
440 | struct nilfs_dir_entry *de; | 438 | struct nilfs_dir_entry *de; |
441 | unsigned long npages = dir_pages(dir); | 439 | unsigned long npages = dir_pages(dir); |
442 | unsigned long n; | 440 | unsigned long n; |
443 | char *kaddr; | 441 | char *kaddr; |
444 | unsigned from, to; | 442 | unsigned int from, to; |
445 | int err; | 443 | int err; |
446 | 444 | ||
447 | /* | 445 | /* |
@@ -533,13 +531,14 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) | |||
533 | struct address_space *mapping = page->mapping; | 531 | struct address_space *mapping = page->mapping; |
534 | struct inode *inode = mapping->host; | 532 | struct inode *inode = mapping->host; |
535 | char *kaddr = page_address(page); | 533 | char *kaddr = page_address(page); |
536 | unsigned from = ((char *)dir - kaddr) & ~(nilfs_chunk_size(inode) - 1); | 534 | unsigned int from, to; |
537 | unsigned to = ((char *)dir - kaddr) + | 535 | struct nilfs_dir_entry *de, *pde = NULL; |
538 | nilfs_rec_len_from_disk(dir->rec_len); | ||
539 | struct nilfs_dir_entry *pde = NULL; | ||
540 | struct nilfs_dir_entry *de = (struct nilfs_dir_entry *)(kaddr + from); | ||
541 | int err; | 536 | int err; |
542 | 537 | ||
538 | from = ((char *)dir - kaddr) & ~(nilfs_chunk_size(inode) - 1); | ||
539 | to = ((char *)dir - kaddr) + nilfs_rec_len_from_disk(dir->rec_len); | ||
540 | de = (struct nilfs_dir_entry *)(kaddr + from); | ||
541 | |||
543 | while ((char *)de < (char *)dir) { | 542 | while ((char *)de < (char *)dir) { |
544 | if (de->rec_len == 0) { | 543 | if (de->rec_len == 0) { |
545 | nilfs_error(inode->i_sb, __func__, | 544 | nilfs_error(inode->i_sb, __func__, |
@@ -572,7 +571,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent) | |||
572 | { | 571 | { |
573 | struct address_space *mapping = inode->i_mapping; | 572 | struct address_space *mapping = inode->i_mapping; |
574 | struct page *page = grab_cache_page(mapping, 0); | 573 | struct page *page = grab_cache_page(mapping, 0); |
575 | unsigned chunk_size = nilfs_chunk_size(inode); | 574 | unsigned int chunk_size = nilfs_chunk_size(inode); |
576 | struct nilfs_dir_entry *de; | 575 | struct nilfs_dir_entry *de; |
577 | int err; | 576 | int err; |
578 | void *kaddr; | 577 | void *kaddr; |
@@ -630,8 +629,8 @@ int nilfs_empty_dir(struct inode *inode) | |||
630 | while ((char *)de <= kaddr) { | 629 | while ((char *)de <= kaddr) { |
631 | if (de->rec_len == 0) { | 630 | if (de->rec_len == 0) { |
632 | nilfs_error(inode->i_sb, __func__, | 631 | nilfs_error(inode->i_sb, __func__, |
633 | "zero-length directory entry " | 632 | "zero-length directory entry (kaddr=%p, de=%p)", |
634 | "(kaddr=%p, de=%p)\n", kaddr, de); | 633 | kaddr, de); |
635 | goto not_empty; | 634 | goto not_empty; |
636 | } | 635 | } |
637 | if (de->inode != 0) { | 636 | if (de->inode != 0) { |
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index ebf89fd8ac1a..251a44928405 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
@@ -62,7 +58,7 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *direct, | |||
62 | 58 | ||
63 | static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct, | 59 | static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct, |
64 | __u64 key, __u64 *ptrp, | 60 | __u64 key, __u64 *ptrp, |
65 | unsigned maxblocks) | 61 | unsigned int maxblocks) |
66 | { | 62 | { |
67 | struct inode *dat = NULL; | 63 | struct inode *dat = NULL; |
68 | __u64 ptr, ptr2; | 64 | __u64 ptr, ptr2; |
@@ -83,7 +79,8 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct, | |||
83 | ptr = blocknr; | 79 | ptr = blocknr; |
84 | } | 80 | } |
85 | 81 | ||
86 | maxblocks = min_t(unsigned, maxblocks, NILFS_DIRECT_KEY_MAX - key + 1); | 82 | maxblocks = min_t(unsigned int, maxblocks, |
83 | NILFS_DIRECT_KEY_MAX - key + 1); | ||
87 | for (cnt = 1; cnt < maxblocks && | 84 | for (cnt = 1; cnt < maxblocks && |
88 | (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) != | 85 | (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) != |
89 | NILFS_BMAP_INVALID_PTR; | 86 | NILFS_BMAP_INVALID_PTR; |
@@ -110,9 +107,9 @@ nilfs_direct_find_target_v(const struct nilfs_bmap *direct, __u64 key) | |||
110 | if (ptr != NILFS_BMAP_INVALID_PTR) | 107 | if (ptr != NILFS_BMAP_INVALID_PTR) |
111 | /* sequential access */ | 108 | /* sequential access */ |
112 | return ptr; | 109 | return ptr; |
113 | else | 110 | |
114 | /* block group */ | 111 | /* block group */ |
115 | return nilfs_bmap_find_target_in_group(direct); | 112 | return nilfs_bmap_find_target_in_group(direct); |
116 | } | 113 | } |
117 | 114 | ||
118 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | 115 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) |
diff --git a/fs/nilfs2/direct.h b/fs/nilfs2/direct.h index dc643de20a25..3015a6e78724 100644 --- a/fs/nilfs2/direct.h +++ b/fs/nilfs2/direct.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_DIRECT_H | 19 | #ifndef _NILFS_DIRECT_H |
diff --git a/fs/nilfs2/export.h b/fs/nilfs2/export.h index 19ccbf9522ab..00107fdb9343 100644 --- a/fs/nilfs2/export.h +++ b/fs/nilfs2/export.h | |||
@@ -20,6 +20,6 @@ struct nilfs_fid { | |||
20 | 20 | ||
21 | u32 parent_gen; | 21 | u32 parent_gen; |
22 | u64 parent_ino; | 22 | u64 parent_ino; |
23 | } __attribute__ ((packed)); | 23 | } __packed; |
24 | 24 | ||
25 | #endif | 25 | #endif |
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 088ba001c6ef..547381f3ce13 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Amagai Yoshiji and Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Amagai Yoshiji <amagai@osrg.net>, | ||
21 | * Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | */ | 17 | */ |
23 | 18 | ||
24 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 0224b7826ace..693aded72498 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c | |||
@@ -13,13 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Seiji Kihara, Amagai Yoshiji, and Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | 17 | * Revised by Ryusuke Konishi. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Seiji Kihara <kihara@osrg.net>, Amagai Yoshiji <amagai@osrg.net>, | ||
21 | * and Ryusuke Konishi <ryusuke@osrg.net>. | ||
22 | * Revised by Ryusuke Konishi <ryusuke@osrg.net>. | ||
23 | * | 18 | * |
24 | */ | 19 | */ |
25 | /* | 20 | /* |
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c index 6548c7851b48..1d2b1805327a 100644 --- a/fs/nilfs2/ifile.c +++ b/fs/nilfs2/ifile.c | |||
@@ -13,12 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Amagai Yoshiji. |
17 | * along with this program; if not, write to the Free Software | 17 | * Revised by Ryusuke Konishi. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Amagai Yoshiji <amagai@osrg.net>. | ||
21 | * Revised by Ryusuke Konishi <ryusuke@osrg.net>. | ||
22 | * | 18 | * |
23 | */ | 19 | */ |
24 | 20 | ||
@@ -68,8 +64,10 @@ int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, | |||
68 | struct nilfs_palloc_req req; | 64 | struct nilfs_palloc_req req; |
69 | int ret; | 65 | int ret; |
70 | 66 | ||
71 | req.pr_entry_nr = 0; /* 0 says find free inode from beginning of | 67 | req.pr_entry_nr = 0; /* |
72 | a group. dull code!! */ | 68 | * 0 says find free inode from beginning |
69 | * of a group. dull code!! | ||
70 | */ | ||
73 | req.pr_entry_bh = NULL; | 71 | req.pr_entry_bh = NULL; |
74 | 72 | ||
75 | ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); | 73 | ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); |
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h index 679674d13372..23ad2f091e76 100644 --- a/fs/nilfs2/ifile.h +++ b/fs/nilfs2/ifile.h | |||
@@ -13,12 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Amagai Yoshiji. |
17 | * along with this program; if not, write to the Free Software | 17 | * Revised by Ryusuke Konishi. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Amagai Yoshiji <amagai@osrg.net> | ||
21 | * Revised by Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | * | 18 | * |
23 | */ | 19 | */ |
24 | 20 | ||
@@ -36,6 +32,7 @@ static inline struct nilfs_inode * | |||
36 | nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh) | 32 | nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh) |
37 | { | 33 | { |
38 | void *kaddr = kmap(ibh->b_page); | 34 | void *kaddr = kmap(ibh->b_page); |
35 | |||
39 | return nilfs_palloc_block_get_entry(ifile, ino, ibh, kaddr); | 36 | return nilfs_palloc_block_get_entry(ifile, ino, ibh, kaddr); |
40 | } | 37 | } |
41 | 38 | ||
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index cfebcd2fc7f3..a0ebdb17e912 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | 19 | ||
@@ -87,7 +83,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
87 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | 83 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
88 | __u64 blknum = 0; | 84 | __u64 blknum = 0; |
89 | int err = 0, ret; | 85 | int err = 0, ret; |
90 | unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; | 86 | unsigned int maxblocks = bh_result->b_size >> inode->i_blkbits; |
91 | 87 | ||
92 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); | 88 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
93 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); | 89 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); |
@@ -133,11 +129,14 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
133 | /* Error handling should be detailed */ | 129 | /* Error handling should be detailed */ |
134 | set_buffer_new(bh_result); | 130 | set_buffer_new(bh_result); |
135 | set_buffer_delay(bh_result); | 131 | set_buffer_delay(bh_result); |
136 | map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed | 132 | map_bh(bh_result, inode->i_sb, 0); |
137 | to proper value */ | 133 | /* Disk block number must be changed to proper value */ |
134 | |||
138 | } else if (ret == -ENOENT) { | 135 | } else if (ret == -ENOENT) { |
139 | /* not found is not error (e.g. hole); must return without | 136 | /* |
140 | the mapped state flag. */ | 137 | * not found is not error (e.g. hole); must return without |
138 | * the mapped state flag. | ||
139 | */ | ||
141 | ; | 140 | ; |
142 | } else { | 141 | } else { |
143 | err = ret; | 142 | err = ret; |
@@ -167,7 +166,7 @@ static int nilfs_readpage(struct file *file, struct page *page) | |||
167 | * @nr_pages - number of pages to be read | 166 | * @nr_pages - number of pages to be read |
168 | */ | 167 | */ |
169 | static int nilfs_readpages(struct file *file, struct address_space *mapping, | 168 | static int nilfs_readpages(struct file *file, struct address_space *mapping, |
170 | struct list_head *pages, unsigned nr_pages) | 169 | struct list_head *pages, unsigned int nr_pages) |
171 | { | 170 | { |
172 | return mpage_readpages(mapping, pages, nr_pages, nilfs_get_block); | 171 | return mpage_readpages(mapping, pages, nr_pages, nilfs_get_block); |
173 | } | 172 | } |
@@ -226,7 +225,7 @@ static int nilfs_set_page_dirty(struct page *page) | |||
226 | int ret = __set_page_dirty_nobuffers(page); | 225 | int ret = __set_page_dirty_nobuffers(page); |
227 | 226 | ||
228 | if (page_has_buffers(page)) { | 227 | if (page_has_buffers(page)) { |
229 | unsigned nr_dirty = 0; | 228 | unsigned int nr_dirty = 0; |
230 | struct buffer_head *bh, *head; | 229 | struct buffer_head *bh, *head; |
231 | 230 | ||
232 | /* | 231 | /* |
@@ -249,7 +248,7 @@ static int nilfs_set_page_dirty(struct page *page) | |||
249 | if (nr_dirty) | 248 | if (nr_dirty) |
250 | nilfs_set_file_dirty(inode, nr_dirty); | 249 | nilfs_set_file_dirty(inode, nr_dirty); |
251 | } else if (ret) { | 250 | } else if (ret) { |
252 | unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); | 251 | unsigned int nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); |
253 | 252 | ||
254 | nilfs_set_file_dirty(inode, nr_dirty); | 253 | nilfs_set_file_dirty(inode, nr_dirty); |
255 | } | 254 | } |
@@ -291,8 +290,8 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, | |||
291 | struct page *page, void *fsdata) | 290 | struct page *page, void *fsdata) |
292 | { | 291 | { |
293 | struct inode *inode = mapping->host; | 292 | struct inode *inode = mapping->host; |
294 | unsigned start = pos & (PAGE_SIZE - 1); | 293 | unsigned int start = pos & (PAGE_SIZE - 1); |
295 | unsigned nr_dirty; | 294 | unsigned int nr_dirty; |
296 | int err; | 295 | int err; |
297 | 296 | ||
298 | nr_dirty = nilfs_page_count_clean_buffers(page, start, | 297 | nr_dirty = nilfs_page_count_clean_buffers(page, start, |
@@ -399,23 +398,26 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode) | |||
399 | 398 | ||
400 | err = nilfs_init_acl(inode, dir); | 399 | err = nilfs_init_acl(inode, dir); |
401 | if (unlikely(err)) | 400 | if (unlikely(err)) |
402 | goto failed_after_creation; /* never occur. When supporting | 401 | /* |
403 | nilfs_init_acl(), proper cancellation of | 402 | * Never occur. When supporting nilfs_init_acl(), |
404 | above jobs should be considered */ | 403 | * proper cancellation of above jobs should be considered. |
404 | */ | ||
405 | goto failed_after_creation; | ||
405 | 406 | ||
406 | return inode; | 407 | return inode; |
407 | 408 | ||
408 | failed_after_creation: | 409 | failed_after_creation: |
409 | clear_nlink(inode); | 410 | clear_nlink(inode); |
410 | unlock_new_inode(inode); | 411 | unlock_new_inode(inode); |
411 | iput(inode); /* raw_inode will be deleted through | 412 | iput(inode); /* |
412 | nilfs_evict_inode() */ | 413 | * raw_inode will be deleted through |
414 | * nilfs_evict_inode(). | ||
415 | */ | ||
413 | goto failed; | 416 | goto failed; |
414 | 417 | ||
415 | failed_ifile_create_inode: | 418 | failed_ifile_create_inode: |
416 | make_bad_inode(inode); | 419 | make_bad_inode(inode); |
417 | iput(inode); /* if i_nlink == 1, generic_forget_inode() will be | 420 | iput(inode); |
418 | called */ | ||
419 | failed: | 421 | failed: |
420 | return ERR_PTR(err); | 422 | return ERR_PTR(err); |
421 | } | 423 | } |
@@ -666,8 +668,10 @@ void nilfs_write_inode_common(struct inode *inode, | |||
666 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) | 668 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
667 | raw_inode->i_device_code = | 669 | raw_inode->i_device_code = |
668 | cpu_to_le64(huge_encode_dev(inode->i_rdev)); | 670 | cpu_to_le64(huge_encode_dev(inode->i_rdev)); |
669 | /* When extending inode, nilfs->ns_inode_size should be checked | 671 | /* |
670 | for substitutions of appended fields */ | 672 | * When extending inode, nilfs->ns_inode_size should be checked |
673 | * for substitutions of appended fields. | ||
674 | */ | ||
671 | } | 675 | } |
672 | 676 | ||
673 | void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) | 677 | void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) |
@@ -685,9 +689,12 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) | |||
685 | set_bit(NILFS_I_INODE_SYNC, &ii->i_state); | 689 | set_bit(NILFS_I_INODE_SYNC, &ii->i_state); |
686 | 690 | ||
687 | nilfs_write_inode_common(inode, raw_inode, 0); | 691 | nilfs_write_inode_common(inode, raw_inode, 0); |
688 | /* XXX: call with has_bmap = 0 is a workaround to avoid | 692 | /* |
689 | deadlock of bmap. This delays update of i_bmap to just | 693 | * XXX: call with has_bmap = 0 is a workaround to avoid |
690 | before writing */ | 694 | * deadlock of bmap. This delays update of i_bmap to just |
695 | * before writing. | ||
696 | */ | ||
697 | |||
691 | nilfs_ifile_unmap_inode(ifile, ino, ibh); | 698 | nilfs_ifile_unmap_inode(ifile, ino, ibh); |
692 | } | 699 | } |
693 | 700 | ||
@@ -752,14 +759,15 @@ void nilfs_truncate(struct inode *inode) | |||
752 | nilfs_mark_inode_dirty(inode); | 759 | nilfs_mark_inode_dirty(inode); |
753 | nilfs_set_file_dirty(inode, 0); | 760 | nilfs_set_file_dirty(inode, 0); |
754 | nilfs_transaction_commit(sb); | 761 | nilfs_transaction_commit(sb); |
755 | /* May construct a logical segment and may fail in sync mode. | 762 | /* |
756 | But truncate has no return value. */ | 763 | * May construct a logical segment and may fail in sync mode. |
764 | * But truncate has no return value. | ||
765 | */ | ||
757 | } | 766 | } |
758 | 767 | ||
759 | static void nilfs_clear_inode(struct inode *inode) | 768 | static void nilfs_clear_inode(struct inode *inode) |
760 | { | 769 | { |
761 | struct nilfs_inode_info *ii = NILFS_I(inode); | 770 | struct nilfs_inode_info *ii = NILFS_I(inode); |
762 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
763 | 771 | ||
764 | /* | 772 | /* |
765 | * Free resources allocated in nilfs_read_inode(), here. | 773 | * Free resources allocated in nilfs_read_inode(), here. |
@@ -768,8 +776,8 @@ static void nilfs_clear_inode(struct inode *inode) | |||
768 | brelse(ii->i_bh); | 776 | brelse(ii->i_bh); |
769 | ii->i_bh = NULL; | 777 | ii->i_bh = NULL; |
770 | 778 | ||
771 | if (mdi && mdi->mi_palloc_cache) | 779 | if (nilfs_is_metadata_file_inode(inode)) |
772 | nilfs_palloc_destroy_cache(inode); | 780 | nilfs_mdt_clear(inode); |
773 | 781 | ||
774 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) | 782 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) |
775 | nilfs_bmap_clear(ii->i_bmap); | 783 | nilfs_bmap_clear(ii->i_bmap); |
@@ -811,8 +819,10 @@ void nilfs_evict_inode(struct inode *inode) | |||
811 | if (IS_SYNC(inode)) | 819 | if (IS_SYNC(inode)) |
812 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 820 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
813 | nilfs_transaction_commit(sb); | 821 | nilfs_transaction_commit(sb); |
814 | /* May construct a logical segment and may fail in sync mode. | 822 | /* |
815 | But delete_inode has no return value. */ | 823 | * May construct a logical segment and may fail in sync mode. |
824 | * But delete_inode has no return value. | ||
825 | */ | ||
816 | } | 826 | } |
817 | 827 | ||
818 | int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) | 828 | int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) |
@@ -856,6 +866,7 @@ out_err: | |||
856 | int nilfs_permission(struct inode *inode, int mask) | 866 | int nilfs_permission(struct inode *inode, int mask) |
857 | { | 867 | { |
858 | struct nilfs_root *root = NILFS_I(inode)->i_root; | 868 | struct nilfs_root *root = NILFS_I(inode)->i_root; |
869 | |||
859 | if ((mask & MAY_WRITE) && root && | 870 | if ((mask & MAY_WRITE) && root && |
860 | root->cno != NILFS_CPTREE_CURRENT_CNO) | 871 | root->cno != NILFS_CPTREE_CURRENT_CNO) |
861 | return -EROFS; /* snapshot is not writable */ | 872 | return -EROFS; /* snapshot is not writable */ |
@@ -906,7 +917,7 @@ int nilfs_inode_dirty(struct inode *inode) | |||
906 | return ret; | 917 | return ret; |
907 | } | 918 | } |
908 | 919 | ||
909 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) | 920 | int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty) |
910 | { | 921 | { |
911 | struct nilfs_inode_info *ii = NILFS_I(inode); | 922 | struct nilfs_inode_info *ii = NILFS_I(inode); |
912 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | 923 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
@@ -919,17 +930,23 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) | |||
919 | spin_lock(&nilfs->ns_inode_lock); | 930 | spin_lock(&nilfs->ns_inode_lock); |
920 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && | 931 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && |
921 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { | 932 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { |
922 | /* Because this routine may race with nilfs_dispose_list(), | 933 | /* |
923 | we have to check NILFS_I_QUEUED here, too. */ | 934 | * Because this routine may race with nilfs_dispose_list(), |
935 | * we have to check NILFS_I_QUEUED here, too. | ||
936 | */ | ||
924 | if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) { | 937 | if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) { |
925 | /* This will happen when somebody is freeing | 938 | /* |
926 | this inode. */ | 939 | * This will happen when somebody is freeing |
940 | * this inode. | ||
941 | */ | ||
927 | nilfs_warning(inode->i_sb, __func__, | 942 | nilfs_warning(inode->i_sb, __func__, |
928 | "cannot get inode (ino=%lu)\n", | 943 | "cannot get inode (ino=%lu)", |
929 | inode->i_ino); | 944 | inode->i_ino); |
930 | spin_unlock(&nilfs->ns_inode_lock); | 945 | spin_unlock(&nilfs->ns_inode_lock); |
931 | return -EINVAL; /* NILFS_I_DIRTY may remain for | 946 | return -EINVAL; /* |
932 | freeing inode */ | 947 | * NILFS_I_DIRTY may remain for |
948 | * freeing inode. | ||
949 | */ | ||
933 | } | 950 | } |
934 | list_move_tail(&ii->i_dirty, &nilfs->ns_dirty_files); | 951 | list_move_tail(&ii->i_dirty, &nilfs->ns_dirty_files); |
935 | set_bit(NILFS_I_QUEUED, &ii->i_state); | 952 | set_bit(NILFS_I_QUEUED, &ii->i_state); |
@@ -946,7 +963,7 @@ int __nilfs_mark_inode_dirty(struct inode *inode, int flags) | |||
946 | err = nilfs_load_inode_block(inode, &ibh); | 963 | err = nilfs_load_inode_block(inode, &ibh); |
947 | if (unlikely(err)) { | 964 | if (unlikely(err)) { |
948 | nilfs_warning(inode->i_sb, __func__, | 965 | nilfs_warning(inode->i_sb, __func__, |
949 | "failed to reget inode block.\n"); | 966 | "failed to reget inode block."); |
950 | return err; | 967 | return err; |
951 | } | 968 | } |
952 | nilfs_update_inode(inode, ibh, flags); | 969 | nilfs_update_inode(inode, ibh, flags); |
@@ -973,7 +990,7 @@ void nilfs_dirty_inode(struct inode *inode, int flags) | |||
973 | 990 | ||
974 | if (is_bad_inode(inode)) { | 991 | if (is_bad_inode(inode)) { |
975 | nilfs_warning(inode->i_sb, __func__, | 992 | nilfs_warning(inode->i_sb, __func__, |
976 | "tried to mark bad_inode dirty. ignored.\n"); | 993 | "tried to mark bad_inode dirty. ignored."); |
977 | dump_stack(); | 994 | dump_stack(); |
978 | return; | 995 | return; |
979 | } | 996 | } |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index e8fe24882b5b..358b57e2cdf9 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
@@ -783,6 +779,7 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, | |||
783 | size_t nmembs = argv->v_nmembs; | 779 | size_t nmembs = argv->v_nmembs; |
784 | struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; | 780 | struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; |
785 | struct nilfs_bdesc *bdescs = buf; | 781 | struct nilfs_bdesc *bdescs = buf; |
782 | struct buffer_head *bh; | ||
786 | int ret, i; | 783 | int ret, i; |
787 | 784 | ||
788 | for (i = 0; i < nmembs; i++) { | 785 | for (i = 0; i < nmembs; i++) { |
@@ -800,12 +797,16 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, | |||
800 | /* skip dead block */ | 797 | /* skip dead block */ |
801 | continue; | 798 | continue; |
802 | if (bdescs[i].bd_level == 0) { | 799 | if (bdescs[i].bd_level == 0) { |
803 | ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat, | 800 | ret = nilfs_mdt_get_block(nilfs->ns_dat, |
804 | bdescs[i].bd_offset); | 801 | bdescs[i].bd_offset, |
805 | if (ret < 0) { | 802 | false, NULL, &bh); |
803 | if (unlikely(ret)) { | ||
806 | WARN_ON(ret == -ENOENT); | 804 | WARN_ON(ret == -ENOENT); |
807 | return ret; | 805 | return ret; |
808 | } | 806 | } |
807 | mark_buffer_dirty(bh); | ||
808 | nilfs_mdt_mark_dirty(nilfs->ns_dat); | ||
809 | put_bh(bh); | ||
809 | } else { | 810 | } else { |
810 | ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset, | 811 | ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset, |
811 | bdescs[i].bd_level); | 812 | bdescs[i].bd_level); |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index f6982b9153d5..3417d859a03c 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
@@ -32,6 +28,7 @@ | |||
32 | #include "segment.h" | 28 | #include "segment.h" |
33 | #include "page.h" | 29 | #include "page.h" |
34 | #include "mdt.h" | 30 | #include "mdt.h" |
31 | #include "alloc.h" /* nilfs_palloc_destroy_cache() */ | ||
35 | 32 | ||
36 | #include <trace/events/nilfs2.h> | 33 | #include <trace/events/nilfs2.h> |
37 | 34 | ||
@@ -393,34 +390,6 @@ int nilfs_mdt_forget_block(struct inode *inode, unsigned long block) | |||
393 | return ret; | 390 | return ret; |
394 | } | 391 | } |
395 | 392 | ||
396 | /** | ||
397 | * nilfs_mdt_mark_block_dirty - mark a block on the meta data file dirty. | ||
398 | * @inode: inode of the meta data file | ||
399 | * @block: block offset | ||
400 | * | ||
401 | * Return Value: On success, it returns 0. On error, the following negative | ||
402 | * error code is returned. | ||
403 | * | ||
404 | * %-ENOMEM - Insufficient memory available. | ||
405 | * | ||
406 | * %-EIO - I/O error | ||
407 | * | ||
408 | * %-ENOENT - the specified block does not exist (hole block) | ||
409 | */ | ||
410 | int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) | ||
411 | { | ||
412 | struct buffer_head *bh; | ||
413 | int err; | ||
414 | |||
415 | err = nilfs_mdt_read_block(inode, block, 0, &bh); | ||
416 | if (unlikely(err)) | ||
417 | return err; | ||
418 | mark_buffer_dirty(bh); | ||
419 | nilfs_mdt_mark_dirty(inode); | ||
420 | brelse(bh); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | int nilfs_mdt_fetch_dirty(struct inode *inode) | 393 | int nilfs_mdt_fetch_dirty(struct inode *inode) |
425 | { | 394 | { |
426 | struct nilfs_inode_info *ii = NILFS_I(inode); | 395 | struct nilfs_inode_info *ii = NILFS_I(inode); |
@@ -497,8 +466,32 @@ int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz) | |||
497 | return 0; | 466 | return 0; |
498 | } | 467 | } |
499 | 468 | ||
500 | void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size, | 469 | /** |
501 | unsigned header_size) | 470 | * nilfs_mdt_clear - do cleanup for the metadata file |
471 | * @inode: inode of the metadata file | ||
472 | */ | ||
473 | void nilfs_mdt_clear(struct inode *inode) | ||
474 | { | ||
475 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
476 | |||
477 | if (mdi->mi_palloc_cache) | ||
478 | nilfs_palloc_destroy_cache(inode); | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * nilfs_mdt_destroy - release resources used by the metadata file | ||
483 | * @inode: inode of the metadata file | ||
484 | */ | ||
485 | void nilfs_mdt_destroy(struct inode *inode) | ||
486 | { | ||
487 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
488 | |||
489 | kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ | ||
490 | kfree(mdi); | ||
491 | } | ||
492 | |||
493 | void nilfs_mdt_set_entry_size(struct inode *inode, unsigned int entry_size, | ||
494 | unsigned int header_size) | ||
502 | { | 495 | { |
503 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); | 496 | struct nilfs_mdt_info *mi = NILFS_MDT(inode); |
504 | 497 | ||
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h index 03246cac3338..3f67f3932097 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_MDT_H | 19 | #ifndef _NILFS_MDT_H |
@@ -57,8 +53,8 @@ struct nilfs_shadow_map { | |||
57 | struct nilfs_mdt_info { | 53 | struct nilfs_mdt_info { |
58 | struct rw_semaphore mi_sem; | 54 | struct rw_semaphore mi_sem; |
59 | struct blockgroup_lock *mi_bgl; | 55 | struct blockgroup_lock *mi_bgl; |
60 | unsigned mi_entry_size; | 56 | unsigned int mi_entry_size; |
61 | unsigned mi_first_entry_offset; | 57 | unsigned int mi_first_entry_offset; |
62 | unsigned long mi_entries_per_block; | 58 | unsigned long mi_entries_per_block; |
63 | struct nilfs_palloc_cache *mi_palloc_cache; | 59 | struct nilfs_palloc_cache *mi_palloc_cache; |
64 | struct nilfs_shadow_map *mi_shadow; | 60 | struct nilfs_shadow_map *mi_shadow; |
@@ -71,6 +67,11 @@ static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode) | |||
71 | return inode->i_private; | 67 | return inode->i_private; |
72 | } | 68 | } |
73 | 69 | ||
70 | static inline int nilfs_is_metadata_file_inode(const struct inode *inode) | ||
71 | { | ||
72 | return inode->i_private != NULL; | ||
73 | } | ||
74 | |||
74 | /* Default GFP flags using highmem */ | 75 | /* Default GFP flags using highmem */ |
75 | #define NILFS_MDT_GFP (__GFP_RECLAIM | __GFP_IO | __GFP_HIGHMEM) | 76 | #define NILFS_MDT_GFP (__GFP_RECLAIM | __GFP_IO | __GFP_HIGHMEM) |
76 | 77 | ||
@@ -83,11 +84,13 @@ int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | |||
83 | struct buffer_head **out_bh); | 84 | struct buffer_head **out_bh); |
84 | int nilfs_mdt_delete_block(struct inode *, unsigned long); | 85 | int nilfs_mdt_delete_block(struct inode *, unsigned long); |
85 | int nilfs_mdt_forget_block(struct inode *, unsigned long); | 86 | int nilfs_mdt_forget_block(struct inode *, unsigned long); |
86 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); | ||
87 | int nilfs_mdt_fetch_dirty(struct inode *); | 87 | int nilfs_mdt_fetch_dirty(struct inode *); |
88 | 88 | ||
89 | int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz); | 89 | int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz); |
90 | void nilfs_mdt_set_entry_size(struct inode *, unsigned, unsigned); | 90 | void nilfs_mdt_clear(struct inode *inode); |
91 | void nilfs_mdt_destroy(struct inode *inode); | ||
92 | |||
93 | void nilfs_mdt_set_entry_size(struct inode *, unsigned int, unsigned int); | ||
91 | 94 | ||
92 | int nilfs_mdt_setup_shadow_map(struct inode *inode, | 95 | int nilfs_mdt_setup_shadow_map(struct inode *inode, |
93 | struct nilfs_shadow_map *shadow); | 96 | struct nilfs_shadow_map *shadow); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 3b2af05f9fb4..1ec8ae5995a5 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Modified for NILFS by Amagai Yoshiji and Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Modified for NILFS by Amagai Yoshiji <amagai@osrg.net>, | ||
21 | * Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | */ | 17 | */ |
23 | /* | 18 | /* |
24 | * linux/fs/ext2/namei.c | 19 | * linux/fs/ext2/namei.c |
@@ -49,6 +44,7 @@ | |||
49 | static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode) | 44 | static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode) |
50 | { | 45 | { |
51 | int err = nilfs_add_link(dentry, inode); | 46 | int err = nilfs_add_link(dentry, inode); |
47 | |||
52 | if (!err) { | 48 | if (!err) { |
53 | d_instantiate(dentry, inode); | 49 | d_instantiate(dentry, inode); |
54 | unlock_new_inode(inode); | 50 | unlock_new_inode(inode); |
@@ -143,7 +139,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry, | |||
143 | { | 139 | { |
144 | struct nilfs_transaction_info ti; | 140 | struct nilfs_transaction_info ti; |
145 | struct super_block *sb = dir->i_sb; | 141 | struct super_block *sb = dir->i_sb; |
146 | unsigned l = strlen(symname)+1; | 142 | unsigned int l = strlen(symname) + 1; |
147 | struct inode *inode; | 143 | struct inode *inode; |
148 | int err; | 144 | int err; |
149 | 145 | ||
@@ -288,7 +284,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry) | |||
288 | 284 | ||
289 | if (!inode->i_nlink) { | 285 | if (!inode->i_nlink) { |
290 | nilfs_warning(inode->i_sb, __func__, | 286 | nilfs_warning(inode->i_sb, __func__, |
291 | "deleting nonexistent file (%lu), %d\n", | 287 | "deleting nonexistent file (%lu), %d", |
292 | inode->i_ino, inode->i_nlink); | 288 | inode->i_ino, inode->i_nlink); |
293 | set_nlink(inode, 1); | 289 | set_nlink(inode, 1); |
294 | } | 290 | } |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 385704027575..b1d48bc0532d 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato and Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net> | ||
21 | * Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | */ | 17 | */ |
23 | 18 | ||
24 | #ifndef _NILFS_H | 19 | #ifndef _NILFS_H |
@@ -69,8 +64,10 @@ struct nilfs_inode_info { | |||
69 | */ | 64 | */ |
70 | struct rw_semaphore xattr_sem; | 65 | struct rw_semaphore xattr_sem; |
71 | #endif | 66 | #endif |
72 | struct buffer_head *i_bh; /* i_bh contains a new or dirty | 67 | struct buffer_head *i_bh; /* |
73 | disk inode */ | 68 | * i_bh contains a new or dirty |
69 | * disk inode. | ||
70 | */ | ||
74 | struct nilfs_root *i_root; | 71 | struct nilfs_root *i_root; |
75 | struct inode vfs_inode; | 72 | struct inode vfs_inode; |
76 | }; | 73 | }; |
@@ -100,8 +97,10 @@ enum { | |||
100 | NILFS_I_NEW = 0, /* Inode is newly created */ | 97 | NILFS_I_NEW = 0, /* Inode is newly created */ |
101 | NILFS_I_DIRTY, /* The file is dirty */ | 98 | NILFS_I_DIRTY, /* The file is dirty */ |
102 | NILFS_I_QUEUED, /* inode is in dirty_files list */ | 99 | NILFS_I_QUEUED, /* inode is in dirty_files list */ |
103 | NILFS_I_BUSY, /* inode is grabbed by a segment | 100 | NILFS_I_BUSY, /* |
104 | constructor */ | 101 | * Inode is grabbed by a segment |
102 | * constructor | ||
103 | */ | ||
105 | NILFS_I_COLLECTED, /* All dirty blocks are collected */ | 104 | NILFS_I_COLLECTED, /* All dirty blocks are collected */ |
106 | NILFS_I_UPDATED, /* The file has been written back */ | 105 | NILFS_I_UPDATED, /* The file has been written back */ |
107 | NILFS_I_INODE_SYNC, /* dsync is not allowed for inode */ | 106 | NILFS_I_INODE_SYNC, /* dsync is not allowed for inode */ |
@@ -145,8 +144,10 @@ enum { | |||
145 | struct nilfs_transaction_info { | 144 | struct nilfs_transaction_info { |
146 | u32 ti_magic; | 145 | u32 ti_magic; |
147 | void *ti_save; | 146 | void *ti_save; |
148 | /* This should never used. If this happens, | 147 | /* |
149 | one of other filesystems has a bug. */ | 148 | * This should never be used. If it happens, |
149 | * one of other filesystems has a bug. | ||
150 | */ | ||
150 | unsigned short ti_flags; | 151 | unsigned short ti_flags; |
151 | unsigned short ti_count; | 152 | unsigned short ti_count; |
152 | }; | 153 | }; |
@@ -156,8 +157,10 @@ struct nilfs_transaction_info { | |||
156 | 157 | ||
157 | /* ti_flags */ | 158 | /* ti_flags */ |
158 | #define NILFS_TI_DYNAMIC_ALLOC 0x0001 /* Allocated from slab */ | 159 | #define NILFS_TI_DYNAMIC_ALLOC 0x0001 /* Allocated from slab */ |
159 | #define NILFS_TI_SYNC 0x0002 /* Force to construct segment at the | 160 | #define NILFS_TI_SYNC 0x0002 /* |
160 | end of transaction. */ | 161 | * Force to construct segment at the |
162 | * end of transaction. | ||
163 | */ | ||
161 | #define NILFS_TI_GC 0x0004 /* GC context */ | 164 | #define NILFS_TI_GC 0x0004 /* GC context */ |
162 | #define NILFS_TI_COMMIT 0x0008 /* Change happened or not */ | 165 | #define NILFS_TI_COMMIT 0x0008 /* Change happened or not */ |
163 | #define NILFS_TI_WRITER 0x0010 /* Constructor context */ | 166 | #define NILFS_TI_WRITER 0x0010 /* Constructor context */ |
@@ -279,7 +282,7 @@ extern void nilfs_write_failed(struct address_space *mapping, loff_t to); | |||
279 | int nilfs_permission(struct inode *inode, int mask); | 282 | int nilfs_permission(struct inode *inode, int mask); |
280 | int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); | 283 | int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); |
281 | extern int nilfs_inode_dirty(struct inode *); | 284 | extern int nilfs_inode_dirty(struct inode *); |
282 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); | 285 | int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty); |
283 | extern int __nilfs_mark_inode_dirty(struct inode *, int); | 286 | extern int __nilfs_mark_inode_dirty(struct inode *, int); |
284 | extern void nilfs_dirty_inode(struct inode *, int flags); | 287 | extern void nilfs_dirty_inode(struct inode *, int flags); |
285 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 288 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 489391561cda..d97ba5f11b77 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi and Seiji Kihara. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net>, | ||
21 | * Seiji Kihara <kihara@osrg.net>. | ||
22 | */ | 17 | */ |
23 | 18 | ||
24 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
@@ -440,12 +435,12 @@ void nilfs_clear_dirty_page(struct page *page, bool silent) | |||
440 | __nilfs_clear_page_dirty(page); | 435 | __nilfs_clear_page_dirty(page); |
441 | } | 436 | } |
442 | 437 | ||
443 | unsigned nilfs_page_count_clean_buffers(struct page *page, | 438 | unsigned int nilfs_page_count_clean_buffers(struct page *page, |
444 | unsigned from, unsigned to) | 439 | unsigned int from, unsigned int to) |
445 | { | 440 | { |
446 | unsigned block_start, block_end; | 441 | unsigned int block_start, block_end; |
447 | struct buffer_head *bh, *head; | 442 | struct buffer_head *bh, *head; |
448 | unsigned nc = 0; | 443 | unsigned int nc = 0; |
449 | 444 | ||
450 | for (bh = head = page_buffers(page), block_start = 0; | 445 | for (bh = head = page_buffers(page), block_start = 0; |
451 | bh != head || !block_start; | 446 | bh != head || !block_start; |
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h index a43b8287d012..f3687c958fa8 100644 --- a/fs/nilfs2/page.h +++ b/fs/nilfs2/page.h | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi and Seiji Kihara. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net>, | ||
21 | * Seiji Kihara <kihara@osrg.net>. | ||
22 | */ | 17 | */ |
23 | 18 | ||
24 | #ifndef _NILFS_PAGE_H | 19 | #ifndef _NILFS_PAGE_H |
@@ -58,7 +53,8 @@ void nilfs_copy_back_pages(struct address_space *, struct address_space *); | |||
58 | void nilfs_clear_dirty_page(struct page *, bool); | 53 | void nilfs_clear_dirty_page(struct page *, bool); |
59 | void nilfs_clear_dirty_pages(struct address_space *, bool); | 54 | void nilfs_clear_dirty_pages(struct address_space *, bool); |
60 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode); | 55 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode); |
61 | unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); | 56 | unsigned int nilfs_page_count_clean_buffers(struct page *, unsigned int, |
57 | unsigned int); | ||
62 | unsigned long nilfs_find_uncommitted_extent(struct inode *inode, | 58 | unsigned long nilfs_find_uncommitted_extent(struct inode *inode, |
63 | sector_t start_blk, | 59 | sector_t start_blk, |
64 | sector_t *blkoff); | 60 | sector_t *blkoff); |
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index 5afa77fadc11..d893dc912b62 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
@@ -47,8 +43,10 @@ enum { | |||
47 | 43 | ||
48 | /* work structure for recovery */ | 44 | /* work structure for recovery */ |
49 | struct nilfs_recovery_block { | 45 | struct nilfs_recovery_block { |
50 | ino_t ino; /* Inode number of the file that this block | 46 | ino_t ino; /* |
51 | belongs to */ | 47 | * Inode number of the file that this block |
48 | * belongs to | ||
49 | */ | ||
52 | sector_t blocknr; /* block number */ | 50 | sector_t blocknr; /* block number */ |
53 | __u64 vblocknr; /* virtual block number */ | 51 | __u64 vblocknr; /* virtual block number */ |
54 | unsigned long blkoff; /* File offset of the data block (per block) */ | 52 | unsigned long blkoff; /* File offset of the data block (per block) */ |
@@ -156,7 +154,7 @@ int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block, | |||
156 | 154 | ||
157 | sr = (struct nilfs_super_root *)bh_sr->b_data; | 155 | sr = (struct nilfs_super_root *)bh_sr->b_data; |
158 | if (check) { | 156 | if (check) { |
159 | unsigned bytes = le16_to_cpu(sr->sr_bytes); | 157 | unsigned int bytes = le16_to_cpu(sr->sr_bytes); |
160 | 158 | ||
161 | if (bytes == 0 || bytes > nilfs->ns_blocksize) { | 159 | if (bytes == 0 || bytes > nilfs->ns_blocksize) { |
162 | ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; | 160 | ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; |
@@ -508,7 +506,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, | |||
508 | { | 506 | { |
509 | struct inode *inode; | 507 | struct inode *inode; |
510 | struct nilfs_recovery_block *rb, *n; | 508 | struct nilfs_recovery_block *rb, *n; |
511 | unsigned blocksize = nilfs->ns_blocksize; | 509 | unsigned int blocksize = nilfs->ns_blocksize; |
512 | struct page *page; | 510 | struct page *page; |
513 | loff_t pos; | 511 | loff_t pos; |
514 | int err = 0, err2 = 0; | 512 | int err = 0, err2 = 0; |
@@ -526,6 +524,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, | |||
526 | 0, &page, nilfs_get_block); | 524 | 0, &page, nilfs_get_block); |
527 | if (unlikely(err)) { | 525 | if (unlikely(err)) { |
528 | loff_t isize = inode->i_size; | 526 | loff_t isize = inode->i_size; |
527 | |||
529 | if (pos + blocksize > isize) | 528 | if (pos + blocksize > isize) |
530 | nilfs_write_failed(inode->i_mapping, | 529 | nilfs_write_failed(inode->i_mapping, |
531 | pos + blocksize); | 530 | pos + blocksize); |
@@ -872,9 +871,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, | |||
872 | 871 | ||
873 | flags = le16_to_cpu(sum->ss_flags); | 872 | flags = le16_to_cpu(sum->ss_flags); |
874 | if (!(flags & NILFS_SS_SR) && !scan_newer) { | 873 | if (!(flags & NILFS_SS_SR) && !scan_newer) { |
875 | /* This will never happen because a superblock | 874 | /* |
876 | (last_segment) always points to a pseg | 875 | * This will never happen because a superblock |
877 | having a super root. */ | 876 | * (last_segment) always points to a pseg with |
877 | * a super root. | ||
878 | */ | ||
878 | ret = NILFS_SEG_FAIL_CONSISTENCY; | 879 | ret = NILFS_SEG_FAIL_CONSISTENCY; |
879 | goto failed; | 880 | goto failed; |
880 | } | 881 | } |
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index f63620ce3892..bf36df10540b 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | 19 | ||
@@ -133,7 +129,7 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf, | |||
133 | return 0; | 129 | return 0; |
134 | } | 130 | } |
135 | 131 | ||
136 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, | 132 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned int flags, |
137 | time_t ctime, __u64 cno) | 133 | time_t ctime, __u64 cno) |
138 | { | 134 | { |
139 | int err; | 135 | int err; |
@@ -240,7 +236,7 @@ nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf, | |||
240 | { | 236 | { |
241 | struct nilfs_super_root *raw_sr; | 237 | struct nilfs_super_root *raw_sr; |
242 | struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info; | 238 | struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info; |
243 | unsigned srsize; | 239 | unsigned int srsize; |
244 | u32 crc; | 240 | u32 crc; |
245 | 241 | ||
246 | raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; | 242 | raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; |
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h index b04f08cc2397..7bbccc099709 100644 --- a/fs/nilfs2/segbuf.h +++ b/fs/nilfs2/segbuf.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | #ifndef _NILFS_SEGBUF_H | 19 | #ifndef _NILFS_SEGBUF_H |
@@ -82,7 +78,7 @@ struct nilfs_segment_buffer { | |||
82 | __u64 sb_nextnum; | 78 | __u64 sb_nextnum; |
83 | sector_t sb_fseg_start, sb_fseg_end; | 79 | sector_t sb_fseg_start, sb_fseg_end; |
84 | sector_t sb_pseg_start; | 80 | sector_t sb_pseg_start; |
85 | unsigned sb_rest_blocks; | 81 | unsigned int sb_rest_blocks; |
86 | 82 | ||
87 | /* Buffers */ | 83 | /* Buffers */ |
88 | struct list_head sb_segsum_buffers; | 84 | struct list_head sb_segsum_buffers; |
@@ -124,7 +120,8 @@ void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf, | |||
124 | struct nilfs_segment_buffer *prev); | 120 | struct nilfs_segment_buffer *prev); |
125 | void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, | 121 | void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, |
126 | struct the_nilfs *); | 122 | struct the_nilfs *); |
127 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t, __u64); | 123 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time_t, |
124 | __u64); | ||
128 | int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *); | 125 | int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *); |
129 | int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *, | 126 | int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *, |
130 | struct buffer_head **); | 127 | struct buffer_head **); |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 4317f72568e6..e78b68a81aec 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | 19 | ||
@@ -49,18 +45,26 @@ | |||
49 | */ | 45 | */ |
50 | #define SC_N_INODEVEC 16 /* Size of locally allocated inode vector */ | 46 | #define SC_N_INODEVEC 16 /* Size of locally allocated inode vector */ |
51 | 47 | ||
52 | #define SC_MAX_SEGDELTA 64 /* Upper limit of the number of segments | 48 | #define SC_MAX_SEGDELTA 64 /* |
53 | appended in collection retry loop */ | 49 | * Upper limit of the number of segments |
50 | * appended in collection retry loop | ||
51 | */ | ||
54 | 52 | ||
55 | /* Construction mode */ | 53 | /* Construction mode */ |
56 | enum { | 54 | enum { |
57 | SC_LSEG_SR = 1, /* Make a logical segment having a super root */ | 55 | SC_LSEG_SR = 1, /* Make a logical segment having a super root */ |
58 | SC_LSEG_DSYNC, /* Flush data blocks of a given file and make | 56 | SC_LSEG_DSYNC, /* |
59 | a logical segment without a super root */ | 57 | * Flush data blocks of a given file and make |
60 | SC_FLUSH_FILE, /* Flush data files, leads to segment writes without | 58 | * a logical segment without a super root. |
61 | creating a checkpoint */ | 59 | */ |
62 | SC_FLUSH_DAT, /* Flush DAT file. This also creates segments without | 60 | SC_FLUSH_FILE, /* |
63 | a checkpoint */ | 61 | * Flush data files, leads to segment writes without |
62 | * creating a checkpoint. | ||
63 | */ | ||
64 | SC_FLUSH_DAT, /* | ||
65 | * Flush DAT file. This also creates segments | ||
66 | * without a checkpoint. | ||
67 | */ | ||
64 | }; | 68 | }; |
65 | 69 | ||
66 | /* Stage numbers of dirty block collection */ | 70 | /* Stage numbers of dirty block collection */ |
@@ -154,17 +158,15 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti) | |||
154 | if (cur_ti) { | 158 | if (cur_ti) { |
155 | if (cur_ti->ti_magic == NILFS_TI_MAGIC) | 159 | if (cur_ti->ti_magic == NILFS_TI_MAGIC) |
156 | return ++cur_ti->ti_count; | 160 | return ++cur_ti->ti_count; |
157 | else { | 161 | |
158 | /* | 162 | /* |
159 | * If journal_info field is occupied by other FS, | 163 | * If journal_info field is occupied by other FS, |
160 | * it is saved and will be restored on | 164 | * it is saved and will be restored on |
161 | * nilfs_transaction_commit(). | 165 | * nilfs_transaction_commit(). |
162 | */ | 166 | */ |
163 | printk(KERN_WARNING | 167 | printk(KERN_WARNING |
164 | "NILFS warning: journal info from a different " | 168 | "NILFS warning: journal info from a different FS\n"); |
165 | "FS\n"); | 169 | save = current->journal_info; |
166 | save = current->journal_info; | ||
167 | } | ||
168 | } | 170 | } |
169 | if (!ti) { | 171 | if (!ti) { |
170 | ti = kmem_cache_alloc(nilfs_transaction_cachep, GFP_NOFS); | 172 | ti = kmem_cache_alloc(nilfs_transaction_cachep, GFP_NOFS); |
@@ -397,10 +399,10 @@ static void nilfs_transaction_unlock(struct super_block *sb) | |||
397 | 399 | ||
398 | static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci, | 400 | static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci, |
399 | struct nilfs_segsum_pointer *ssp, | 401 | struct nilfs_segsum_pointer *ssp, |
400 | unsigned bytes) | 402 | unsigned int bytes) |
401 | { | 403 | { |
402 | struct nilfs_segment_buffer *segbuf = sci->sc_curseg; | 404 | struct nilfs_segment_buffer *segbuf = sci->sc_curseg; |
403 | unsigned blocksize = sci->sc_super->s_blocksize; | 405 | unsigned int blocksize = sci->sc_super->s_blocksize; |
404 | void *p; | 406 | void *p; |
405 | 407 | ||
406 | if (unlikely(ssp->offset + bytes > blocksize)) { | 408 | if (unlikely(ssp->offset + bytes > blocksize)) { |
@@ -422,8 +424,8 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci) | |||
422 | { | 424 | { |
423 | struct nilfs_segment_buffer *segbuf = sci->sc_curseg; | 425 | struct nilfs_segment_buffer *segbuf = sci->sc_curseg; |
424 | struct buffer_head *sumbh; | 426 | struct buffer_head *sumbh; |
425 | unsigned sumbytes; | 427 | unsigned int sumbytes; |
426 | unsigned flags = 0; | 428 | unsigned int flags = 0; |
427 | int err; | 429 | int err; |
428 | 430 | ||
429 | if (nilfs_doing_gc()) | 431 | if (nilfs_doing_gc()) |
@@ -444,8 +446,10 @@ static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci) | |||
444 | { | 446 | { |
445 | sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks; | 447 | sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks; |
446 | if (NILFS_SEGBUF_IS_LAST(sci->sc_curseg, &sci->sc_segbufs)) | 448 | if (NILFS_SEGBUF_IS_LAST(sci->sc_curseg, &sci->sc_segbufs)) |
447 | return -E2BIG; /* The current segment is filled up | 449 | return -E2BIG; /* |
448 | (internal code) */ | 450 | * The current segment is filled up |
451 | * (internal code) | ||
452 | */ | ||
449 | sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg); | 453 | sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg); |
450 | return nilfs_segctor_reset_segment_buffer(sci); | 454 | return nilfs_segctor_reset_segment_buffer(sci); |
451 | } | 455 | } |
@@ -472,9 +476,9 @@ static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci) | |||
472 | */ | 476 | */ |
473 | static int nilfs_segctor_segsum_block_required( | 477 | static int nilfs_segctor_segsum_block_required( |
474 | struct nilfs_sc_info *sci, const struct nilfs_segsum_pointer *ssp, | 478 | struct nilfs_sc_info *sci, const struct nilfs_segsum_pointer *ssp, |
475 | unsigned binfo_size) | 479 | unsigned int binfo_size) |
476 | { | 480 | { |
477 | unsigned blocksize = sci->sc_super->s_blocksize; | 481 | unsigned int blocksize = sci->sc_super->s_blocksize; |
478 | /* Size of finfo and binfo is enough small against blocksize */ | 482 | /* Size of finfo and binfo is enough small against blocksize */ |
479 | 483 | ||
480 | return ssp->offset + binfo_size + | 484 | return ssp->offset + binfo_size + |
@@ -533,7 +537,7 @@ static void nilfs_segctor_end_finfo(struct nilfs_sc_info *sci, | |||
533 | static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci, | 537 | static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci, |
534 | struct buffer_head *bh, | 538 | struct buffer_head *bh, |
535 | struct inode *inode, | 539 | struct inode *inode, |
536 | unsigned binfo_size) | 540 | unsigned int binfo_size) |
537 | { | 541 | { |
538 | struct nilfs_segment_buffer *segbuf; | 542 | struct nilfs_segment_buffer *segbuf; |
539 | int required, err = 0; | 543 | int required, err = 0; |
@@ -617,7 +621,7 @@ static void nilfs_write_file_node_binfo(struct nilfs_sc_info *sci, | |||
617 | *vblocknr = binfo->bi_v.bi_vblocknr; | 621 | *vblocknr = binfo->bi_v.bi_vblocknr; |
618 | } | 622 | } |
619 | 623 | ||
620 | static struct nilfs_sc_operations nilfs_sc_file_ops = { | 624 | static const struct nilfs_sc_operations nilfs_sc_file_ops = { |
621 | .collect_data = nilfs_collect_file_data, | 625 | .collect_data = nilfs_collect_file_data, |
622 | .collect_node = nilfs_collect_file_node, | 626 | .collect_node = nilfs_collect_file_node, |
623 | .collect_bmap = nilfs_collect_file_bmap, | 627 | .collect_bmap = nilfs_collect_file_bmap, |
@@ -666,7 +670,7 @@ static void nilfs_write_dat_node_binfo(struct nilfs_sc_info *sci, | |||
666 | *binfo_dat = binfo->bi_dat; | 670 | *binfo_dat = binfo->bi_dat; |
667 | } | 671 | } |
668 | 672 | ||
669 | static struct nilfs_sc_operations nilfs_sc_dat_ops = { | 673 | static const struct nilfs_sc_operations nilfs_sc_dat_ops = { |
670 | .collect_data = nilfs_collect_dat_data, | 674 | .collect_data = nilfs_collect_dat_data, |
671 | .collect_node = nilfs_collect_file_node, | 675 | .collect_node = nilfs_collect_file_node, |
672 | .collect_bmap = nilfs_collect_dat_bmap, | 676 | .collect_bmap = nilfs_collect_dat_bmap, |
@@ -674,7 +678,7 @@ static struct nilfs_sc_operations nilfs_sc_dat_ops = { | |||
674 | .write_node_binfo = nilfs_write_dat_node_binfo, | 678 | .write_node_binfo = nilfs_write_dat_node_binfo, |
675 | }; | 679 | }; |
676 | 680 | ||
677 | static struct nilfs_sc_operations nilfs_sc_dsync_ops = { | 681 | static const struct nilfs_sc_operations nilfs_sc_dsync_ops = { |
678 | .collect_data = nilfs_collect_file_data, | 682 | .collect_data = nilfs_collect_file_data, |
679 | .collect_node = NULL, | 683 | .collect_node = NULL, |
680 | .collect_bmap = NULL, | 684 | .collect_bmap = NULL, |
@@ -777,7 +781,7 @@ static void nilfs_dispose_list(struct the_nilfs *nilfs, | |||
777 | { | 781 | { |
778 | struct nilfs_inode_info *ii, *n; | 782 | struct nilfs_inode_info *ii, *n; |
779 | struct nilfs_inode_info *ivec[SC_N_INODEVEC], **pii; | 783 | struct nilfs_inode_info *ivec[SC_N_INODEVEC], **pii; |
780 | unsigned nv = 0; | 784 | unsigned int nv = 0; |
781 | 785 | ||
782 | while (!list_empty(head)) { | 786 | while (!list_empty(head)) { |
783 | spin_lock(&nilfs->ns_inode_lock); | 787 | spin_lock(&nilfs->ns_inode_lock); |
@@ -875,9 +879,11 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) | |||
875 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 1, | 879 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 1, |
876 | &raw_cp, &bh_cp); | 880 | &raw_cp, &bh_cp); |
877 | if (likely(!err)) { | 881 | if (likely(!err)) { |
878 | /* The following code is duplicated with cpfile. But, it is | 882 | /* |
879 | needed to collect the checkpoint even if it was not newly | 883 | * The following code is duplicated with cpfile. But, it is |
880 | created */ | 884 | * needed to collect the checkpoint even if it was not newly |
885 | * created. | ||
886 | */ | ||
881 | mark_buffer_dirty(bh_cp); | 887 | mark_buffer_dirty(bh_cp); |
882 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); | 888 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); |
883 | nilfs_cpfile_put_checkpoint( | 889 | nilfs_cpfile_put_checkpoint( |
@@ -958,7 +964,7 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, | |||
958 | { | 964 | { |
959 | struct buffer_head *bh_sr; | 965 | struct buffer_head *bh_sr; |
960 | struct nilfs_super_root *raw_sr; | 966 | struct nilfs_super_root *raw_sr; |
961 | unsigned isz, srsz; | 967 | unsigned int isz, srsz; |
962 | 968 | ||
963 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; | 969 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; |
964 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; | 970 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; |
@@ -1043,7 +1049,7 @@ static size_t nilfs_segctor_buffer_rest(struct nilfs_sc_info *sci) | |||
1043 | 1049 | ||
1044 | static int nilfs_segctor_scan_file(struct nilfs_sc_info *sci, | 1050 | static int nilfs_segctor_scan_file(struct nilfs_sc_info *sci, |
1045 | struct inode *inode, | 1051 | struct inode *inode, |
1046 | struct nilfs_sc_operations *sc_ops) | 1052 | const struct nilfs_sc_operations *sc_ops) |
1047 | { | 1053 | { |
1048 | LIST_HEAD(data_buffers); | 1054 | LIST_HEAD(data_buffers); |
1049 | LIST_HEAD(node_buffers); | 1055 | LIST_HEAD(node_buffers); |
@@ -1406,8 +1412,10 @@ static void nilfs_free_incomplete_logs(struct list_head *logs, | |||
1406 | if (atomic_read(&segbuf->sb_err)) { | 1412 | if (atomic_read(&segbuf->sb_err)) { |
1407 | /* Case 1: The first segment failed */ | 1413 | /* Case 1: The first segment failed */ |
1408 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) | 1414 | if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) |
1409 | /* Case 1a: Partial segment appended into an existing | 1415 | /* |
1410 | segment */ | 1416 | * Case 1a: Partial segment appended into an existing |
1417 | * segment | ||
1418 | */ | ||
1411 | nilfs_terminate_segment(nilfs, segbuf->sb_fseg_start, | 1419 | nilfs_terminate_segment(nilfs, segbuf->sb_fseg_start, |
1412 | segbuf->sb_fseg_end); | 1420 | segbuf->sb_fseg_end); |
1413 | else /* Case 1b: New full segment */ | 1421 | else /* Case 1b: New full segment */ |
@@ -1550,7 +1558,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci, | |||
1550 | sector_t blocknr; | 1558 | sector_t blocknr; |
1551 | unsigned long nfinfo = segbuf->sb_sum.nfinfo; | 1559 | unsigned long nfinfo = segbuf->sb_sum.nfinfo; |
1552 | unsigned long nblocks = 0, ndatablk = 0; | 1560 | unsigned long nblocks = 0, ndatablk = 0; |
1553 | struct nilfs_sc_operations *sc_op = NULL; | 1561 | const struct nilfs_sc_operations *sc_op = NULL; |
1554 | struct nilfs_segsum_pointer ssp; | 1562 | struct nilfs_segsum_pointer ssp; |
1555 | struct nilfs_finfo *finfo = NULL; | 1563 | struct nilfs_finfo *finfo = NULL; |
1556 | union nilfs_binfo binfo; | 1564 | union nilfs_binfo binfo; |
@@ -1631,8 +1639,10 @@ static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode) | |||
1631 | static void nilfs_begin_page_io(struct page *page) | 1639 | static void nilfs_begin_page_io(struct page *page) |
1632 | { | 1640 | { |
1633 | if (!page || PageWriteback(page)) | 1641 | if (!page || PageWriteback(page)) |
1634 | /* For split b-tree node pages, this function may be called | 1642 | /* |
1635 | twice. We ignore the 2nd or later calls by this check. */ | 1643 | * For split b-tree node pages, this function may be called |
1644 | * twice. We ignore the 2nd or later calls by this check. | ||
1645 | */ | ||
1636 | return; | 1646 | return; |
1637 | 1647 | ||
1638 | lock_page(page); | 1648 | lock_page(page); |
@@ -1942,7 +1952,7 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, | |||
1942 | ifile, ii->vfs_inode.i_ino, &ibh); | 1952 | ifile, ii->vfs_inode.i_ino, &ibh); |
1943 | if (unlikely(err)) { | 1953 | if (unlikely(err)) { |
1944 | nilfs_warning(sci->sc_super, __func__, | 1954 | nilfs_warning(sci->sc_super, __func__, |
1945 | "failed to get inode block.\n"); | 1955 | "failed to get inode block."); |
1946 | return err; | 1956 | return err; |
1947 | } | 1957 | } |
1948 | mark_buffer_dirty(ibh); | 1958 | mark_buffer_dirty(ibh); |
@@ -2395,6 +2405,7 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | |||
2395 | static void nilfs_construction_timeout(unsigned long data) | 2405 | static void nilfs_construction_timeout(unsigned long data) |
2396 | { | 2406 | { |
2397 | struct task_struct *p = (struct task_struct *)data; | 2407 | struct task_struct *p = (struct task_struct *)data; |
2408 | |||
2398 | wake_up_process(p); | 2409 | wake_up_process(p); |
2399 | } | 2410 | } |
2400 | 2411 | ||
@@ -2555,10 +2566,10 @@ static int nilfs_segctor_thread(void *arg) | |||
2555 | 2566 | ||
2556 | if (timeout || sci->sc_seq_request != sci->sc_seq_done) | 2567 | if (timeout || sci->sc_seq_request != sci->sc_seq_done) |
2557 | mode = SC_LSEG_SR; | 2568 | mode = SC_LSEG_SR; |
2558 | else if (!sci->sc_flush_request) | 2569 | else if (sci->sc_flush_request) |
2559 | break; | ||
2560 | else | ||
2561 | mode = nilfs_segctor_flush_mode(sci); | 2570 | mode = nilfs_segctor_flush_mode(sci); |
2571 | else | ||
2572 | break; | ||
2562 | 2573 | ||
2563 | spin_unlock(&sci->sc_state_lock); | 2574 | spin_unlock(&sci->sc_state_lock); |
2564 | nilfs_segctor_thread_construct(sci, mode); | 2575 | nilfs_segctor_thread_construct(sci, mode); |
@@ -2684,8 +2695,10 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) | |||
2684 | { | 2695 | { |
2685 | int ret, retrycount = NILFS_SC_CLEANUP_RETRY; | 2696 | int ret, retrycount = NILFS_SC_CLEANUP_RETRY; |
2686 | 2697 | ||
2687 | /* The segctord thread was stopped and its timer was removed. | 2698 | /* |
2688 | But some tasks remain. */ | 2699 | * The segctord thread was stopped and its timer was removed. |
2700 | * But some tasks remain. | ||
2701 | */ | ||
2689 | do { | 2702 | do { |
2690 | struct nilfs_transaction_info ti; | 2703 | struct nilfs_transaction_info ti; |
2691 | 2704 | ||
@@ -2727,13 +2740,13 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2727 | 2740 | ||
2728 | if (!list_empty(&sci->sc_dirty_files)) { | 2741 | if (!list_empty(&sci->sc_dirty_files)) { |
2729 | nilfs_warning(sci->sc_super, __func__, | 2742 | nilfs_warning(sci->sc_super, __func__, |
2730 | "dirty file(s) after the final construction\n"); | 2743 | "dirty file(s) after the final construction"); |
2731 | nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1); | 2744 | nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1); |
2732 | } | 2745 | } |
2733 | 2746 | ||
2734 | if (!list_empty(&sci->sc_iput_queue)) { | 2747 | if (!list_empty(&sci->sc_iput_queue)) { |
2735 | nilfs_warning(sci->sc_super, __func__, | 2748 | nilfs_warning(sci->sc_super, __func__, |
2736 | "iput queue is not empty\n"); | 2749 | "iput queue is not empty"); |
2737 | nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1); | 2750 | nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1); |
2738 | } | 2751 | } |
2739 | 2752 | ||
@@ -2810,7 +2823,7 @@ void nilfs_detach_log_writer(struct super_block *sb) | |||
2810 | if (!list_empty(&nilfs->ns_dirty_files)) { | 2823 | if (!list_empty(&nilfs->ns_dirty_files)) { |
2811 | list_splice_init(&nilfs->ns_dirty_files, &garbage_list); | 2824 | list_splice_init(&nilfs->ns_dirty_files, &garbage_list); |
2812 | nilfs_warning(sb, __func__, | 2825 | nilfs_warning(sb, __func__, |
2813 | "Hit dirty file after stopped log writer\n"); | 2826 | "Hit dirty file after stopped log writer"); |
2814 | } | 2827 | } |
2815 | spin_unlock(&nilfs->ns_inode_lock); | 2828 | spin_unlock(&nilfs->ns_inode_lock); |
2816 | up_write(&nilfs->ns_segctor_sem); | 2829 | up_write(&nilfs->ns_segctor_sem); |
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 0408b9b2814b..6565c10b7b76 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | #ifndef _NILFS_SEGMENT_H | 19 | #ifndef _NILFS_SEGMENT_H |
@@ -75,7 +71,7 @@ struct nilfs_recovery_info { | |||
75 | */ | 71 | */ |
76 | struct nilfs_cstage { | 72 | struct nilfs_cstage { |
77 | int scnt; | 73 | int scnt; |
78 | unsigned flags; | 74 | unsigned int flags; |
79 | struct nilfs_inode_info *dirty_file_ptr; | 75 | struct nilfs_inode_info *dirty_file_ptr; |
80 | struct nilfs_inode_info *gc_inode_ptr; | 76 | struct nilfs_inode_info *gc_inode_ptr; |
81 | }; | 77 | }; |
@@ -84,7 +80,7 @@ struct nilfs_segment_buffer; | |||
84 | 80 | ||
85 | struct nilfs_segsum_pointer { | 81 | struct nilfs_segsum_pointer { |
86 | struct buffer_head *bh; | 82 | struct buffer_head *bh; |
87 | unsigned offset; /* offset in bytes */ | 83 | unsigned int offset; /* offset in bytes */ |
88 | }; | 84 | }; |
89 | 85 | ||
90 | /** | 86 | /** |
@@ -193,11 +189,15 @@ enum { | |||
193 | NILFS_SC_DIRTY, /* One or more dirty meta-data blocks exist */ | 189 | NILFS_SC_DIRTY, /* One or more dirty meta-data blocks exist */ |
194 | NILFS_SC_UNCLOSED, /* Logical segment is not closed */ | 190 | NILFS_SC_UNCLOSED, /* Logical segment is not closed */ |
195 | NILFS_SC_SUPER_ROOT, /* The latest segment has a super root */ | 191 | NILFS_SC_SUPER_ROOT, /* The latest segment has a super root */ |
196 | NILFS_SC_PRIOR_FLUSH, /* Requesting immediate flush without making a | 192 | NILFS_SC_PRIOR_FLUSH, /* |
197 | checkpoint */ | 193 | * Requesting immediate flush without making a |
198 | NILFS_SC_HAVE_DELTA, /* Next checkpoint will have update of files | 194 | * checkpoint |
199 | other than DAT, cpfile, sufile, or files | 195 | */ |
200 | moved by GC */ | 196 | NILFS_SC_HAVE_DELTA, /* |
197 | * Next checkpoint will have update of files | ||
198 | * other than DAT, cpfile, sufile, or files | ||
199 | * moved by GC. | ||
200 | */ | ||
201 | }; | 201 | }; |
202 | 202 | ||
203 | /* sc_state */ | 203 | /* sc_state */ |
@@ -207,17 +207,23 @@ enum { | |||
207 | /* | 207 | /* |
208 | * Constant parameters | 208 | * Constant parameters |
209 | */ | 209 | */ |
210 | #define NILFS_SC_CLEANUP_RETRY 3 /* Retry count of construction when | 210 | #define NILFS_SC_CLEANUP_RETRY 3 /* |
211 | destroying segctord */ | 211 | * Retry count of construction when |
212 | * destroying segctord | ||
213 | */ | ||
212 | 214 | ||
213 | /* | 215 | /* |
214 | * Default values of timeout, in seconds. | 216 | * Default values of timeout, in seconds. |
215 | */ | 217 | */ |
216 | #define NILFS_SC_DEFAULT_TIMEOUT 5 /* Timeout value of dirty blocks. | 218 | #define NILFS_SC_DEFAULT_TIMEOUT 5 /* |
217 | It triggers construction of a | 219 | * Timeout value of dirty blocks. |
218 | logical segment with a super root */ | 220 | * It triggers construction of a |
219 | #define NILFS_SC_DEFAULT_SR_FREQ 30 /* Maximum frequency of super root | 221 | * logical segment with a super root. |
220 | creation */ | 222 | */ |
223 | #define NILFS_SC_DEFAULT_SR_FREQ 30 /* | ||
224 | * Maximum frequency of super root | ||
225 | * creation | ||
226 | */ | ||
221 | 227 | ||
222 | /* | 228 | /* |
223 | * The default threshold amount of data, in block counts. | 229 | * The default threshold amount of data, in block counts. |
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 52821ffc11f4..1963595a1580 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -13,12 +13,8 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | 17 | * Revised by Ryusuke Konishi. |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | * Revised by Ryusuke Konishi <ryusuke@osrg.net>. | ||
22 | */ | 18 | */ |
23 | 19 | ||
24 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -61,6 +57,7 @@ static unsigned long | |||
61 | nilfs_sufile_get_blkoff(const struct inode *sufile, __u64 segnum) | 57 | nilfs_sufile_get_blkoff(const struct inode *sufile, __u64 segnum) |
62 | { | 58 | { |
63 | __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; | 59 | __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; |
60 | |||
64 | do_div(t, nilfs_sufile_segment_usages_per_block(sufile)); | 61 | do_div(t, nilfs_sufile_segment_usages_per_block(sufile)); |
65 | return (unsigned long)t; | 62 | return (unsigned long)t; |
66 | } | 63 | } |
@@ -69,6 +66,7 @@ static unsigned long | |||
69 | nilfs_sufile_get_offset(const struct inode *sufile, __u64 segnum) | 66 | nilfs_sufile_get_offset(const struct inode *sufile, __u64 segnum) |
70 | { | 67 | { |
71 | __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; | 68 | __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; |
69 | |||
72 | return do_div(t, nilfs_sufile_segment_usages_per_block(sufile)); | 70 | return do_div(t, nilfs_sufile_segment_usages_per_block(sufile)); |
73 | } | 71 | } |
74 | 72 | ||
@@ -819,7 +817,7 @@ out: | |||
819 | * %-ENOMEM - Insufficient amount of memory available. | 817 | * %-ENOMEM - Insufficient amount of memory available. |
820 | */ | 818 | */ |
821 | ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, | 819 | ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, |
822 | unsigned sisz, size_t nsi) | 820 | unsigned int sisz, size_t nsi) |
823 | { | 821 | { |
824 | struct buffer_head *su_bh; | 822 | struct buffer_head *su_bh; |
825 | struct nilfs_segment_usage *su; | 823 | struct nilfs_segment_usage *su; |
@@ -897,7 +895,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, | |||
897 | * %-EINVAL - Invalid values in input (segment number, flags or nblocks) | 895 | * %-EINVAL - Invalid values in input (segment number, flags or nblocks) |
898 | */ | 896 | */ |
899 | ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf, | 897 | ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf, |
900 | unsigned supsz, size_t nsup) | 898 | unsigned int supsz, size_t nsup) |
901 | { | 899 | { |
902 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; | 900 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; |
903 | struct buffer_head *header_bh, *bh; | 901 | struct buffer_head *header_bh, *bh; |
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index b8afd72f2379..46e89872294c 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Koji Sato. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net>. | ||
21 | */ | 17 | */ |
22 | 18 | ||
23 | #ifndef _NILFS_SUFILE_H | 19 | #ifndef _NILFS_SUFILE_H |
@@ -42,9 +38,9 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); | |||
42 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, | 38 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, |
43 | unsigned long nblocks, time_t modtime); | 39 | unsigned long nblocks, time_t modtime); |
44 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); | 40 | int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); |
45 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned, | 41 | ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned int, |
46 | size_t); | 42 | size_t); |
47 | ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned , size_t); | 43 | ssize_t nilfs_sufile_set_suinfo(struct inode *, void *, unsigned int, size_t); |
48 | 44 | ||
49 | int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *, | 45 | int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *, |
50 | void (*dofunc)(struct inode *, __u64, | 46 | void (*dofunc)(struct inode *, __u64, |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7f5d3d9f1c37..666107a18a22 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | */ | 17 | */ |
22 | /* | 18 | /* |
23 | * linux/fs/ext2/super.c | 19 | * linux/fs/ext2/super.c |
@@ -173,12 +169,10 @@ struct inode *nilfs_alloc_inode(struct super_block *sb) | |||
173 | static void nilfs_i_callback(struct rcu_head *head) | 169 | static void nilfs_i_callback(struct rcu_head *head) |
174 | { | 170 | { |
175 | struct inode *inode = container_of(head, struct inode, i_rcu); | 171 | struct inode *inode = container_of(head, struct inode, i_rcu); |
176 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
177 | 172 | ||
178 | if (mdi) { | 173 | if (nilfs_is_metadata_file_inode(inode)) |
179 | kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ | 174 | nilfs_mdt_destroy(inode); |
180 | kfree(mdi); | 175 | |
181 | } | ||
182 | kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); | 176 | kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); |
183 | } | 177 | } |
184 | 178 | ||
@@ -279,7 +273,7 @@ struct nilfs_super_block **nilfs_prepare_super(struct super_block *sb, | |||
279 | } | 273 | } |
280 | } else if (sbp[1] && | 274 | } else if (sbp[1] && |
281 | sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { | 275 | sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { |
282 | memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); | 276 | memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); |
283 | } | 277 | } |
284 | 278 | ||
285 | if (flip && sbp[1]) | 279 | if (flip && sbp[1]) |
@@ -749,6 +743,7 @@ static int parse_options(char *options, struct super_block *sb, int is_remount) | |||
749 | 743 | ||
750 | while ((p = strsep(&options, ",")) != NULL) { | 744 | while ((p = strsep(&options, ",")) != NULL) { |
751 | int token; | 745 | int token; |
746 | |||
752 | if (!*p) | 747 | if (!*p) |
753 | continue; | 748 | continue; |
754 | 749 | ||
@@ -891,7 +886,7 @@ int nilfs_store_magic_and_option(struct super_block *sb, | |||
891 | nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); | 886 | nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); |
892 | nilfs->ns_watermark = le32_to_cpu(sbp->s_c_block_max); | 887 | nilfs->ns_watermark = le32_to_cpu(sbp->s_c_block_max); |
893 | 888 | ||
894 | return !parse_options(data, sb, 0) ? -EINVAL : 0 ; | 889 | return !parse_options(data, sb, 0) ? -EINVAL : 0; |
895 | } | 890 | } |
896 | 891 | ||
897 | int nilfs_check_feature_compatibility(struct super_block *sb, | 892 | int nilfs_check_feature_compatibility(struct super_block *sb, |
@@ -1316,7 +1311,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1316 | } | 1311 | } |
1317 | 1312 | ||
1318 | if (!s->s_root) { | 1313 | if (!s->s_root) { |
1319 | s_new = true; | 1314 | s_new = true; |
1320 | 1315 | ||
1321 | /* New superblock instance created */ | 1316 | /* New superblock instance created */ |
1322 | s->s_mode = mode; | 1317 | s->s_mode = mode; |
diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c index bbb0dcc35905..8ffa42b704d8 100644 --- a/fs/nilfs2/sysfs.c +++ b/fs/nilfs2/sysfs.c | |||
@@ -68,7 +68,7 @@ static ssize_t nilfs_##name##_attr_store(struct kobject *kobj, \ | |||
68 | static const struct sysfs_ops nilfs_##name##_attr_ops = { \ | 68 | static const struct sysfs_ops nilfs_##name##_attr_ops = { \ |
69 | .show = nilfs_##name##_attr_show, \ | 69 | .show = nilfs_##name##_attr_show, \ |
70 | .store = nilfs_##name##_attr_store, \ | 70 | .store = nilfs_##name##_attr_store, \ |
71 | }; | 71 | } |
72 | 72 | ||
73 | #define NILFS_DEV_INT_GROUP_TYPE(name, parent_name) \ | 73 | #define NILFS_DEV_INT_GROUP_TYPE(name, parent_name) \ |
74 | static void nilfs_##name##_attr_release(struct kobject *kobj) \ | 74 | static void nilfs_##name##_attr_release(struct kobject *kobj) \ |
@@ -84,7 +84,7 @@ static struct kobj_type nilfs_##name##_ktype = { \ | |||
84 | .default_attrs = nilfs_##name##_attrs, \ | 84 | .default_attrs = nilfs_##name##_attrs, \ |
85 | .sysfs_ops = &nilfs_##name##_attr_ops, \ | 85 | .sysfs_ops = &nilfs_##name##_attr_ops, \ |
86 | .release = nilfs_##name##_attr_release, \ | 86 | .release = nilfs_##name##_attr_release, \ |
87 | }; | 87 | } |
88 | 88 | ||
89 | #define NILFS_DEV_INT_GROUP_FNS(name, parent_name) \ | 89 | #define NILFS_DEV_INT_GROUP_FNS(name, parent_name) \ |
90 | static int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \ | 90 | static int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \ |
@@ -756,7 +756,7 @@ nilfs_superblock_sb_write_count_show(struct nilfs_superblock_attr *attr, | |||
756 | struct the_nilfs *nilfs, | 756 | struct the_nilfs *nilfs, |
757 | char *buf) | 757 | char *buf) |
758 | { | 758 | { |
759 | unsigned sbwcount; | 759 | unsigned int sbwcount; |
760 | 760 | ||
761 | down_read(&nilfs->ns_sem); | 761 | down_read(&nilfs->ns_sem); |
762 | sbwcount = nilfs->ns_sbwcount; | 762 | sbwcount = nilfs->ns_sbwcount; |
@@ -770,7 +770,7 @@ nilfs_superblock_sb_update_frequency_show(struct nilfs_superblock_attr *attr, | |||
770 | struct the_nilfs *nilfs, | 770 | struct the_nilfs *nilfs, |
771 | char *buf) | 771 | char *buf) |
772 | { | 772 | { |
773 | unsigned sb_update_freq; | 773 | unsigned int sb_update_freq; |
774 | 774 | ||
775 | down_read(&nilfs->ns_sem); | 775 | down_read(&nilfs->ns_sem); |
776 | sb_update_freq = nilfs->ns_sb_update_freq; | 776 | sb_update_freq = nilfs->ns_sb_update_freq; |
@@ -784,7 +784,7 @@ nilfs_superblock_sb_update_frequency_store(struct nilfs_superblock_attr *attr, | |||
784 | struct the_nilfs *nilfs, | 784 | struct the_nilfs *nilfs, |
785 | const char *buf, size_t count) | 785 | const char *buf, size_t count) |
786 | { | 786 | { |
787 | unsigned val; | 787 | unsigned int val; |
788 | int err; | 788 | int err; |
789 | 789 | ||
790 | err = kstrtouint(skip_spaces(buf), 0, &val); | 790 | err = kstrtouint(skip_spaces(buf), 0, &val); |
diff --git a/fs/nilfs2/sysfs.h b/fs/nilfs2/sysfs.h index 677e3a1a8370..648cedf9c06e 100644 --- a/fs/nilfs2/sysfs.h +++ b/fs/nilfs2/sysfs.h | |||
@@ -66,7 +66,7 @@ struct nilfs_##name##_attr { \ | |||
66 | char *); \ | 66 | char *); \ |
67 | ssize_t (*store)(struct kobject *, struct attribute *, \ | 67 | ssize_t (*store)(struct kobject *, struct attribute *, \ |
68 | const char *, size_t); \ | 68 | const char *, size_t); \ |
69 | }; | 69 | } |
70 | 70 | ||
71 | NILFS_COMMON_ATTR_STRUCT(feature); | 71 | NILFS_COMMON_ATTR_STRUCT(feature); |
72 | 72 | ||
@@ -77,7 +77,7 @@ struct nilfs_##name##_attr { \ | |||
77 | char *); \ | 77 | char *); \ |
78 | ssize_t (*store)(struct nilfs_##name##_attr *, struct the_nilfs *, \ | 78 | ssize_t (*store)(struct nilfs_##name##_attr *, struct the_nilfs *, \ |
79 | const char *, size_t); \ | 79 | const char *, size_t); \ |
80 | }; | 80 | } |
81 | 81 | ||
82 | NILFS_DEV_ATTR_STRUCT(dev); | 82 | NILFS_DEV_ATTR_STRUCT(dev); |
83 | NILFS_DEV_ATTR_STRUCT(segments); | 83 | NILFS_DEV_ATTR_STRUCT(segments); |
@@ -93,7 +93,7 @@ struct nilfs_##name##_attr { \ | |||
93 | char *); \ | 93 | char *); \ |
94 | ssize_t (*store)(struct nilfs_##name##_attr *, struct nilfs_root *, \ | 94 | ssize_t (*store)(struct nilfs_##name##_attr *, struct nilfs_root *, \ |
95 | const char *, size_t); \ | 95 | const char *, size_t); \ |
96 | }; | 96 | } |
97 | 97 | ||
98 | NILFS_CP_ATTR_STRUCT(snapshot); | 98 | NILFS_CP_ATTR_STRUCT(snapshot); |
99 | 99 | ||
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 69bd801afb53..809bd2de7ad0 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | 19 | ||
@@ -112,8 +108,8 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs, | |||
112 | struct nilfs_super_root *raw_sr; | 108 | struct nilfs_super_root *raw_sr; |
113 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | 109 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
114 | struct nilfs_inode *rawi; | 110 | struct nilfs_inode *rawi; |
115 | unsigned dat_entry_size, segment_usage_size, checkpoint_size; | 111 | unsigned int dat_entry_size, segment_usage_size, checkpoint_size; |
116 | unsigned inode_size; | 112 | unsigned int inode_size; |
117 | int err; | 113 | int err; |
118 | 114 | ||
119 | err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1); | 115 | err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1); |
@@ -621,8 +617,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) | |||
621 | err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); | 617 | err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); |
622 | if (err) | 618 | if (err) |
623 | goto out; | 619 | goto out; |
624 | /* not failed_sbh; sbh is released automatically | 620 | /* |
625 | when reloading fails. */ | 621 | * Not to failed_sbh; sbh is released automatically |
622 | * when reloading fails. | ||
623 | */ | ||
626 | } | 624 | } |
627 | nilfs->ns_blocksize_bits = sb->s_blocksize_bits; | 625 | nilfs->ns_blocksize_bits = sb->s_blocksize_bits; |
628 | nilfs->ns_blocksize = blocksize; | 626 | nilfs->ns_blocksize = blocksize; |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 23778d385836..79369fd6b13b 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -13,11 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * Written by Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Ryusuke Konishi <ryusuke@osrg.net> | ||
21 | * | 17 | * |
22 | */ | 18 | */ |
23 | 19 | ||
@@ -118,10 +114,10 @@ struct the_nilfs { | |||
118 | struct buffer_head *ns_sbh[2]; | 114 | struct buffer_head *ns_sbh[2]; |
119 | struct nilfs_super_block *ns_sbp[2]; | 115 | struct nilfs_super_block *ns_sbp[2]; |
120 | time_t ns_sbwtime; | 116 | time_t ns_sbwtime; |
121 | unsigned ns_sbwcount; | 117 | unsigned int ns_sbwcount; |
122 | unsigned ns_sbsize; | 118 | unsigned int ns_sbsize; |
123 | unsigned ns_mount_state; | 119 | unsigned int ns_mount_state; |
124 | unsigned ns_sb_update_freq; | 120 | unsigned int ns_sb_update_freq; |
125 | 121 | ||
126 | /* | 122 | /* |
127 | * Following fields are dedicated to a writable FS-instance. | 123 | * Following fields are dedicated to a writable FS-instance. |
@@ -226,15 +222,14 @@ THE_NILFS_FNS(SB_DIRTY, sb_dirty) | |||
226 | * Mount option operations | 222 | * Mount option operations |
227 | */ | 223 | */ |
228 | #define nilfs_clear_opt(nilfs, opt) \ | 224 | #define nilfs_clear_opt(nilfs, opt) \ |
229 | do { (nilfs)->ns_mount_opt &= ~NILFS_MOUNT_##opt; } while (0) | 225 | ((nilfs)->ns_mount_opt &= ~NILFS_MOUNT_##opt) |
230 | #define nilfs_set_opt(nilfs, opt) \ | 226 | #define nilfs_set_opt(nilfs, opt) \ |
231 | do { (nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt; } while (0) | 227 | ((nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt) |
232 | #define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt) | 228 | #define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt) |
233 | #define nilfs_write_opt(nilfs, mask, opt) \ | 229 | #define nilfs_write_opt(nilfs, mask, opt) \ |
234 | do { (nilfs)->ns_mount_opt = \ | 230 | ((nilfs)->ns_mount_opt = \ |
235 | (((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) | \ | 231 | (((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) | \ |
236 | NILFS_MOUNT_##opt); \ | 232 | NILFS_MOUNT_##opt)) \ |
237 | } while (0) | ||
238 | 233 | ||
239 | /** | 234 | /** |
240 | * struct nilfs_root - nilfs root object | 235 | * struct nilfs_root - nilfs root object |
@@ -273,6 +268,7 @@ struct nilfs_root { | |||
273 | static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) | 268 | static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) |
274 | { | 269 | { |
275 | u64 t = get_seconds(); | 270 | u64 t = get_seconds(); |
271 | |||
276 | return t < nilfs->ns_sbwtime || | 272 | return t < nilfs->ns_sbwtime || |
277 | t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq; | 273 | t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq; |
278 | } | 274 | } |
@@ -280,6 +276,7 @@ static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) | |||
280 | static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs) | 276 | static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs) |
281 | { | 277 | { |
282 | int flip_bits = nilfs->ns_sbwcount & 0x0FL; | 278 | int flip_bits = nilfs->ns_sbwcount & 0x0FL; |
279 | |||
283 | return (flip_bits != 0x08 && flip_bits != 0x0F); | 280 | return (flip_bits != 0x08 && flip_bits != 0x0F); |
284 | } | 281 | } |
285 | 282 | ||
@@ -308,7 +305,7 @@ static inline void nilfs_get_root(struct nilfs_root *root) | |||
308 | 305 | ||
309 | static inline int nilfs_valid_fs(struct the_nilfs *nilfs) | 306 | static inline int nilfs_valid_fs(struct the_nilfs *nilfs) |
310 | { | 307 | { |
311 | unsigned valid_fs; | 308 | unsigned int valid_fs; |
312 | 309 | ||
313 | down_read(&nilfs->ns_sem); | 310 | down_read(&nilfs->ns_sem); |
314 | valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS); | 311 | valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS); |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 541583510cfb..4648c7f63ae2 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -1027,11 +1027,15 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
1027 | }; | 1027 | }; |
1028 | 1028 | ||
1029 | if (type == CLEAR_REFS_MM_HIWATER_RSS) { | 1029 | if (type == CLEAR_REFS_MM_HIWATER_RSS) { |
1030 | if (down_write_killable(&mm->mmap_sem)) { | ||
1031 | count = -EINTR; | ||
1032 | goto out_mm; | ||
1033 | } | ||
1034 | |||
1030 | /* | 1035 | /* |
1031 | * Writing 5 to /proc/pid/clear_refs resets the peak | 1036 | * Writing 5 to /proc/pid/clear_refs resets the peak |
1032 | * resident set size to this mm's current rss value. | 1037 | * resident set size to this mm's current rss value. |
1033 | */ | 1038 | */ |
1034 | down_write(&mm->mmap_sem); | ||
1035 | reset_mm_hiwater_rss(mm); | 1039 | reset_mm_hiwater_rss(mm); |
1036 | up_write(&mm->mmap_sem); | 1040 | up_write(&mm->mmap_sem); |
1037 | goto out_mm; | 1041 | goto out_mm; |
@@ -1043,7 +1047,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
1043 | if (!(vma->vm_flags & VM_SOFTDIRTY)) | 1047 | if (!(vma->vm_flags & VM_SOFTDIRTY)) |
1044 | continue; | 1048 | continue; |
1045 | up_read(&mm->mmap_sem); | 1049 | up_read(&mm->mmap_sem); |
1046 | down_write(&mm->mmap_sem); | 1050 | if (down_write_killable(&mm->mmap_sem)) { |
1051 | count = -EINTR; | ||
1052 | goto out_mm; | ||
1053 | } | ||
1047 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 1054 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
1048 | vma->vm_flags &= ~VM_SOFTDIRTY; | 1055 | vma->vm_flags &= ~VM_SOFTDIRTY; |
1049 | vma_set_page_prot(vma); | 1056 | vma_set_page_prot(vma); |
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 2cc643c6e870..e8acb2b43dd9 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -230,8 +230,6 @@ extern void crash_kexec(struct pt_regs *); | |||
230 | int kexec_should_crash(struct task_struct *); | 230 | int kexec_should_crash(struct task_struct *); |
231 | void crash_save_cpu(struct pt_regs *regs, int cpu); | 231 | void crash_save_cpu(struct pt_regs *regs, int cpu); |
232 | void crash_save_vmcoreinfo(void); | 232 | void crash_save_vmcoreinfo(void); |
233 | void crash_map_reserved_pages(void); | ||
234 | void crash_unmap_reserved_pages(void); | ||
235 | void arch_crash_save_vmcoreinfo(void); | 233 | void arch_crash_save_vmcoreinfo(void); |
236 | __printf(1, 2) | 234 | __printf(1, 2) |
237 | void vmcoreinfo_append_str(const char *fmt, ...); | 235 | void vmcoreinfo_append_str(const char *fmt, ...); |
@@ -317,6 +315,8 @@ int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, | |||
317 | Elf_Shdr *sechdrs, unsigned int relsec); | 315 | Elf_Shdr *sechdrs, unsigned int relsec); |
318 | int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | 316 | int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, |
319 | unsigned int relsec); | 317 | unsigned int relsec); |
318 | void arch_kexec_protect_crashkres(void); | ||
319 | void arch_kexec_unprotect_crashkres(void); | ||
320 | 320 | ||
321 | #else /* !CONFIG_KEXEC_CORE */ | 321 | #else /* !CONFIG_KEXEC_CORE */ |
322 | struct pt_regs; | 322 | struct pt_regs; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index b530c99e8e81..2835d598d258 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -2011,9 +2011,9 @@ static inline void mm_populate(unsigned long addr, unsigned long len) {} | |||
2011 | #endif | 2011 | #endif |
2012 | 2012 | ||
2013 | /* These take the mm semaphore themselves */ | 2013 | /* These take the mm semaphore themselves */ |
2014 | extern unsigned long vm_brk(unsigned long, unsigned long); | 2014 | extern unsigned long __must_check vm_brk(unsigned long, unsigned long); |
2015 | extern int vm_munmap(unsigned long, size_t); | 2015 | extern int vm_munmap(unsigned long, size_t); |
2016 | extern unsigned long vm_mmap(struct file *, unsigned long, | 2016 | extern unsigned long __must_check vm_mmap(struct file *, unsigned long, |
2017 | unsigned long, unsigned long, | 2017 | unsigned long, unsigned long, |
2018 | unsigned long, unsigned long); | 2018 | unsigned long, unsigned long); |
2019 | 2019 | ||
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index e9fcf90b270d..5988dd57ba66 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h | |||
@@ -13,12 +13,7 @@ | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. | 14 | * GNU Lesser General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License | 16 | * Written by Koji Sato and Ryusuke Konishi. |
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | * | ||
20 | * Written by Koji Sato <koji@osrg.net> | ||
21 | * Ryusuke Konishi <ryusuke@osrg.net> | ||
22 | */ | 17 | */ |
23 | /* | 18 | /* |
24 | * linux/include/linux/ext2_fs.h | 19 | * linux/include/linux/ext2_fs.h |
@@ -132,10 +127,14 @@ struct nilfs_super_root { | |||
132 | #define NILFS_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ | 127 | #define NILFS_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ |
133 | #define NILFS_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ | 128 | #define NILFS_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ |
134 | #define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */ | 129 | #define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */ |
135 | #define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order | 130 | #define NILFS_MOUNT_STRICT_ORDER 0x2000 /* |
136 | semantics also for data */ | 131 | * Apply strict in-order |
137 | #define NILFS_MOUNT_NORECOVERY 0x4000 /* Disable write access during | 132 | * semantics also for data |
138 | mount-time recovery */ | 133 | */ |
134 | #define NILFS_MOUNT_NORECOVERY 0x4000 /* | ||
135 | * Disable write access during | ||
136 | * mount-time recovery | ||
137 | */ | ||
139 | #define NILFS_MOUNT_DISCARD 0x8000 /* Issue DISCARD requests */ | 138 | #define NILFS_MOUNT_DISCARD 0x8000 /* Issue DISCARD requests */ |
140 | 139 | ||
141 | 140 | ||
@@ -147,16 +146,20 @@ struct nilfs_super_block { | |||
147 | __le16 s_minor_rev_level; /* minor revision level */ | 146 | __le16 s_minor_rev_level; /* minor revision level */ |
148 | __le16 s_magic; /* Magic signature */ | 147 | __le16 s_magic; /* Magic signature */ |
149 | 148 | ||
150 | __le16 s_bytes; /* Bytes count of CRC calculation | 149 | __le16 s_bytes; /* |
151 | for this structure. s_reserved | 150 | * Bytes count of CRC calculation |
152 | is excluded. */ | 151 | * for this structure. s_reserved |
152 | * is excluded. | ||
153 | */ | ||
153 | __le16 s_flags; /* flags */ | 154 | __le16 s_flags; /* flags */ |
154 | __le32 s_crc_seed; /* Seed value of CRC calculation */ | 155 | __le32 s_crc_seed; /* Seed value of CRC calculation */ |
155 | /*10*/ __le32 s_sum; /* Check sum of super block */ | 156 | /*10*/ __le32 s_sum; /* Check sum of super block */ |
156 | 157 | ||
157 | __le32 s_log_block_size; /* Block size represented as follows | 158 | __le32 s_log_block_size; /* |
158 | blocksize = | 159 | * Block size represented as follows |
159 | 1 << (s_log_block_size + 10) */ | 160 | * blocksize = |
161 | * 1 << (s_log_block_size + 10) | ||
162 | */ | ||
160 | __le64 s_nsegments; /* Number of segments in filesystem */ | 163 | __le64 s_nsegments; /* Number of segments in filesystem */ |
161 | /*20*/ __le64 s_dev_size; /* block device size in bytes */ | 164 | /*20*/ __le64 s_dev_size; /* block device size in bytes */ |
162 | __le64 s_first_data_block; /* 1st seg disk block number */ | 165 | __le64 s_first_data_block; /* 1st seg disk block number */ |
@@ -168,8 +171,10 @@ struct nilfs_super_block { | |||
168 | __le64 s_last_seq; /* seq. number of seg written last */ | 171 | __le64 s_last_seq; /* seq. number of seg written last */ |
169 | /*50*/ __le64 s_free_blocks_count; /* Free blocks count */ | 172 | /*50*/ __le64 s_free_blocks_count; /* Free blocks count */ |
170 | 173 | ||
171 | __le64 s_ctime; /* Creation time (execution time of | 174 | __le64 s_ctime; /* |
172 | newfs) */ | 175 | * Creation time (execution time of |
176 | * newfs) | ||
177 | */ | ||
173 | /*60*/ __le64 s_mtime; /* Mount time */ | 178 | /*60*/ __le64 s_mtime; /* Mount time */ |
174 | __le64 s_wtime; /* Write time */ | 179 | __le64 s_wtime; /* Write time */ |
175 | /*70*/ __le16 s_mnt_count; /* Mount count */ | 180 | /*70*/ __le16 s_mnt_count; /* Mount count */ |
@@ -193,8 +198,10 @@ struct nilfs_super_block { | |||
193 | /*A8*/ char s_volume_name[80]; /* volume name */ | 198 | /*A8*/ char s_volume_name[80]; /* volume name */ |
194 | 199 | ||
195 | /*F8*/ __le32 s_c_interval; /* Commit interval of segment */ | 200 | /*F8*/ __le32 s_c_interval; /* Commit interval of segment */ |
196 | __le32 s_c_block_max; /* Threshold of data amount for | 201 | __le32 s_c_block_max; /* |
197 | the segment construction */ | 202 | * Threshold of data amount for |
203 | * the segment construction | ||
204 | */ | ||
198 | /*100*/ __le64 s_feature_compat; /* Compatible feature set */ | 205 | /*100*/ __le64 s_feature_compat; /* Compatible feature set */ |
199 | __le64 s_feature_compat_ro; /* Read-only compatible feature set */ | 206 | __le64 s_feature_compat_ro; /* Read-only compatible feature set */ |
200 | __le64 s_feature_incompat; /* Incompatible feature set */ | 207 | __le64 s_feature_incompat; /* Incompatible feature set */ |
@@ -247,12 +254,18 @@ struct nilfs_super_block { | |||
247 | 254 | ||
248 | #define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */ | 255 | #define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */ |
249 | 256 | ||
250 | #define NILFS_SEG_MIN_BLOCKS 16 /* Minimum number of blocks in | 257 | #define NILFS_SEG_MIN_BLOCKS 16 /* |
251 | a full segment */ | 258 | * Minimum number of blocks in |
252 | #define NILFS_PSEG_MIN_BLOCKS 2 /* Minimum number of blocks in | 259 | * a full segment |
253 | a partial segment */ | 260 | */ |
254 | #define NILFS_MIN_NRSVSEGS 8 /* Minimum number of reserved | 261 | #define NILFS_PSEG_MIN_BLOCKS 2 /* |
255 | segments */ | 262 | * Minimum number of blocks in |
263 | * a partial segment | ||
264 | */ | ||
265 | #define NILFS_MIN_NRSVSEGS 8 /* | ||
266 | * Minimum number of reserved | ||
267 | * segments | ||
268 | */ | ||
256 | 269 | ||
257 | /* | 270 | /* |
258 | * We call DAT, cpfile, and sufile root metadata files. Inodes of | 271 | * We call DAT, cpfile, and sufile root metadata files. Inodes of |
@@ -327,9 +340,9 @@ enum { | |||
327 | ~NILFS_DIR_ROUND) | 340 | ~NILFS_DIR_ROUND) |
328 | #define NILFS_MAX_REC_LEN ((1<<16)-1) | 341 | #define NILFS_MAX_REC_LEN ((1<<16)-1) |
329 | 342 | ||
330 | static inline unsigned nilfs_rec_len_from_disk(__le16 dlen) | 343 | static inline unsigned int nilfs_rec_len_from_disk(__le16 dlen) |
331 | { | 344 | { |
332 | unsigned len = le16_to_cpu(dlen); | 345 | unsigned int len = le16_to_cpu(dlen); |
333 | 346 | ||
334 | #if !defined(__KERNEL__) || (PAGE_SIZE >= 65536) | 347 | #if !defined(__KERNEL__) || (PAGE_SIZE >= 65536) |
335 | if (len == NILFS_MAX_REC_LEN) | 348 | if (len == NILFS_MAX_REC_LEN) |
@@ -338,7 +351,7 @@ static inline unsigned nilfs_rec_len_from_disk(__le16 dlen) | |||
338 | return len; | 351 | return len; |
339 | } | 352 | } |
340 | 353 | ||
341 | static inline __le16 nilfs_rec_len_to_disk(unsigned len) | 354 | static inline __le16 nilfs_rec_len_to_disk(unsigned int len) |
342 | { | 355 | { |
343 | #if !defined(__KERNEL__) || (PAGE_SIZE >= 65536) | 356 | #if !defined(__KERNEL__) || (PAGE_SIZE >= 65536) |
344 | if (len == (1 << 16)) | 357 | if (len == (1 << 16)) |
@@ -518,9 +531,11 @@ struct nilfs_checkpoint { | |||
518 | __le64 cp_inodes_count; | 531 | __le64 cp_inodes_count; |
519 | __le64 cp_blocks_count; | 532 | __le64 cp_blocks_count; |
520 | 533 | ||
521 | /* Do not change the byte offset of ifile inode. | 534 | /* |
522 | To keep the compatibility of the disk format, | 535 | * Do not change the byte offset of ifile inode. |
523 | additional fields should be added behind cp_ifile_inode. */ | 536 | * To keep the compatibility of the disk format, |
537 | * additional fields should be added behind cp_ifile_inode. | ||
538 | */ | ||
524 | struct nilfs_inode cp_ifile_inode; | 539 | struct nilfs_inode cp_ifile_inode; |
525 | }; | 540 | }; |
526 | 541 | ||
diff --git a/include/linux/oom.h b/include/linux/oom.h index d3f533f2f481..83469522690a 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
@@ -50,24 +50,21 @@ enum oom_scan_t { | |||
50 | OOM_SCAN_SELECT, /* always select this thread first */ | 50 | OOM_SCAN_SELECT, /* always select this thread first */ |
51 | }; | 51 | }; |
52 | 52 | ||
53 | /* Thread is the potential origin of an oom condition; kill first on oom */ | ||
54 | #define OOM_FLAG_ORIGIN ((__force oom_flags_t)0x1) | ||
55 | |||
56 | extern struct mutex oom_lock; | 53 | extern struct mutex oom_lock; |
57 | 54 | ||
58 | static inline void set_current_oom_origin(void) | 55 | static inline void set_current_oom_origin(void) |
59 | { | 56 | { |
60 | current->signal->oom_flags |= OOM_FLAG_ORIGIN; | 57 | current->signal->oom_flag_origin = true; |
61 | } | 58 | } |
62 | 59 | ||
63 | static inline void clear_current_oom_origin(void) | 60 | static inline void clear_current_oom_origin(void) |
64 | { | 61 | { |
65 | current->signal->oom_flags &= ~OOM_FLAG_ORIGIN; | 62 | current->signal->oom_flag_origin = false; |
66 | } | 63 | } |
67 | 64 | ||
68 | static inline bool oom_task_origin(const struct task_struct *p) | 65 | static inline bool oom_task_origin(const struct task_struct *p) |
69 | { | 66 | { |
70 | return !!(p->signal->oom_flags & OOM_FLAG_ORIGIN); | 67 | return p->signal->oom_flag_origin; |
71 | } | 68 | } |
72 | 69 | ||
73 | extern void mark_oom_victim(struct task_struct *tsk); | 70 | extern void mark_oom_victim(struct task_struct *tsk); |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c036de6c1ee..21c26e78aec5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -794,7 +794,11 @@ struct signal_struct { | |||
794 | struct tty_audit_buf *tty_audit_buf; | 794 | struct tty_audit_buf *tty_audit_buf; |
795 | #endif | 795 | #endif |
796 | 796 | ||
797 | oom_flags_t oom_flags; | 797 | /* |
798 | * Thread is the potential origin of an oom condition; kill first on | ||
799 | * oom | ||
800 | */ | ||
801 | bool oom_flag_origin; | ||
798 | short oom_score_adj; /* OOM kill score adjustment */ | 802 | short oom_score_adj; /* OOM kill score adjustment */ |
799 | short oom_score_adj_min; /* OOM kill score adjustment min value. | 803 | short oom_score_adj_min; /* OOM kill score adjustment min value. |
800 | * Only settable by CAP_SYS_RESOURCE. */ | 804 | * Only settable by CAP_SYS_RESOURCE. */ |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 639be264f5f9..b63f63eaa39c 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -400,7 +400,9 @@ int unhandled_signal(struct task_struct *tsk, int sig); | |||
400 | #else | 400 | #else |
401 | #define rt_sigmask(sig) sigmask(sig) | 401 | #define rt_sigmask(sig) sigmask(sig) |
402 | #endif | 402 | #endif |
403 | #define siginmask(sig, mask) (rt_sigmask(sig) & (mask)) | 403 | |
404 | #define siginmask(sig, mask) \ | ||
405 | ((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) | ||
404 | 406 | ||
405 | #define SIG_KERNEL_ONLY_MASK (\ | 407 | #define SIG_KERNEL_ONLY_MASK (\ |
406 | rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP)) | 408 | rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP)) |
@@ -421,14 +423,10 @@ int unhandled_signal(struct task_struct *tsk, int sig); | |||
421 | rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \ | 423 | rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \ |
422 | rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) ) | 424 | rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) ) |
423 | 425 | ||
424 | #define sig_kernel_only(sig) \ | 426 | #define sig_kernel_only(sig) siginmask(sig, SIG_KERNEL_ONLY_MASK) |
425 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK)) | 427 | #define sig_kernel_coredump(sig) siginmask(sig, SIG_KERNEL_COREDUMP_MASK) |
426 | #define sig_kernel_coredump(sig) \ | 428 | #define sig_kernel_ignore(sig) siginmask(sig, SIG_KERNEL_IGNORE_MASK) |
427 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK)) | 429 | #define sig_kernel_stop(sig) siginmask(sig, SIG_KERNEL_STOP_MASK) |
428 | #define sig_kernel_ignore(sig) \ | ||
429 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK)) | ||
430 | #define sig_kernel_stop(sig) \ | ||
431 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK)) | ||
432 | 430 | ||
433 | #define sig_user_defined(t, signr) \ | 431 | #define sig_user_defined(t, signr) \ |
434 | (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ | 432 | (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ |
diff --git a/include/linux/types.h b/include/linux/types.h index 70dd3dfde631..baf718324f4a 100644 --- a/include/linux/types.h +++ b/include/linux/types.h | |||
@@ -156,7 +156,6 @@ typedef u32 dma_addr_t; | |||
156 | 156 | ||
157 | typedef unsigned __bitwise__ gfp_t; | 157 | typedef unsigned __bitwise__ gfp_t; |
158 | typedef unsigned __bitwise__ fmode_t; | 158 | typedef unsigned __bitwise__ fmode_t; |
159 | typedef unsigned __bitwise__ oom_flags_t; | ||
160 | 159 | ||
161 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | 160 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
162 | typedef u64 phys_addr_t; | 161 | typedef u64 phys_addr_t; |
@@ -1200,7 +1200,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
1200 | if (err) | 1200 | if (err) |
1201 | goto out_fput; | 1201 | goto out_fput; |
1202 | 1202 | ||
1203 | down_write(¤t->mm->mmap_sem); | 1203 | if (down_write_killable(¤t->mm->mmap_sem)) { |
1204 | err = -EINTR; | ||
1205 | goto out_fput; | ||
1206 | } | ||
1207 | |||
1204 | if (addr && !(shmflg & SHM_REMAP)) { | 1208 | if (addr && !(shmflg & SHM_REMAP)) { |
1205 | err = -EINVAL; | 1209 | err = -EINVAL; |
1206 | if (addr + size < addr) | 1210 | if (addr + size < addr) |
@@ -1271,7 +1275,8 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) | |||
1271 | if (addr & ~PAGE_MASK) | 1275 | if (addr & ~PAGE_MASK) |
1272 | return retval; | 1276 | return retval; |
1273 | 1277 | ||
1274 | down_write(&mm->mmap_sem); | 1278 | if (down_write_killable(&mm->mmap_sem)) |
1279 | return -EINTR; | ||
1275 | 1280 | ||
1276 | /* | 1281 | /* |
1277 | * This function tries to be smart and unmap shm segments that | 1282 | * This function tries to be smart and unmap shm segments that |
diff --git a/kernel/Makefile b/kernel/Makefile index f0c40bf49d9f..e2ec54e2b952 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -91,9 +91,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o | |||
91 | obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o | 91 | obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o |
92 | obj-$(CONFIG_TRACEPOINTS) += tracepoint.o | 92 | obj-$(CONFIG_TRACEPOINTS) += tracepoint.o |
93 | obj-$(CONFIG_LATENCYTOP) += latencytop.o | 93 | obj-$(CONFIG_LATENCYTOP) += latencytop.o |
94 | obj-$(CONFIG_BINFMT_ELF) += elfcore.o | 94 | obj-$(CONFIG_ELFCORE) += elfcore.o |
95 | obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o | ||
96 | obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o | ||
97 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ | 95 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ |
98 | obj-$(CONFIG_TRACING) += trace/ | 96 | obj-$(CONFIG_TRACING) += trace/ |
99 | obj-$(CONFIG_TRACE_CLOCK) += trace/ | 97 | obj-$(CONFIG_TRACE_CLOCK) += trace/ |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index c01f733ff2e1..b7a525ab2083 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1130,7 +1130,9 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area) | |||
1130 | struct vm_area_struct *vma; | 1130 | struct vm_area_struct *vma; |
1131 | int ret; | 1131 | int ret; |
1132 | 1132 | ||
1133 | down_write(&mm->mmap_sem); | 1133 | if (down_write_killable(&mm->mmap_sem)) |
1134 | return -EINTR; | ||
1135 | |||
1134 | if (mm->uprobes_state.xol_area) { | 1136 | if (mm->uprobes_state.xol_area) { |
1135 | ret = -EALREADY; | 1137 | ret = -EALREADY; |
1136 | goto fail; | 1138 | goto fail; |
@@ -1469,7 +1471,8 @@ static void dup_xol_work(struct callback_head *work) | |||
1469 | if (current->flags & PF_EXITING) | 1471 | if (current->flags & PF_EXITING) |
1470 | return; | 1472 | return; |
1471 | 1473 | ||
1472 | if (!__create_xol_area(current->utask->dup_xol_addr)) | 1474 | if (!__create_xol_area(current->utask->dup_xol_addr) && |
1475 | !fatal_signal_pending(current)) | ||
1473 | uprobe_warn(current, "dup xol area"); | 1476 | uprobe_warn(current, "dup xol area"); |
1474 | } | 1477 | } |
1475 | 1478 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 75b34fe835b2..9e6e1356e6bb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -918,17 +918,28 @@ static int eligible_pid(struct wait_opts *wo, struct task_struct *p) | |||
918 | task_pid_type(p, wo->wo_type) == wo->wo_pid; | 918 | task_pid_type(p, wo->wo_type) == wo->wo_pid; |
919 | } | 919 | } |
920 | 920 | ||
921 | static int eligible_child(struct wait_opts *wo, struct task_struct *p) | 921 | static int |
922 | eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p) | ||
922 | { | 923 | { |
923 | if (!eligible_pid(wo, p)) | 924 | if (!eligible_pid(wo, p)) |
924 | return 0; | 925 | return 0; |
925 | /* Wait for all children (clone and not) if __WALL is set; | 926 | |
926 | * otherwise, wait for clone children *only* if __WCLONE is | 927 | /* |
927 | * set; otherwise, wait for non-clone children *only*. (Note: | 928 | * Wait for all children (clone and not) if __WALL is set or |
928 | * A "clone" child here is one that reports to its parent | 929 | * if it is traced by us. |
929 | * using a signal other than SIGCHLD.) */ | 930 | */ |
930 | if (((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE)) | 931 | if (ptrace || (wo->wo_flags & __WALL)) |
931 | && !(wo->wo_flags & __WALL)) | 932 | return 1; |
933 | |||
934 | /* | ||
935 | * Otherwise, wait for clone children *only* if __WCLONE is set; | ||
936 | * otherwise, wait for non-clone children *only*. | ||
937 | * | ||
938 | * Note: a "clone" child here is one that reports to its parent | ||
939 | * using a signal other than SIGCHLD, or a non-leader thread which | ||
940 | * we can only see if it is traced by us. | ||
941 | */ | ||
942 | if ((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE)) | ||
932 | return 0; | 943 | return 0; |
933 | 944 | ||
934 | return 1; | 945 | return 1; |
@@ -1300,7 +1311,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1300 | if (unlikely(exit_state == EXIT_DEAD)) | 1311 | if (unlikely(exit_state == EXIT_DEAD)) |
1301 | return 0; | 1312 | return 0; |
1302 | 1313 | ||
1303 | ret = eligible_child(wo, p); | 1314 | ret = eligible_child(wo, ptrace, p); |
1304 | if (!ret) | 1315 | if (!ret) |
1305 | return ret; | 1316 | return ret; |
1306 | 1317 | ||
@@ -1524,7 +1535,8 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, | |||
1524 | enum pid_type type; | 1535 | enum pid_type type; |
1525 | long ret; | 1536 | long ret; |
1526 | 1537 | ||
1527 | if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED)) | 1538 | if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED| |
1539 | __WNOTHREAD|__WCLONE|__WALL)) | ||
1528 | return -EINVAL; | 1540 | return -EINVAL; |
1529 | if (!(options & (WEXITED|WSTOPPED|WCONTINUED))) | 1541 | if (!(options & (WEXITED|WSTOPPED|WCONTINUED))) |
1530 | return -EINVAL; | 1542 | return -EINVAL; |
diff --git a/kernel/fork.c b/kernel/fork.c index 103d78fd8f75..47887bba944f 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -340,13 +340,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) | |||
340 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | 340 | *stackend = STACK_END_MAGIC; /* for overflow detection */ |
341 | } | 341 | } |
342 | 342 | ||
343 | static struct task_struct *dup_task_struct(struct task_struct *orig) | 343 | static struct task_struct *dup_task_struct(struct task_struct *orig, int node) |
344 | { | 344 | { |
345 | struct task_struct *tsk; | 345 | struct task_struct *tsk; |
346 | struct thread_info *ti; | 346 | struct thread_info *ti; |
347 | int node = tsk_fork_get_node(orig); | ||
348 | int err; | 347 | int err; |
349 | 348 | ||
349 | if (node == NUMA_NO_NODE) | ||
350 | node = tsk_fork_get_node(orig); | ||
350 | tsk = alloc_task_struct_node(node); | 351 | tsk = alloc_task_struct_node(node); |
351 | if (!tsk) | 352 | if (!tsk) |
352 | return NULL; | 353 | return NULL; |
@@ -413,7 +414,10 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
413 | unsigned long charge; | 414 | unsigned long charge; |
414 | 415 | ||
415 | uprobe_start_dup_mmap(); | 416 | uprobe_start_dup_mmap(); |
416 | down_write(&oldmm->mmap_sem); | 417 | if (down_write_killable(&oldmm->mmap_sem)) { |
418 | retval = -EINTR; | ||
419 | goto fail_uprobe_end; | ||
420 | } | ||
417 | flush_cache_dup_mm(oldmm); | 421 | flush_cache_dup_mm(oldmm); |
418 | uprobe_dup_mmap(oldmm, mm); | 422 | uprobe_dup_mmap(oldmm, mm); |
419 | /* | 423 | /* |
@@ -525,6 +529,7 @@ out: | |||
525 | up_write(&mm->mmap_sem); | 529 | up_write(&mm->mmap_sem); |
526 | flush_tlb_mm(oldmm); | 530 | flush_tlb_mm(oldmm); |
527 | up_write(&oldmm->mmap_sem); | 531 | up_write(&oldmm->mmap_sem); |
532 | fail_uprobe_end: | ||
528 | uprobe_end_dup_mmap(); | 533 | uprobe_end_dup_mmap(); |
529 | return retval; | 534 | return retval; |
530 | fail_nomem_anon_vma_fork: | 535 | fail_nomem_anon_vma_fork: |
@@ -1276,7 +1281,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1276 | int __user *child_tidptr, | 1281 | int __user *child_tidptr, |
1277 | struct pid *pid, | 1282 | struct pid *pid, |
1278 | int trace, | 1283 | int trace, |
1279 | unsigned long tls) | 1284 | unsigned long tls, |
1285 | int node) | ||
1280 | { | 1286 | { |
1281 | int retval; | 1287 | int retval; |
1282 | struct task_struct *p; | 1288 | struct task_struct *p; |
@@ -1328,7 +1334,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1328 | goto fork_out; | 1334 | goto fork_out; |
1329 | 1335 | ||
1330 | retval = -ENOMEM; | 1336 | retval = -ENOMEM; |
1331 | p = dup_task_struct(current); | 1337 | p = dup_task_struct(current, node); |
1332 | if (!p) | 1338 | if (!p) |
1333 | goto fork_out; | 1339 | goto fork_out; |
1334 | 1340 | ||
@@ -1706,7 +1712,8 @@ static inline void init_idle_pids(struct pid_link *links) | |||
1706 | struct task_struct *fork_idle(int cpu) | 1712 | struct task_struct *fork_idle(int cpu) |
1707 | { | 1713 | { |
1708 | struct task_struct *task; | 1714 | struct task_struct *task; |
1709 | task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0); | 1715 | task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0, |
1716 | cpu_to_node(cpu)); | ||
1710 | if (!IS_ERR(task)) { | 1717 | if (!IS_ERR(task)) { |
1711 | init_idle_pids(task->pids); | 1718 | init_idle_pids(task->pids); |
1712 | init_idle(task, cpu); | 1719 | init_idle(task, cpu); |
@@ -1751,7 +1758,7 @@ long _do_fork(unsigned long clone_flags, | |||
1751 | } | 1758 | } |
1752 | 1759 | ||
1753 | p = copy_process(clone_flags, stack_start, stack_size, | 1760 | p = copy_process(clone_flags, stack_start, stack_size, |
1754 | child_tidptr, NULL, trace, tls); | 1761 | child_tidptr, NULL, trace, tls, NUMA_NO_NODE); |
1755 | /* | 1762 | /* |
1756 | * Do this prior waking up the new thread - the thread pointer | 1763 | * Do this prior waking up the new thread - the thread pointer |
1757 | * might get invalid after that point, if the thread exits quickly. | 1764 | * might get invalid after that point, if the thread exits quickly. |
diff --git a/kernel/kexec.c b/kernel/kexec.c index ee70aef5cd81..4384672d3245 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -103,6 +103,65 @@ out_free_image: | |||
103 | return ret; | 103 | return ret; |
104 | } | 104 | } |
105 | 105 | ||
106 | static int do_kexec_load(unsigned long entry, unsigned long nr_segments, | ||
107 | struct kexec_segment __user *segments, unsigned long flags) | ||
108 | { | ||
109 | struct kimage **dest_image, *image; | ||
110 | unsigned long i; | ||
111 | int ret; | ||
112 | |||
113 | if (flags & KEXEC_ON_CRASH) { | ||
114 | dest_image = &kexec_crash_image; | ||
115 | if (kexec_crash_image) | ||
116 | arch_kexec_unprotect_crashkres(); | ||
117 | } else { | ||
118 | dest_image = &kexec_image; | ||
119 | } | ||
120 | |||
121 | if (nr_segments == 0) { | ||
122 | /* Uninstall image */ | ||
123 | kimage_free(xchg(dest_image, NULL)); | ||
124 | return 0; | ||
125 | } | ||
126 | if (flags & KEXEC_ON_CRASH) { | ||
127 | /* | ||
128 | * Loading another kernel to switch to if this one | ||
129 | * crashes. Free any current crash dump kernel before | ||
130 | * we corrupt it. | ||
131 | */ | ||
132 | kimage_free(xchg(&kexec_crash_image, NULL)); | ||
133 | } | ||
134 | |||
135 | ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags); | ||
136 | if (ret) | ||
137 | return ret; | ||
138 | |||
139 | if (flags & KEXEC_PRESERVE_CONTEXT) | ||
140 | image->preserve_context = 1; | ||
141 | |||
142 | ret = machine_kexec_prepare(image); | ||
143 | if (ret) | ||
144 | goto out; | ||
145 | |||
146 | for (i = 0; i < nr_segments; i++) { | ||
147 | ret = kimage_load_segment(image, &image->segment[i]); | ||
148 | if (ret) | ||
149 | goto out; | ||
150 | } | ||
151 | |||
152 | kimage_terminate(image); | ||
153 | |||
154 | /* Install the new kernel and uninstall the old */ | ||
155 | image = xchg(dest_image, image); | ||
156 | |||
157 | out: | ||
158 | if ((flags & KEXEC_ON_CRASH) && kexec_crash_image) | ||
159 | arch_kexec_protect_crashkres(); | ||
160 | |||
161 | kimage_free(image); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
106 | /* | 165 | /* |
107 | * Exec Kernel system call: for obvious reasons only root may call it. | 166 | * Exec Kernel system call: for obvious reasons only root may call it. |
108 | * | 167 | * |
@@ -127,7 +186,6 @@ out_free_image: | |||
127 | SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | 186 | SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, |
128 | struct kexec_segment __user *, segments, unsigned long, flags) | 187 | struct kexec_segment __user *, segments, unsigned long, flags) |
129 | { | 188 | { |
130 | struct kimage **dest_image, *image; | ||
131 | int result; | 189 | int result; |
132 | 190 | ||
133 | /* We only trust the superuser with rebooting the system. */ | 191 | /* We only trust the superuser with rebooting the system. */ |
@@ -152,9 +210,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | |||
152 | if (nr_segments > KEXEC_SEGMENT_MAX) | 210 | if (nr_segments > KEXEC_SEGMENT_MAX) |
153 | return -EINVAL; | 211 | return -EINVAL; |
154 | 212 | ||
155 | image = NULL; | ||
156 | result = 0; | ||
157 | |||
158 | /* Because we write directly to the reserved memory | 213 | /* Because we write directly to the reserved memory |
159 | * region when loading crash kernels we need a mutex here to | 214 | * region when loading crash kernels we need a mutex here to |
160 | * prevent multiple crash kernels from attempting to load | 215 | * prevent multiple crash kernels from attempting to load |
@@ -166,53 +221,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | |||
166 | if (!mutex_trylock(&kexec_mutex)) | 221 | if (!mutex_trylock(&kexec_mutex)) |
167 | return -EBUSY; | 222 | return -EBUSY; |
168 | 223 | ||
169 | dest_image = &kexec_image; | 224 | result = do_kexec_load(entry, nr_segments, segments, flags); |
170 | if (flags & KEXEC_ON_CRASH) | ||
171 | dest_image = &kexec_crash_image; | ||
172 | if (nr_segments > 0) { | ||
173 | unsigned long i; | ||
174 | |||
175 | if (flags & KEXEC_ON_CRASH) { | ||
176 | /* | ||
177 | * Loading another kernel to switch to if this one | ||
178 | * crashes. Free any current crash dump kernel before | ||
179 | * we corrupt it. | ||
180 | */ | ||
181 | |||
182 | kimage_free(xchg(&kexec_crash_image, NULL)); | ||
183 | result = kimage_alloc_init(&image, entry, nr_segments, | ||
184 | segments, flags); | ||
185 | crash_map_reserved_pages(); | ||
186 | } else { | ||
187 | /* Loading another kernel to reboot into. */ | ||
188 | |||
189 | result = kimage_alloc_init(&image, entry, nr_segments, | ||
190 | segments, flags); | ||
191 | } | ||
192 | if (result) | ||
193 | goto out; | ||
194 | |||
195 | if (flags & KEXEC_PRESERVE_CONTEXT) | ||
196 | image->preserve_context = 1; | ||
197 | result = machine_kexec_prepare(image); | ||
198 | if (result) | ||
199 | goto out; | ||
200 | |||
201 | for (i = 0; i < nr_segments; i++) { | ||
202 | result = kimage_load_segment(image, &image->segment[i]); | ||
203 | if (result) | ||
204 | goto out; | ||
205 | } | ||
206 | kimage_terminate(image); | ||
207 | if (flags & KEXEC_ON_CRASH) | ||
208 | crash_unmap_reserved_pages(); | ||
209 | } | ||
210 | /* Install the new kernel, and Uninstall the old */ | ||
211 | image = xchg(dest_image, image); | ||
212 | 225 | ||
213 | out: | ||
214 | mutex_unlock(&kexec_mutex); | 226 | mutex_unlock(&kexec_mutex); |
215 | kimage_free(image); | ||
216 | 227 | ||
217 | return result; | 228 | return result; |
218 | } | 229 | } |
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index d5d408252992..56b3ed0927b0 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c | |||
@@ -954,7 +954,6 @@ int crash_shrink_memory(unsigned long new_size) | |||
954 | start = roundup(start, KEXEC_CRASH_MEM_ALIGN); | 954 | start = roundup(start, KEXEC_CRASH_MEM_ALIGN); |
955 | end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); | 955 | end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); |
956 | 956 | ||
957 | crash_map_reserved_pages(); | ||
958 | crash_free_reserved_phys_range(end, crashk_res.end); | 957 | crash_free_reserved_phys_range(end, crashk_res.end); |
959 | 958 | ||
960 | if ((start == end) && (crashk_res.parent != NULL)) | 959 | if ((start == end) && (crashk_res.parent != NULL)) |
@@ -968,7 +967,6 @@ int crash_shrink_memory(unsigned long new_size) | |||
968 | crashk_res.end = end - 1; | 967 | crashk_res.end = end - 1; |
969 | 968 | ||
970 | insert_resource(&iomem_resource, ram_res); | 969 | insert_resource(&iomem_resource, ram_res); |
971 | crash_unmap_reserved_pages(); | ||
972 | 970 | ||
973 | unlock: | 971 | unlock: |
974 | mutex_unlock(&kexec_mutex); | 972 | mutex_unlock(&kexec_mutex); |
@@ -1553,13 +1551,14 @@ int kernel_kexec(void) | |||
1553 | } | 1551 | } |
1554 | 1552 | ||
1555 | /* | 1553 | /* |
1556 | * Add and remove page tables for crashkernel memory | 1554 | * Protection mechanism for crashkernel reserved memory after |
1555 | * the kdump kernel is loaded. | ||
1557 | * | 1556 | * |
1558 | * Provide an empty default implementation here -- architecture | 1557 | * Provide an empty default implementation here -- architecture |
1559 | * code may override this | 1558 | * code may override this |
1560 | */ | 1559 | */ |
1561 | void __weak crash_map_reserved_pages(void) | 1560 | void __weak arch_kexec_protect_crashkres(void) |
1562 | {} | 1561 | {} |
1563 | 1562 | ||
1564 | void __weak crash_unmap_reserved_pages(void) | 1563 | void __weak arch_kexec_unprotect_crashkres(void) |
1565 | {} | 1564 | {} |
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index c72d2ff5896e..503bc2d348e5 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -274,8 +274,11 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, | |||
274 | return -EBUSY; | 274 | return -EBUSY; |
275 | 275 | ||
276 | dest_image = &kexec_image; | 276 | dest_image = &kexec_image; |
277 | if (flags & KEXEC_FILE_ON_CRASH) | 277 | if (flags & KEXEC_FILE_ON_CRASH) { |
278 | dest_image = &kexec_crash_image; | 278 | dest_image = &kexec_crash_image; |
279 | if (kexec_crash_image) | ||
280 | arch_kexec_unprotect_crashkres(); | ||
281 | } | ||
279 | 282 | ||
280 | if (flags & KEXEC_FILE_UNLOAD) | 283 | if (flags & KEXEC_FILE_UNLOAD) |
281 | goto exchange; | 284 | goto exchange; |
@@ -324,6 +327,9 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, | |||
324 | exchange: | 327 | exchange: |
325 | image = xchg(dest_image, image); | 328 | image = xchg(dest_image, image); |
326 | out: | 329 | out: |
330 | if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image) | ||
331 | arch_kexec_protect_crashkres(); | ||
332 | |||
327 | mutex_unlock(&kexec_mutex); | 333 | mutex_unlock(&kexec_mutex); |
328 | kimage_free(image); | 334 | kimage_free(image); |
329 | return ret; | 335 | return ret; |
diff --git a/kernel/signal.c b/kernel/signal.c index ab122a2cee41..96e9bc40667f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -224,7 +224,7 @@ static inline void print_dropped_signal(int sig) | |||
224 | if (!__ratelimit(&ratelimit_state)) | 224 | if (!__ratelimit(&ratelimit_state)) |
225 | return; | 225 | return; |
226 | 226 | ||
227 | printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n", | 227 | pr_info("%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n", |
228 | current->comm, current->pid, sig); | 228 | current->comm, current->pid, sig); |
229 | } | 229 | } |
230 | 230 | ||
@@ -1089,10 +1089,10 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1089 | static void print_fatal_signal(int signr) | 1089 | static void print_fatal_signal(int signr) |
1090 | { | 1090 | { |
1091 | struct pt_regs *regs = signal_pt_regs(); | 1091 | struct pt_regs *regs = signal_pt_regs(); |
1092 | printk(KERN_INFO "potentially unexpected fatal signal %d.\n", signr); | 1092 | pr_info("potentially unexpected fatal signal %d.\n", signr); |
1093 | 1093 | ||
1094 | #if defined(__i386__) && !defined(__arch_um__) | 1094 | #if defined(__i386__) && !defined(__arch_um__) |
1095 | printk(KERN_INFO "code at %08lx: ", regs->ip); | 1095 | pr_info("code at %08lx: ", regs->ip); |
1096 | { | 1096 | { |
1097 | int i; | 1097 | int i; |
1098 | for (i = 0; i < 16; i++) { | 1098 | for (i = 0; i < 16; i++) { |
@@ -1100,10 +1100,10 @@ static void print_fatal_signal(int signr) | |||
1100 | 1100 | ||
1101 | if (get_user(insn, (unsigned char *)(regs->ip + i))) | 1101 | if (get_user(insn, (unsigned char *)(regs->ip + i))) |
1102 | break; | 1102 | break; |
1103 | printk(KERN_CONT "%02x ", insn); | 1103 | pr_cont("%02x ", insn); |
1104 | } | 1104 | } |
1105 | } | 1105 | } |
1106 | printk(KERN_CONT "\n"); | 1106 | pr_cont("\n"); |
1107 | #endif | 1107 | #endif |
1108 | preempt_disable(); | 1108 | preempt_disable(); |
1109 | show_regs(regs); | 1109 | show_regs(regs); |
diff --git a/kernel/sys.c b/kernel/sys.c index cf8ba545c7d3..89d5be418157 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -2246,7 +2246,8 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
2246 | case PR_SET_THP_DISABLE: | 2246 | case PR_SET_THP_DISABLE: |
2247 | if (arg3 || arg4 || arg5) | 2247 | if (arg3 || arg4 || arg5) |
2248 | return -EINVAL; | 2248 | return -EINVAL; |
2249 | down_write(&me->mm->mmap_sem); | 2249 | if (down_write_killable(&me->mm->mmap_sem)) |
2250 | return -EINTR; | ||
2250 | if (arg2) | 2251 | if (arg2) |
2251 | me->mm->def_flags |= VM_NOHUGEPAGE; | 2252 | me->mm->def_flags |= VM_NOHUGEPAGE; |
2252 | else | 2253 | else |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index c635a107a7de..533f912638ed 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -22,7 +22,7 @@ config KGDB_SERIAL_CONSOLE | |||
22 | tristate "KGDB: use kgdb over the serial console" | 22 | tristate "KGDB: use kgdb over the serial console" |
23 | select CONSOLE_POLL | 23 | select CONSOLE_POLL |
24 | select MAGIC_SYSRQ | 24 | select MAGIC_SYSRQ |
25 | depends on TTY | 25 | depends on TTY && HW_CONSOLE |
26 | default y | 26 | default y |
27 | help | 27 | help |
28 | Share a serial console with kgdb. Sysrq-g must be used | 28 | Share a serial console with kgdb. Sysrq-g must be used |
diff --git a/mm/internal.h b/mm/internal.h index f6f3353b0868..a37e5b6f9d25 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -442,7 +442,7 @@ extern u64 hwpoison_filter_flags_value; | |||
442 | extern u64 hwpoison_filter_memcg; | 442 | extern u64 hwpoison_filter_memcg; |
443 | extern u32 hwpoison_filter_enable; | 443 | extern u32 hwpoison_filter_enable; |
444 | 444 | ||
445 | extern unsigned long vm_mmap_pgoff(struct file *, unsigned long, | 445 | extern unsigned long __must_check vm_mmap_pgoff(struct file *, unsigned long, |
446 | unsigned long, unsigned long, | 446 | unsigned long, unsigned long, |
447 | unsigned long, unsigned long); | 447 | unsigned long, unsigned long); |
448 | 448 | ||
diff --git a/mm/madvise.c b/mm/madvise.c index 07427d3fcead..93fb63e88b5e 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -707,10 +707,12 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) | |||
707 | return error; | 707 | return error; |
708 | 708 | ||
709 | write = madvise_need_mmap_write(behavior); | 709 | write = madvise_need_mmap_write(behavior); |
710 | if (write) | 710 | if (write) { |
711 | down_write(¤t->mm->mmap_sem); | 711 | if (down_write_killable(¤t->mm->mmap_sem)) |
712 | else | 712 | return -EINTR; |
713 | } else { | ||
713 | down_read(¤t->mm->mmap_sem); | 714 | down_read(¤t->mm->mmap_sem); |
715 | } | ||
714 | 716 | ||
715 | /* | 717 | /* |
716 | * If the interval [start,end) covers some unmapped address | 718 | * If the interval [start,end) covers some unmapped address |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index b3f16ab4b431..cf428d7b9a03 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1604,7 +1604,7 @@ static void memcg_oom_recover(struct mem_cgroup *memcg) | |||
1604 | 1604 | ||
1605 | static void mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int order) | 1605 | static void mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int order) |
1606 | { | 1606 | { |
1607 | if (!current->memcg_may_oom) | 1607 | if (!current->memcg_may_oom || current->memcg_in_oom) |
1608 | return; | 1608 | return; |
1609 | /* | 1609 | /* |
1610 | * We are in the middle of the charge context here, so we | 1610 | * We are in the middle of the charge context here, so we |
diff --git a/mm/mlock.c b/mm/mlock.c index 96f001041928..ef8dc9f395c4 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -617,7 +617,7 @@ static int apply_vma_lock_flags(unsigned long start, size_t len, | |||
617 | return error; | 617 | return error; |
618 | } | 618 | } |
619 | 619 | ||
620 | static int do_mlock(unsigned long start, size_t len, vm_flags_t flags) | 620 | static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t flags) |
621 | { | 621 | { |
622 | unsigned long locked; | 622 | unsigned long locked; |
623 | unsigned long lock_limit; | 623 | unsigned long lock_limit; |
@@ -635,7 +635,8 @@ static int do_mlock(unsigned long start, size_t len, vm_flags_t flags) | |||
635 | lock_limit >>= PAGE_SHIFT; | 635 | lock_limit >>= PAGE_SHIFT; |
636 | locked = len >> PAGE_SHIFT; | 636 | locked = len >> PAGE_SHIFT; |
637 | 637 | ||
638 | down_write(¤t->mm->mmap_sem); | 638 | if (down_write_killable(¤t->mm->mmap_sem)) |
639 | return -EINTR; | ||
639 | 640 | ||
640 | locked += current->mm->locked_vm; | 641 | locked += current->mm->locked_vm; |
641 | 642 | ||
@@ -678,7 +679,8 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len) | |||
678 | len = PAGE_ALIGN(len + (offset_in_page(start))); | 679 | len = PAGE_ALIGN(len + (offset_in_page(start))); |
679 | start &= PAGE_MASK; | 680 | start &= PAGE_MASK; |
680 | 681 | ||
681 | down_write(¤t->mm->mmap_sem); | 682 | if (down_write_killable(¤t->mm->mmap_sem)) |
683 | return -EINTR; | ||
682 | ret = apply_vma_lock_flags(start, len, 0); | 684 | ret = apply_vma_lock_flags(start, len, 0); |
683 | up_write(¤t->mm->mmap_sem); | 685 | up_write(¤t->mm->mmap_sem); |
684 | 686 | ||
@@ -748,9 +750,10 @@ SYSCALL_DEFINE1(mlockall, int, flags) | |||
748 | lock_limit = rlimit(RLIMIT_MEMLOCK); | 750 | lock_limit = rlimit(RLIMIT_MEMLOCK); |
749 | lock_limit >>= PAGE_SHIFT; | 751 | lock_limit >>= PAGE_SHIFT; |
750 | 752 | ||
751 | ret = -ENOMEM; | 753 | if (down_write_killable(¤t->mm->mmap_sem)) |
752 | down_write(¤t->mm->mmap_sem); | 754 | return -EINTR; |
753 | 755 | ||
756 | ret = -ENOMEM; | ||
754 | if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || | 757 | if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || |
755 | capable(CAP_IPC_LOCK)) | 758 | capable(CAP_IPC_LOCK)) |
756 | ret = apply_mlockall_flags(flags); | 759 | ret = apply_mlockall_flags(flags); |
@@ -765,7 +768,8 @@ SYSCALL_DEFINE0(munlockall) | |||
765 | { | 768 | { |
766 | int ret; | 769 | int ret; |
767 | 770 | ||
768 | down_write(¤t->mm->mmap_sem); | 771 | if (down_write_killable(¤t->mm->mmap_sem)) |
772 | return -EINTR; | ||
769 | ret = apply_mlockall_flags(0); | 773 | ret = apply_mlockall_flags(0); |
770 | up_write(¤t->mm->mmap_sem); | 774 | up_write(¤t->mm->mmap_sem); |
771 | return ret; | 775 | return ret; |
@@ -178,7 +178,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) | |||
178 | unsigned long min_brk; | 178 | unsigned long min_brk; |
179 | bool populate; | 179 | bool populate; |
180 | 180 | ||
181 | down_write(&mm->mmap_sem); | 181 | if (down_write_killable(&mm->mmap_sem)) |
182 | return -EINTR; | ||
182 | 183 | ||
183 | #ifdef CONFIG_COMPAT_BRK | 184 | #ifdef CONFIG_COMPAT_BRK |
184 | /* | 185 | /* |
@@ -2493,7 +2494,9 @@ int vm_munmap(unsigned long start, size_t len) | |||
2493 | int ret; | 2494 | int ret; |
2494 | struct mm_struct *mm = current->mm; | 2495 | struct mm_struct *mm = current->mm; |
2495 | 2496 | ||
2496 | down_write(&mm->mmap_sem); | 2497 | if (down_write_killable(&mm->mmap_sem)) |
2498 | return -EINTR; | ||
2499 | |||
2497 | ret = do_munmap(mm, start, len); | 2500 | ret = do_munmap(mm, start, len); |
2498 | up_write(&mm->mmap_sem); | 2501 | up_write(&mm->mmap_sem); |
2499 | return ret; | 2502 | return ret; |
@@ -2502,8 +2505,15 @@ EXPORT_SYMBOL(vm_munmap); | |||
2502 | 2505 | ||
2503 | SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) | 2506 | SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) |
2504 | { | 2507 | { |
2508 | int ret; | ||
2509 | struct mm_struct *mm = current->mm; | ||
2510 | |||
2505 | profile_munmap(addr); | 2511 | profile_munmap(addr); |
2506 | return vm_munmap(addr, len); | 2512 | if (down_write_killable(&mm->mmap_sem)) |
2513 | return -EINTR; | ||
2514 | ret = do_munmap(mm, addr, len); | ||
2515 | up_write(&mm->mmap_sem); | ||
2516 | return ret; | ||
2507 | } | 2517 | } |
2508 | 2518 | ||
2509 | 2519 | ||
@@ -2535,7 +2545,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
2535 | if (pgoff + (size >> PAGE_SHIFT) < pgoff) | 2545 | if (pgoff + (size >> PAGE_SHIFT) < pgoff) |
2536 | return ret; | 2546 | return ret; |
2537 | 2547 | ||
2538 | down_write(&mm->mmap_sem); | 2548 | if (down_write_killable(&mm->mmap_sem)) |
2549 | return -EINTR; | ||
2550 | |||
2539 | vma = find_vma(mm, start); | 2551 | vma = find_vma(mm, start); |
2540 | 2552 | ||
2541 | if (!vma || !(vma->vm_flags & VM_SHARED)) | 2553 | if (!vma || !(vma->vm_flags & VM_SHARED)) |
@@ -2700,7 +2712,9 @@ unsigned long vm_brk(unsigned long addr, unsigned long len) | |||
2700 | unsigned long ret; | 2712 | unsigned long ret; |
2701 | bool populate; | 2713 | bool populate; |
2702 | 2714 | ||
2703 | down_write(&mm->mmap_sem); | 2715 | if (down_write_killable(&mm->mmap_sem)) |
2716 | return -EINTR; | ||
2717 | |||
2704 | ret = do_brk(addr, len); | 2718 | ret = do_brk(addr, len); |
2705 | populate = ((mm->def_flags & VM_LOCKED) != 0); | 2719 | populate = ((mm->def_flags & VM_LOCKED) != 0); |
2706 | up_write(&mm->mmap_sem); | 2720 | up_write(&mm->mmap_sem); |
diff --git a/mm/mprotect.c b/mm/mprotect.c index b650c5412f58..5019a1ef2848 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -379,7 +379,8 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, | |||
379 | 379 | ||
380 | reqprot = prot; | 380 | reqprot = prot; |
381 | 381 | ||
382 | down_write(¤t->mm->mmap_sem); | 382 | if (down_write_killable(¤t->mm->mmap_sem)) |
383 | return -EINTR; | ||
383 | 384 | ||
384 | vma = find_vma(current->mm, start); | 385 | vma = find_vma(current->mm, start); |
385 | error = -ENOMEM; | 386 | error = -ENOMEM; |
diff --git a/mm/mremap.c b/mm/mremap.c index 9dc499977924..1f157adfdaf9 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -503,7 +503,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, | |||
503 | if (!new_len) | 503 | if (!new_len) |
504 | return ret; | 504 | return ret; |
505 | 505 | ||
506 | down_write(¤t->mm->mmap_sem); | 506 | if (down_write_killable(¤t->mm->mmap_sem)) |
507 | return -EINTR; | ||
507 | 508 | ||
508 | if (flags & MREMAP_FIXED) { | 509 | if (flags & MREMAP_FIXED) { |
509 | ret = mremap_to(addr, old_len, new_addr, new_len, | 510 | ret = mremap_to(addr, old_len, new_addr, new_len, |
@@ -297,7 +297,8 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr, | |||
297 | 297 | ||
298 | ret = security_mmap_file(file, prot, flag); | 298 | ret = security_mmap_file(file, prot, flag); |
299 | if (!ret) { | 299 | if (!ret) { |
300 | down_write(&mm->mmap_sem); | 300 | if (down_write_killable(&mm->mmap_sem)) |
301 | return -EINTR; | ||
301 | ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff, | 302 | ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff, |
302 | &populate); | 303 | &populate); |
303 | up_write(&mm->mmap_sem); | 304 | up_write(&mm->mmap_sem); |
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile index 6cf1ecf61057..cd129e65d1ff 100644 --- a/scripts/gdb/linux/Makefile +++ b/scripts/gdb/linux/Makefile | |||
@@ -8,4 +8,14 @@ ifneq ($(KBUILD_SRC),) | |||
8 | endif | 8 | endif |
9 | @: | 9 | @: |
10 | 10 | ||
11 | clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) | 11 | quiet_cmd_gen_constants_py = GEN $@ |
12 | cmd_gen_constants_py = \ | ||
13 | $(CPP) -E -x c -P $(c_flags) $< > $@ ;\ | ||
14 | sed -i '1,/<!-- end-c-headers -->/d;' $@ | ||
15 | |||
16 | $(obj)/constants.py: $(SRCTREE)/$(obj)/constants.py.in | ||
17 | $(call if_changed,gen_constants_py) | ||
18 | |||
19 | build_constants_py: $(obj)/constants.py | ||
20 | |||
21 | clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) $(obj)/constants.py | ||
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in new file mode 100644 index 000000000000..07e6c2befe36 --- /dev/null +++ b/scripts/gdb/linux/constants.py.in | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * gdb helper commands and functions for Linux kernel debugging | ||
3 | * | ||
4 | * Kernel constants derived from include files. | ||
5 | * | ||
6 | * Copyright (c) 2016 Linaro Ltd | ||
7 | * | ||
8 | * Authors: | ||
9 | * Kieran Bingham <kieran.bingham@linaro.org> | ||
10 | * | ||
11 | * This work is licensed under the terms of the GNU GPL version 2. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/fs.h> | ||
16 | #include <linux/mount.h> | ||
17 | #include <linux/radix-tree.h> | ||
18 | |||
19 | /* We need to stringify expanded macros so that they can be parsed */ | ||
20 | |||
21 | #define STRING(x) #x | ||
22 | #define XSTRING(x) STRING(x) | ||
23 | |||
24 | #define LX_VALUE(x) LX_##x = x | ||
25 | #define LX_GDBPARSED(x) LX_##x = gdb.parse_and_eval(XSTRING(x)) | ||
26 | |||
27 | /* | ||
28 | * IS_ENABLED generates (a || b) which is not compatible with python | ||
29 | * We can only switch on configuration items we know are available | ||
30 | * Therefore - IS_BUILTIN() is more appropriate | ||
31 | */ | ||
32 | #define LX_CONFIG(x) LX_##x = IS_BUILTIN(x) | ||
33 | |||
34 | /* The build system will take care of deleting everything above this marker */ | ||
35 | <!-- end-c-headers --> | ||
36 | |||
37 | import gdb | ||
38 | |||
39 | /* linux/fs.h */ | ||
40 | LX_VALUE(MS_RDONLY) | ||
41 | LX_VALUE(MS_SYNCHRONOUS) | ||
42 | LX_VALUE(MS_MANDLOCK) | ||
43 | LX_VALUE(MS_DIRSYNC) | ||
44 | LX_VALUE(MS_NOATIME) | ||
45 | LX_VALUE(MS_NODIRATIME) | ||
46 | |||
47 | /* linux/mount.h */ | ||
48 | LX_VALUE(MNT_NOSUID) | ||
49 | LX_VALUE(MNT_NODEV) | ||
50 | LX_VALUE(MNT_NOEXEC) | ||
51 | LX_VALUE(MNT_NOATIME) | ||
52 | LX_VALUE(MNT_NODIRATIME) | ||
53 | LX_VALUE(MNT_RELATIME) | ||
54 | |||
55 | /* linux/radix-tree.h */ | ||
56 | LX_VALUE(RADIX_TREE_INDIRECT_PTR) | ||
57 | LX_GDBPARSED(RADIX_TREE_HEIGHT_MASK) | ||
58 | LX_GDBPARSED(RADIX_TREE_MAP_SHIFT) | ||
59 | LX_GDBPARSED(RADIX_TREE_MAP_MASK) | ||
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index 4297b83fedef..ca11e8df31b6 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py | |||
@@ -97,9 +97,47 @@ def cpu_list(mask_name): | |||
97 | bits >>= 1 | 97 | bits >>= 1 |
98 | bit += 1 | 98 | bit += 1 |
99 | 99 | ||
100 | yield int(cpu) | ||
101 | |||
102 | |||
103 | def each_online_cpu(): | ||
104 | for cpu in cpu_list("__cpu_online_mask"): | ||
105 | yield cpu | ||
106 | |||
107 | |||
108 | def each_present_cpu(): | ||
109 | for cpu in cpu_list("__cpu_present_mask"): | ||
110 | yield cpu | ||
111 | |||
112 | |||
113 | def each_possible_cpu(): | ||
114 | for cpu in cpu_list("__cpu_possible_mask"): | ||
115 | yield cpu | ||
116 | |||
117 | |||
118 | def each_active_cpu(): | ||
119 | for cpu in cpu_list("__cpu_active_mask"): | ||
100 | yield cpu | 120 | yield cpu |
101 | 121 | ||
102 | 122 | ||
123 | class LxCpus(gdb.Command): | ||
124 | """List CPU status arrays | ||
125 | |||
126 | Displays the known state of each CPU based on the kernel masks | ||
127 | and can help identify the state of hotplugged CPUs""" | ||
128 | |||
129 | def __init__(self): | ||
130 | super(LxCpus, self).__init__("lx-cpus", gdb.COMMAND_DATA) | ||
131 | |||
132 | def invoke(self, arg, from_tty): | ||
133 | gdb.write("Possible CPUs : {}\n".format(list(each_possible_cpu()))) | ||
134 | gdb.write("Present CPUs : {}\n".format(list(each_present_cpu()))) | ||
135 | gdb.write("Online CPUs : {}\n".format(list(each_online_cpu()))) | ||
136 | gdb.write("Active CPUs : {}\n".format(list(each_active_cpu()))) | ||
137 | |||
138 | LxCpus() | ||
139 | |||
140 | |||
103 | class PerCpu(gdb.Function): | 141 | class PerCpu(gdb.Function): |
104 | """Return per-cpu variable. | 142 | """Return per-cpu variable. |
105 | 143 | ||
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 927d0d2a3145..f9b92ece7834 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py | |||
@@ -33,11 +33,12 @@ class LxDmesg(gdb.Command): | |||
33 | if log_first_idx < log_next_idx: | 33 | if log_first_idx < log_next_idx: |
34 | log_buf_2nd_half = -1 | 34 | log_buf_2nd_half = -1 |
35 | length = log_next_idx - log_first_idx | 35 | length = log_next_idx - log_first_idx |
36 | log_buf = inf.read_memory(start, length) | 36 | log_buf = utils.read_memoryview(inf, start, length).tobytes() |
37 | else: | 37 | else: |
38 | log_buf_2nd_half = log_buf_len - log_first_idx | 38 | log_buf_2nd_half = log_buf_len - log_first_idx |
39 | log_buf = inf.read_memory(start, log_buf_2nd_half) + \ | 39 | a = utils.read_memoryview(inf, start, log_buf_2nd_half) |
40 | inf.read_memory(log_buf_addr, log_next_idx) | 40 | b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) |
41 | log_buf = a.tobytes() + b.tobytes() | ||
41 | 42 | ||
42 | pos = 0 | 43 | pos = 0 |
43 | while pos < log_buf.__len__(): | 44 | while pos < log_buf.__len__(): |
@@ -50,10 +51,10 @@ class LxDmesg(gdb.Command): | |||
50 | continue | 51 | continue |
51 | 52 | ||
52 | text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) | 53 | text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) |
53 | text = log_buf[pos + 16:pos + 16 + text_len] | 54 | text = log_buf[pos + 16:pos + 16 + text_len].decode() |
54 | time_stamp = utils.read_u64(log_buf[pos:pos + 8]) | 55 | time_stamp = utils.read_u64(log_buf[pos:pos + 8]) |
55 | 56 | ||
56 | for line in memoryview(text).tobytes().splitlines(): | 57 | for line in text.splitlines(): |
57 | gdb.write("[{time:12.6f}] {line}\n".format( | 58 | gdb.write("[{time:12.6f}] {line}\n".format( |
58 | time=time_stamp / 1000000000.0, | 59 | time=time_stamp / 1000000000.0, |
59 | line=line)) | 60 | line=line)) |
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py index 3a3775bc162b..2f335fbd86fd 100644 --- a/scripts/gdb/linux/lists.py +++ b/scripts/gdb/linux/lists.py | |||
@@ -18,6 +18,27 @@ from linux import utils | |||
18 | list_head = utils.CachedType("struct list_head") | 18 | list_head = utils.CachedType("struct list_head") |
19 | 19 | ||
20 | 20 | ||
21 | def list_for_each(head): | ||
22 | if head.type == list_head.get_type().pointer(): | ||
23 | head = head.dereference() | ||
24 | elif head.type != list_head.get_type(): | ||
25 | raise gdb.GdbError("Must be struct list_head not {}" | ||
26 | .format(head.type)) | ||
27 | |||
28 | node = head['next'].dereference() | ||
29 | while node.address != head.address: | ||
30 | yield node.address | ||
31 | node = node['next'].dereference() | ||
32 | |||
33 | |||
34 | def list_for_each_entry(head, gdbtype, member): | ||
35 | for node in list_for_each(head): | ||
36 | if node.type != list_head.get_type().pointer(): | ||
37 | raise TypeError("Type {} found. Expected struct list_head *." | ||
38 | .format(node.type)) | ||
39 | yield utils.container_of(node, gdbtype, member) | ||
40 | |||
41 | |||
21 | def list_check(head): | 42 | def list_check(head): |
22 | nb = 0 | 43 | nb = 0 |
23 | if (head.type == list_head.get_type().pointer()): | 44 | if (head.type == list_head.get_type().pointer()): |
diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 0a35d6dbfb80..441b23239896 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | import gdb | 14 | import gdb |
15 | 15 | ||
16 | from linux import cpus, utils | 16 | from linux import cpus, utils, lists |
17 | 17 | ||
18 | 18 | ||
19 | module_type = utils.CachedType("struct module") | 19 | module_type = utils.CachedType("struct module") |
@@ -21,14 +21,14 @@ module_type = utils.CachedType("struct module") | |||
21 | 21 | ||
22 | def module_list(): | 22 | def module_list(): |
23 | global module_type | 23 | global module_type |
24 | modules = utils.gdb_eval_or_none("modules") | ||
25 | if modules is None: | ||
26 | return | ||
27 | |||
24 | module_ptr_type = module_type.get_type().pointer() | 28 | module_ptr_type = module_type.get_type().pointer() |
25 | modules = gdb.parse_and_eval("modules") | ||
26 | entry = modules['next'] | ||
27 | end_of_list = modules.address | ||
28 | 29 | ||
29 | while entry != end_of_list: | 30 | for module in lists.list_for_each_entry(modules, module_ptr_type, "list"): |
30 | yield utils.container_of(entry, module_ptr_type, "list") | 31 | yield module |
31 | entry = entry['next'] | ||
32 | 32 | ||
33 | 33 | ||
34 | def find_module_by_name(name): | 34 | def find_module_by_name(name): |
@@ -78,19 +78,17 @@ class LxLsmod(gdb.Command): | |||
78 | address=str(layout['base']).split()[0], | 78 | address=str(layout['base']).split()[0], |
79 | name=module['name'].string(), | 79 | name=module['name'].string(), |
80 | size=str(layout['size']), | 80 | size=str(layout['size']), |
81 | ref=str(module['refcnt']['counter']))) | 81 | ref=str(module['refcnt']['counter'] - 1))) |
82 | 82 | ||
83 | source_list = module['source_list'] | ||
84 | t = self._module_use_type.get_type().pointer() | 83 | t = self._module_use_type.get_type().pointer() |
85 | entry = source_list['next'] | ||
86 | first = True | 84 | first = True |
87 | while entry != source_list.address: | 85 | sources = module['source_list'] |
88 | use = utils.container_of(entry, t, "source_list") | 86 | for use in lists.list_for_each_entry(sources, t, "source_list"): |
89 | gdb.write("{separator}{name}".format( | 87 | gdb.write("{separator}{name}".format( |
90 | separator=" " if first else ",", | 88 | separator=" " if first else ",", |
91 | name=use['source']['name'].string())) | 89 | name=use['source']['name'].string())) |
92 | first = False | 90 | first = False |
93 | entry = entry['next'] | 91 | |
94 | gdb.write("\n") | 92 | gdb.write("\n") |
95 | 93 | ||
96 | 94 | ||
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 6e6709c1830c..38b1f09d1cd9 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py | |||
@@ -12,6 +12,10 @@ | |||
12 | # | 12 | # |
13 | 13 | ||
14 | import gdb | 14 | import gdb |
15 | from linux import constants | ||
16 | from linux import utils | ||
17 | from linux import tasks | ||
18 | from linux import lists | ||
15 | 19 | ||
16 | 20 | ||
17 | class LxCmdLine(gdb.Command): | 21 | class LxCmdLine(gdb.Command): |
@@ -39,3 +43,155 @@ class LxVersion(gdb.Command): | |||
39 | gdb.write(gdb.parse_and_eval("linux_banner").string()) | 43 | gdb.write(gdb.parse_and_eval("linux_banner").string()) |
40 | 44 | ||
41 | LxVersion() | 45 | LxVersion() |
46 | |||
47 | |||
48 | # Resource Structure Printers | ||
49 | # /proc/iomem | ||
50 | # /proc/ioports | ||
51 | |||
52 | def get_resources(resource, depth): | ||
53 | while resource: | ||
54 | yield resource, depth | ||
55 | |||
56 | child = resource['child'] | ||
57 | if child: | ||
58 | for res, deep in get_resources(child, depth + 1): | ||
59 | yield res, deep | ||
60 | |||
61 | resource = resource['sibling'] | ||
62 | |||
63 | |||
64 | def show_lx_resources(resource_str): | ||
65 | resource = gdb.parse_and_eval(resource_str) | ||
66 | width = 4 if resource['end'] < 0x10000 else 8 | ||
67 | # Iterate straight to the first child | ||
68 | for res, depth in get_resources(resource['child'], 0): | ||
69 | start = int(res['start']) | ||
70 | end = int(res['end']) | ||
71 | gdb.write(" " * depth * 2 + | ||
72 | "{0:0{1}x}-".format(start, width) + | ||
73 | "{0:0{1}x} : ".format(end, width) + | ||
74 | res['name'].string() + "\n") | ||
75 | |||
76 | |||
77 | class LxIOMem(gdb.Command): | ||
78 | """Identify the IO memory resource locations defined by the kernel | ||
79 | |||
80 | Equivalent to cat /proc/iomem on a running target""" | ||
81 | |||
82 | def __init__(self): | ||
83 | super(LxIOMem, self).__init__("lx-iomem", gdb.COMMAND_DATA) | ||
84 | |||
85 | def invoke(self, arg, from_tty): | ||
86 | return show_lx_resources("iomem_resource") | ||
87 | |||
88 | LxIOMem() | ||
89 | |||
90 | |||
91 | class LxIOPorts(gdb.Command): | ||
92 | """Identify the IO port resource locations defined by the kernel | ||
93 | |||
94 | Equivalent to cat /proc/ioports on a running target""" | ||
95 | |||
96 | def __init__(self): | ||
97 | super(LxIOPorts, self).__init__("lx-ioports", gdb.COMMAND_DATA) | ||
98 | |||
99 | def invoke(self, arg, from_tty): | ||
100 | return show_lx_resources("ioport_resource") | ||
101 | |||
102 | LxIOPorts() | ||
103 | |||
104 | |||
105 | # Mount namespace viewer | ||
106 | # /proc/mounts | ||
107 | |||
108 | def info_opts(lst, opt): | ||
109 | opts = "" | ||
110 | for key, string in lst.items(): | ||
111 | if opt & key: | ||
112 | opts += string | ||
113 | return opts | ||
114 | |||
115 | |||
116 | FS_INFO = {constants.LX_MS_SYNCHRONOUS: ",sync", | ||
117 | constants.LX_MS_MANDLOCK: ",mand", | ||
118 | constants.LX_MS_DIRSYNC: ",dirsync", | ||
119 | constants.LX_MS_NOATIME: ",noatime", | ||
120 | constants.LX_MS_NODIRATIME: ",nodiratime"} | ||
121 | |||
122 | MNT_INFO = {constants.LX_MNT_NOSUID: ",nosuid", | ||
123 | constants.LX_MNT_NODEV: ",nodev", | ||
124 | constants.LX_MNT_NOEXEC: ",noexec", | ||
125 | constants.LX_MNT_NOATIME: ",noatime", | ||
126 | constants.LX_MNT_NODIRATIME: ",nodiratime", | ||
127 | constants.LX_MNT_RELATIME: ",relatime"} | ||
128 | |||
129 | mount_type = utils.CachedType("struct mount") | ||
130 | mount_ptr_type = mount_type.get_type().pointer() | ||
131 | |||
132 | |||
133 | class LxMounts(gdb.Command): | ||
134 | """Report the VFS mounts of the current process namespace. | ||
135 | |||
136 | Equivalent to cat /proc/mounts on a running target | ||
137 | An integer value can be supplied to display the mount | ||
138 | values of that process namespace""" | ||
139 | |||
140 | def __init__(self): | ||
141 | super(LxMounts, self).__init__("lx-mounts", gdb.COMMAND_DATA) | ||
142 | |||
143 | # Equivalent to proc_namespace.c:show_vfsmnt | ||
144 | # However, that has the ability to call into s_op functions | ||
145 | # whereas we cannot and must make do with the information we can obtain. | ||
146 | def invoke(self, arg, from_tty): | ||
147 | argv = gdb.string_to_argv(arg) | ||
148 | if len(argv) >= 1: | ||
149 | try: | ||
150 | pid = int(argv[0]) | ||
151 | except: | ||
152 | raise gdb.GdbError("Provide a PID as integer value") | ||
153 | else: | ||
154 | pid = 1 | ||
155 | |||
156 | task = tasks.get_task_by_pid(pid) | ||
157 | if not task: | ||
158 | raise gdb.GdbError("Couldn't find a process with PID {}" | ||
159 | .format(pid)) | ||
160 | |||
161 | namespace = task['nsproxy']['mnt_ns'] | ||
162 | if not namespace: | ||
163 | raise gdb.GdbError("No namespace for current process") | ||
164 | |||
165 | for vfs in lists.list_for_each_entry(namespace['list'], | ||
166 | mount_ptr_type, "mnt_list"): | ||
167 | devname = vfs['mnt_devname'].string() | ||
168 | devname = devname if devname else "none" | ||
169 | |||
170 | pathname = "" | ||
171 | parent = vfs | ||
172 | while True: | ||
173 | mntpoint = parent['mnt_mountpoint'] | ||
174 | pathname = utils.dentry_name(mntpoint) + pathname | ||
175 | if (parent == parent['mnt_parent']): | ||
176 | break | ||
177 | parent = parent['mnt_parent'] | ||
178 | |||
179 | if (pathname == ""): | ||
180 | pathname = "/" | ||
181 | |||
182 | superblock = vfs['mnt']['mnt_sb'] | ||
183 | fstype = superblock['s_type']['name'].string() | ||
184 | s_flags = int(superblock['s_flags']) | ||
185 | m_flags = int(vfs['mnt']['mnt_flags']) | ||
186 | rd = "ro" if (s_flags & constants.LX_MS_RDONLY) else "rw" | ||
187 | |||
188 | gdb.write( | ||
189 | "{} {} {} {}{}{} 0 0\n" | ||
190 | .format(devname, | ||
191 | pathname, | ||
192 | fstype, | ||
193 | rd, | ||
194 | info_opts(FS_INFO, s_flags), | ||
195 | info_opts(MNT_INFO, m_flags))) | ||
196 | |||
197 | LxMounts() | ||
diff --git a/scripts/gdb/linux/radixtree.py b/scripts/gdb/linux/radixtree.py new file mode 100644 index 000000000000..0fdef4e2971a --- /dev/null +++ b/scripts/gdb/linux/radixtree.py | |||
@@ -0,0 +1,97 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # Radix Tree Parser | ||
5 | # | ||
6 | # Copyright (c) 2016 Linaro Ltd | ||
7 | # | ||
8 | # Authors: | ||
9 | # Kieran Bingham <kieran.bingham@linaro.org> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | from linux import utils | ||
17 | from linux import constants | ||
18 | |||
19 | radix_tree_root_type = utils.CachedType("struct radix_tree_root") | ||
20 | radix_tree_node_type = utils.CachedType("struct radix_tree_node") | ||
21 | |||
22 | |||
23 | def is_indirect_ptr(node): | ||
24 | long_type = utils.get_long_type() | ||
25 | return (node.cast(long_type) & constants.LX_RADIX_TREE_INDIRECT_PTR) | ||
26 | |||
27 | |||
28 | def indirect_to_ptr(node): | ||
29 | long_type = utils.get_long_type() | ||
30 | node_type = node.type | ||
31 | indirect_ptr = node.cast(long_type) & ~constants.LX_RADIX_TREE_INDIRECT_PTR | ||
32 | return indirect_ptr.cast(node_type) | ||
33 | |||
34 | |||
35 | def maxindex(height): | ||
36 | height = height & constants.LX_RADIX_TREE_HEIGHT_MASK | ||
37 | return gdb.parse_and_eval("height_to_maxindex["+str(height)+"]") | ||
38 | |||
39 | |||
40 | def lookup(root, index): | ||
41 | if root.type == radix_tree_root_type.get_type().pointer(): | ||
42 | root = root.dereference() | ||
43 | elif root.type != radix_tree_root_type.get_type(): | ||
44 | raise gdb.GdbError("Must be struct radix_tree_root not {}" | ||
45 | .format(root.type)) | ||
46 | |||
47 | node = root['rnode'] | ||
48 | if node is 0: | ||
49 | return None | ||
50 | |||
51 | if not (is_indirect_ptr(node)): | ||
52 | if (index > 0): | ||
53 | return None | ||
54 | return node | ||
55 | |||
56 | node = indirect_to_ptr(node) | ||
57 | |||
58 | height = node['path'] & constants.LX_RADIX_TREE_HEIGHT_MASK | ||
59 | if (index > maxindex(height)): | ||
60 | return None | ||
61 | |||
62 | shift = (height-1) * constants.LX_RADIX_TREE_MAP_SHIFT | ||
63 | |||
64 | while True: | ||
65 | new_index = (index >> shift) & constants.LX_RADIX_TREE_MAP_MASK | ||
66 | slot = node['slots'][new_index] | ||
67 | |||
68 | node = slot.cast(node.type.pointer()).dereference() | ||
69 | if node is 0: | ||
70 | return None | ||
71 | |||
72 | shift -= constants.LX_RADIX_TREE_MAP_SHIFT | ||
73 | height -= 1 | ||
74 | |||
75 | if (height <= 0): | ||
76 | break | ||
77 | |||
78 | return node | ||
79 | |||
80 | |||
81 | class LxRadixTree(gdb.Function): | ||
82 | """ Lookup and return a node from a RadixTree. | ||
83 | |||
84 | $lx_radix_tree_lookup(root_node [, index]): Return the node at the given index. | ||
85 | If index is omitted, the root node is dereferenced and returned.""" | ||
86 | |||
87 | def __init__(self): | ||
88 | super(LxRadixTree, self).__init__("lx_radix_tree_lookup") | ||
89 | |||
90 | def invoke(self, root, index=0): | ||
91 | result = lookup(root, index) | ||
92 | if result is None: | ||
93 | raise gdb.GdbError("No entry in tree at index {}".format(index)) | ||
94 | |||
95 | return result | ||
96 | |||
97 | LxRadixTree() | ||
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 862a4ae24d49..1bf949c43b76 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py | |||
@@ -114,3 +114,22 @@ variable.""" | |||
114 | 114 | ||
115 | 115 | ||
116 | LxThreadInfoFunc() | 116 | LxThreadInfoFunc() |
117 | |||
118 | |||
119 | class LxThreadInfoByPidFunc (gdb.Function): | ||
120 | """Calculate Linux thread_info from task variable found by pid | ||
121 | |||
122 | $lx_thread_info_by_pid(PID): Given PID, return the corresponding thread_info | ||
123 | variable.""" | ||
124 | |||
125 | def __init__(self): | ||
126 | super(LxThreadInfoByPidFunc, self).__init__("lx_thread_info_by_pid") | ||
127 | |||
128 | def invoke(self, pid): | ||
129 | task = get_task_by_pid(pid) | ||
130 | if task: | ||
131 | return get_thread_info(task.dereference()) | ||
132 | else: | ||
133 | raise gdb.GdbError("No task of PID " + str(pid)) | ||
134 | |||
135 | LxThreadInfoByPidFunc() | ||
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 0893b326a28b..50805874cfc3 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py | |||
@@ -87,11 +87,24 @@ def get_target_endianness(): | |||
87 | return target_endianness | 87 | return target_endianness |
88 | 88 | ||
89 | 89 | ||
90 | def read_memoryview(inf, start, length): | ||
91 | return memoryview(inf.read_memory(start, length)) | ||
92 | |||
93 | |||
90 | def read_u16(buffer): | 94 | def read_u16(buffer): |
95 | value = [0, 0] | ||
96 | |||
97 | if type(buffer[0]) is str: | ||
98 | value[0] = ord(buffer[0]) | ||
99 | value[1] = ord(buffer[1]) | ||
100 | else: | ||
101 | value[0] = buffer[0] | ||
102 | value[1] = buffer[1] | ||
103 | |||
91 | if get_target_endianness() == LITTLE_ENDIAN: | 104 | if get_target_endianness() == LITTLE_ENDIAN: |
92 | return ord(buffer[0]) + (ord(buffer[1]) << 8) | 105 | return value[0] + (value[1] << 8) |
93 | else: | 106 | else: |
94 | return ord(buffer[1]) + (ord(buffer[0]) << 8) | 107 | return value[1] + (value[0] << 8) |
95 | 108 | ||
96 | 109 | ||
97 | def read_u32(buffer): | 110 | def read_u32(buffer): |
@@ -154,3 +167,18 @@ def get_gdbserver_type(): | |||
154 | if gdbserver_type is not None and hasattr(gdb, 'events'): | 167 | if gdbserver_type is not None and hasattr(gdb, 'events'): |
155 | gdb.events.exited.connect(exit_handler) | 168 | gdb.events.exited.connect(exit_handler) |
156 | return gdbserver_type | 169 | return gdbserver_type |
170 | |||
171 | |||
172 | def gdb_eval_or_none(expresssion): | ||
173 | try: | ||
174 | return gdb.parse_and_eval(expresssion) | ||
175 | except: | ||
176 | return None | ||
177 | |||
178 | |||
179 | def dentry_name(d): | ||
180 | parent = d['d_parent'] | ||
181 | if parent == d or parent == 0: | ||
182 | return "" | ||
183 | p = dentry_name(d['d_parent']) + "/" | ||
184 | return p + d['d_iname'].string() | ||
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index d5943eca19cd..3a80ad6eecad 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py | |||
@@ -30,3 +30,5 @@ else: | |||
30 | import linux.cpus | 30 | import linux.cpus |
31 | import linux.lists | 31 | import linux.lists |
32 | import linux.proc | 32 | import linux.proc |
33 | import linux.constants | ||
34 | import linux.radixtree | ||