diff options
-rw-r--r-- | arch/um/drivers/ubd.h | 1 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 72 | ||||
-rw-r--r-- | arch/um/drivers/ubd_user.c | 5 | ||||
-rw-r--r-- | arch/um/include/shared/os.h | 3 | ||||
-rw-r--r-- | arch/um/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/um/kernel/maccess.c | 24 | ||||
-rw-r--r-- | arch/um/os-Linux/aio.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/file.c | 9 | ||||
-rw-r--r-- | arch/um/os-Linux/main.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 53 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 10 | ||||
-rw-r--r-- | arch/x86/um/os-Linux/prctl.c | 2 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 9 |
15 files changed, 176 insertions, 27 deletions
diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3845051f1b10..3b48cd2081ee 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h | |||
@@ -7,7 +7,6 @@ | |||
7 | #ifndef __UM_UBD_USER_H | 7 | #ifndef __UM_UBD_USER_H |
8 | #define __UM_UBD_USER_H | 8 | #define __UM_UBD_USER_H |
9 | 9 | ||
10 | extern void ignore_sigwinch_sig(void); | ||
11 | extern int start_io_thread(unsigned long sp, int *fds_out); | 10 | extern int start_io_thread(unsigned long sp, int *fds_out); |
12 | extern int io_thread(void *arg); | 11 | extern int io_thread(void *arg); |
13 | extern int kernel_fd; | 12 | extern int kernel_fd; |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 879990cb66c6..3716e6952554 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <os.h> | 41 | #include <os.h> |
42 | #include "cow.h" | 42 | #include "cow.h" |
43 | 43 | ||
44 | enum ubd_req { UBD_READ, UBD_WRITE }; | 44 | enum ubd_req { UBD_READ, UBD_WRITE, UBD_FLUSH }; |
45 | 45 | ||
46 | struct io_thread_req { | 46 | struct io_thread_req { |
47 | struct request *req; | 47 | struct request *req; |
@@ -866,6 +866,7 @@ static int ubd_add(int n, char **error_out) | |||
866 | goto out; | 866 | goto out; |
867 | } | 867 | } |
868 | ubd_dev->queue->queuedata = ubd_dev; | 868 | ubd_dev->queue->queuedata = ubd_dev; |
869 | blk_queue_flush(ubd_dev->queue, REQ_FLUSH); | ||
869 | 870 | ||
870 | blk_queue_max_segments(ubd_dev->queue, MAX_SG); | 871 | blk_queue_max_segments(ubd_dev->queue, MAX_SG); |
871 | err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); | 872 | err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); |
@@ -1239,11 +1240,40 @@ static void prepare_request(struct request *req, struct io_thread_req *io_req, | |||
1239 | } | 1240 | } |
1240 | 1241 | ||
1241 | /* Called with dev->lock held */ | 1242 | /* Called with dev->lock held */ |
1243 | static void prepare_flush_request(struct request *req, | ||
1244 | struct io_thread_req *io_req) | ||
1245 | { | ||
1246 | struct gendisk *disk = req->rq_disk; | ||
1247 | struct ubd *ubd_dev = disk->private_data; | ||
1248 | |||
1249 | io_req->req = req; | ||
1250 | io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : | ||
1251 | ubd_dev->fd; | ||
1252 | io_req->op = UBD_FLUSH; | ||
1253 | } | ||
1254 | |||
1255 | static bool submit_request(struct io_thread_req *io_req, struct ubd *dev) | ||
1256 | { | ||
1257 | int n = os_write_file(thread_fd, &io_req, | ||
1258 | sizeof(io_req)); | ||
1259 | if (n != sizeof(io_req)) { | ||
1260 | if (n != -EAGAIN) | ||
1261 | printk("write to io thread failed, " | ||
1262 | "errno = %d\n", -n); | ||
1263 | else if (list_empty(&dev->restart)) | ||
1264 | list_add(&dev->restart, &restart); | ||
1265 | |||
1266 | kfree(io_req); | ||
1267 | return false; | ||
1268 | } | ||
1269 | return true; | ||
1270 | } | ||
1271 | |||
1272 | /* Called with dev->lock held */ | ||
1242 | static void do_ubd_request(struct request_queue *q) | 1273 | static void do_ubd_request(struct request_queue *q) |
1243 | { | 1274 | { |
1244 | struct io_thread_req *io_req; | 1275 | struct io_thread_req *io_req; |
1245 | struct request *req; | 1276 | struct request *req; |
1246 | int n; | ||
1247 | 1277 | ||
1248 | while(1){ | 1278 | while(1){ |
1249 | struct ubd *dev = q->queuedata; | 1279 | struct ubd *dev = q->queuedata; |
@@ -1259,6 +1289,19 @@ static void do_ubd_request(struct request_queue *q) | |||
1259 | } | 1289 | } |
1260 | 1290 | ||
1261 | req = dev->request; | 1291 | req = dev->request; |
1292 | |||
1293 | if (req->cmd_flags & REQ_FLUSH) { | ||
1294 | io_req = kmalloc(sizeof(struct io_thread_req), | ||
1295 | GFP_ATOMIC); | ||
1296 | if (io_req == NULL) { | ||
1297 | if (list_empty(&dev->restart)) | ||
1298 | list_add(&dev->restart, &restart); | ||
1299 | return; | ||
1300 | } | ||
1301 | prepare_flush_request(req, io_req); | ||
1302 | submit_request(io_req, dev); | ||
1303 | } | ||
1304 | |||
1262 | while(dev->start_sg < dev->end_sg){ | 1305 | while(dev->start_sg < dev->end_sg){ |
1263 | struct scatterlist *sg = &dev->sg[dev->start_sg]; | 1306 | struct scatterlist *sg = &dev->sg[dev->start_sg]; |
1264 | 1307 | ||
@@ -1273,17 +1316,8 @@ static void do_ubd_request(struct request_queue *q) | |||
1273 | (unsigned long long)dev->rq_pos << 9, | 1316 | (unsigned long long)dev->rq_pos << 9, |
1274 | sg->offset, sg->length, sg_page(sg)); | 1317 | sg->offset, sg->length, sg_page(sg)); |
1275 | 1318 | ||
1276 | n = os_write_file(thread_fd, &io_req, | 1319 | if (submit_request(io_req, dev) == false) |
1277 | sizeof(struct io_thread_req *)); | ||
1278 | if(n != sizeof(struct io_thread_req *)){ | ||
1279 | if(n != -EAGAIN) | ||
1280 | printk("write to io thread failed, " | ||
1281 | "errno = %d\n", -n); | ||
1282 | else if(list_empty(&dev->restart)) | ||
1283 | list_add(&dev->restart, &restart); | ||
1284 | kfree(io_req); | ||
1285 | return; | 1320 | return; |
1286 | } | ||
1287 | 1321 | ||
1288 | dev->rq_pos += sg->length >> 9; | 1322 | dev->rq_pos += sg->length >> 9; |
1289 | dev->start_sg++; | 1323 | dev->start_sg++; |
@@ -1367,6 +1401,17 @@ static void do_io(struct io_thread_req *req) | |||
1367 | int err; | 1401 | int err; |
1368 | __u64 off; | 1402 | __u64 off; |
1369 | 1403 | ||
1404 | if (req->op == UBD_FLUSH) { | ||
1405 | /* fds[0] is always either the rw image or our cow file */ | ||
1406 | n = os_sync_file(req->fds[0]); | ||
1407 | if (n != 0) { | ||
1408 | printk("do_io - sync failed err = %d " | ||
1409 | "fd = %d\n", -n, req->fds[0]); | ||
1410 | req->error = 1; | ||
1411 | } | ||
1412 | return; | ||
1413 | } | ||
1414 | |||
1370 | nsectors = req->length / req->sectorsize; | 1415 | nsectors = req->length / req->sectorsize; |
1371 | start = 0; | 1416 | start = 0; |
1372 | do { | 1417 | do { |
@@ -1431,7 +1476,8 @@ int io_thread(void *arg) | |||
1431 | struct io_thread_req *req; | 1476 | struct io_thread_req *req; |
1432 | int n; | 1477 | int n; |
1433 | 1478 | ||
1434 | ignore_sigwinch_sig(); | 1479 | os_fix_helper_signals(); |
1480 | |||
1435 | while(1){ | 1481 | while(1){ |
1436 | n = os_read_file(kernel_fd, &req, | 1482 | n = os_read_file(kernel_fd, &req, |
1437 | sizeof(struct io_thread_req *)); | 1483 | sizeof(struct io_thread_req *)); |
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index a703e45d8aac..e376f9b9c68d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c | |||
@@ -21,11 +21,6 @@ | |||
21 | #include "ubd.h" | 21 | #include "ubd.h" |
22 | #include <os.h> | 22 | #include <os.h> |
23 | 23 | ||
24 | void ignore_sigwinch_sig(void) | ||
25 | { | ||
26 | signal(SIGWINCH, SIG_IGN); | ||
27 | } | ||
28 | |||
29 | int start_io_thread(unsigned long sp, int *fd_out) | 24 | int start_io_thread(unsigned long sp, int *fd_out) |
30 | { | 25 | { |
31 | int pid, fds[2], err; | 26 | int pid, fds[2], err; |
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 95feaa47a2fb..021104d98cb3 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h | |||
@@ -141,6 +141,7 @@ extern int os_seek_file(int fd, unsigned long long offset); | |||
141 | extern int os_open_file(const char *file, struct openflags flags, int mode); | 141 | extern int os_open_file(const char *file, struct openflags flags, int mode); |
142 | extern int os_read_file(int fd, void *buf, int len); | 142 | extern int os_read_file(int fd, void *buf, int len); |
143 | extern int os_write_file(int fd, const void *buf, int count); | 143 | extern int os_write_file(int fd, const void *buf, int count); |
144 | extern int os_sync_file(int fd); | ||
144 | extern int os_file_size(const char *file, unsigned long long *size_out); | 145 | extern int os_file_size(const char *file, unsigned long long *size_out); |
145 | extern int os_file_modtime(const char *file, unsigned long *modtime); | 146 | extern int os_file_modtime(const char *file, unsigned long *modtime); |
146 | extern int os_pipe(int *fd, int stream, int close_on_exec); | 147 | extern int os_pipe(int *fd, int stream, int close_on_exec); |
@@ -200,6 +201,7 @@ extern int os_unmap_memory(void *addr, int len); | |||
200 | extern int os_drop_memory(void *addr, int length); | 201 | extern int os_drop_memory(void *addr, int length); |
201 | extern int can_drop_memory(void); | 202 | extern int can_drop_memory(void); |
202 | extern void os_flush_stdout(void); | 203 | extern void os_flush_stdout(void); |
204 | extern int os_mincore(void *addr, unsigned long len); | ||
203 | 205 | ||
204 | /* execvp.c */ | 206 | /* execvp.c */ |
205 | extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); | 207 | extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); |
@@ -233,6 +235,7 @@ extern void setup_machinename(char *machine_out); | |||
233 | extern void setup_hostinfo(char *buf, int len); | 235 | extern void setup_hostinfo(char *buf, int len); |
234 | extern void os_dump_core(void) __attribute__ ((noreturn)); | 236 | extern void os_dump_core(void) __attribute__ ((noreturn)); |
235 | extern void um_early_printk(const char *s, unsigned int n); | 237 | extern void um_early_printk(const char *s, unsigned int n); |
238 | extern void os_fix_helper_signals(void); | ||
236 | 239 | ||
237 | /* time.c */ | 240 | /* time.c */ |
238 | extern void idle_sleep(unsigned long long nsecs); | 241 | extern void idle_sleep(unsigned long long nsecs); |
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index babe21826e3e..d8b78a03855c 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -13,7 +13,7 @@ clean-files := | |||
13 | obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ | 13 | obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ |
14 | physmem.o process.o ptrace.o reboot.o sigio.o \ | 14 | physmem.o process.o ptrace.o reboot.o sigio.o \ |
15 | signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ | 15 | signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ |
16 | um_arch.o umid.o skas/ | 16 | um_arch.o umid.o maccess.o skas/ |
17 | 17 | ||
18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
19 | obj-$(CONFIG_GPROF) += gprof_syms.o | 19 | obj-$(CONFIG_GPROF) += gprof_syms.o |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 36e12f0cefd5..1d8505b1e290 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -337,6 +337,8 @@ static struct irq_chip normal_irq_type = { | |||
337 | .irq_disable = dummy, | 337 | .irq_disable = dummy, |
338 | .irq_enable = dummy, | 338 | .irq_enable = dummy, |
339 | .irq_ack = dummy, | 339 | .irq_ack = dummy, |
340 | .irq_mask = dummy, | ||
341 | .irq_unmask = dummy, | ||
340 | }; | 342 | }; |
341 | 343 | ||
342 | static struct irq_chip SIGVTALRM_irq_type = { | 344 | static struct irq_chip SIGVTALRM_irq_type = { |
@@ -344,6 +346,8 @@ static struct irq_chip SIGVTALRM_irq_type = { | |||
344 | .irq_disable = dummy, | 346 | .irq_disable = dummy, |
345 | .irq_enable = dummy, | 347 | .irq_enable = dummy, |
346 | .irq_ack = dummy, | 348 | .irq_ack = dummy, |
349 | .irq_mask = dummy, | ||
350 | .irq_unmask = dummy, | ||
347 | }; | 351 | }; |
348 | 352 | ||
349 | void __init init_IRQ(void) | 353 | void __init init_IRQ(void) |
diff --git a/arch/um/kernel/maccess.c b/arch/um/kernel/maccess.c new file mode 100644 index 000000000000..1f3d5c4910d1 --- /dev/null +++ b/arch/um/kernel/maccess.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Richard Weinberger <richrd@nod.at> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/uaccess.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <os.h> | ||
12 | |||
13 | long probe_kernel_read(void *dst, const void *src, size_t size) | ||
14 | { | ||
15 | void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); | ||
16 | |||
17 | if ((unsigned long)src < PAGE_SIZE || size <= 0) | ||
18 | return -EFAULT; | ||
19 | |||
20 | if (os_mincore(psrc, size + src - psrc) <= 0) | ||
21 | return -EFAULT; | ||
22 | |||
23 | return __probe_kernel_read(dst, src, size); | ||
24 | } | ||
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 3a6bc2af0961..014eb35fd13b 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c | |||
@@ -104,8 +104,7 @@ static int aio_thread(void *arg) | |||
104 | struct io_event event; | 104 | struct io_event event; |
105 | int err, n, reply_fd; | 105 | int err, n, reply_fd; |
106 | 106 | ||
107 | signal(SIGWINCH, SIG_IGN); | 107 | os_fix_helper_signals(); |
108 | |||
109 | while (1) { | 108 | while (1) { |
110 | n = io_getevents(ctx, 1, 1, &event, NULL); | 109 | n = io_getevents(ctx, 1, 1, &event, NULL); |
111 | if (n < 0) { | 110 | if (n < 0) { |
@@ -173,7 +172,7 @@ static int not_aio_thread(void *arg) | |||
173 | struct aio_thread_reply reply; | 172 | struct aio_thread_reply reply; |
174 | int err; | 173 | int err; |
175 | 174 | ||
176 | signal(SIGWINCH, SIG_IGN); | 175 | os_fix_helper_signals(); |
177 | while (1) { | 176 | while (1) { |
178 | err = read(aio_req_fd_r, &req, sizeof(req)); | 177 | err = read(aio_req_fd_r, &req, sizeof(req)); |
179 | if (err != sizeof(req)) { | 178 | if (err != sizeof(req)) { |
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index c17bd6f7d674..07a750197bb0 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c | |||
@@ -266,6 +266,15 @@ int os_write_file(int fd, const void *buf, int len) | |||
266 | return n; | 266 | return n; |
267 | } | 267 | } |
268 | 268 | ||
269 | int os_sync_file(int fd) | ||
270 | { | ||
271 | int n = fsync(fd); | ||
272 | |||
273 | if (n < 0) | ||
274 | return -errno; | ||
275 | return n; | ||
276 | } | ||
277 | |||
269 | int os_file_size(const char *file, unsigned long long *size_out) | 278 | int os_file_size(const char *file, unsigned long long *size_out) |
270 | { | 279 | { |
271 | struct uml_stat buf; | 280 | struct uml_stat buf; |
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 749c96da7b99..e1704ff600ff 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -123,6 +123,8 @@ int __init main(int argc, char **argv, char **envp) | |||
123 | 123 | ||
124 | setup_env_path(); | 124 | setup_env_path(); |
125 | 125 | ||
126 | setsid(); | ||
127 | |||
126 | new_argv = malloc((argc + 1) * sizeof(char *)); | 128 | new_argv = malloc((argc + 1) * sizeof(char *)); |
127 | if (new_argv == NULL) { | 129 | if (new_argv == NULL) { |
128 | perror("Mallocing argv"); | 130 | perror("Mallocing argv"); |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index b8f34c9e53ae..33496fe2bb52 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdio.h> | 6 | #include <stdio.h> |
7 | #include <stdlib.h> | ||
7 | #include <unistd.h> | 8 | #include <unistd.h> |
8 | #include <errno.h> | 9 | #include <errno.h> |
9 | #include <signal.h> | 10 | #include <signal.h> |
@@ -232,6 +233,57 @@ out: | |||
232 | return ok; | 233 | return ok; |
233 | } | 234 | } |
234 | 235 | ||
236 | static int os_page_mincore(void *addr) | ||
237 | { | ||
238 | char vec[2]; | ||
239 | int ret; | ||
240 | |||
241 | ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); | ||
242 | if (ret < 0) { | ||
243 | if (errno == ENOMEM || errno == EINVAL) | ||
244 | return 0; | ||
245 | else | ||
246 | return -errno; | ||
247 | } | ||
248 | |||
249 | return vec[0] & 1; | ||
250 | } | ||
251 | |||
252 | int os_mincore(void *addr, unsigned long len) | ||
253 | { | ||
254 | char *vec; | ||
255 | int ret, i; | ||
256 | |||
257 | if (len <= UM_KERN_PAGE_SIZE) | ||
258 | return os_page_mincore(addr); | ||
259 | |||
260 | vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); | ||
261 | if (!vec) | ||
262 | return -ENOMEM; | ||
263 | |||
264 | ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); | ||
265 | if (ret < 0) { | ||
266 | if (errno == ENOMEM || errno == EINVAL) | ||
267 | ret = 0; | ||
268 | else | ||
269 | ret = -errno; | ||
270 | |||
271 | goto out; | ||
272 | } | ||
273 | |||
274 | for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) { | ||
275 | if (!(vec[i] & 1)) { | ||
276 | ret = 0; | ||
277 | goto out; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | ret = 1; | ||
282 | out: | ||
283 | free(vec); | ||
284 | return ret; | ||
285 | } | ||
286 | |||
235 | void init_new_thread_signals(void) | 287 | void init_new_thread_signals(void) |
236 | { | 288 | { |
237 | set_handler(SIGSEGV); | 289 | set_handler(SIGSEGV); |
@@ -242,5 +294,4 @@ void init_new_thread_signals(void) | |||
242 | signal(SIGHUP, SIG_IGN); | 294 | signal(SIGHUP, SIG_IGN); |
243 | set_handler(SIGIO); | 295 | set_handler(SIGIO); |
244 | signal(SIGWINCH, SIG_IGN); | 296 | signal(SIGWINCH, SIG_IGN); |
245 | signal(SIGTERM, SIG_DFL); | ||
246 | } | 297 | } |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 8b61cc0e82c8..46e762f926eb 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -55,7 +55,7 @@ static int write_sigio_thread(void *unused) | |||
55 | int i, n, respond_fd; | 55 | int i, n, respond_fd; |
56 | char c; | 56 | char c; |
57 | 57 | ||
58 | signal(SIGWINCH, SIG_IGN); | 58 | os_fix_helper_signals(); |
59 | fds = ¤t_poll; | 59 | fds = ¤t_poll; |
60 | while (1) { | 60 | while (1) { |
61 | n = poll(fds->poll, fds->used, -1); | 61 | n = poll(fds->poll, fds->used, -1); |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 492ef5e6e166..faee55ef6d2f 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -94,6 +94,16 @@ static inline void __attribute__ ((noreturn)) uml_abort(void) | |||
94 | exit(127); | 94 | exit(127); |
95 | } | 95 | } |
96 | 96 | ||
97 | /* | ||
98 | * UML helper threads must not handle SIGWINCH/INT/TERM | ||
99 | */ | ||
100 | void os_fix_helper_signals(void) | ||
101 | { | ||
102 | signal(SIGWINCH, SIG_IGN); | ||
103 | signal(SIGINT, SIG_DFL); | ||
104 | signal(SIGTERM, SIG_DFL); | ||
105 | } | ||
106 | |||
97 | void os_dump_core(void) | 107 | void os_dump_core(void) |
98 | { | 108 | { |
99 | int pid; | 109 | int pid; |
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c index 9d34eddb517f..96eb2bd28832 100644 --- a/arch/x86/um/os-Linux/prctl.c +++ b/arch/x86/um/os-Linux/prctl.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <sys/ptrace.h> | 6 | #include <sys/ptrace.h> |
7 | #include <linux/ptrace.h> | 7 | #include <asm/ptrace.h> |
8 | 8 | ||
9 | int os_arch_prctl(int pid, int code, unsigned long *addr) | 9 | int os_arch_prctl(int pid, int code, unsigned long *addr) |
10 | { | 10 | { |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index cddb05217512..25437280a207 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -361,6 +361,13 @@ retry: | |||
361 | return 0; | 361 | return 0; |
362 | } | 362 | } |
363 | 363 | ||
364 | static int hostfs_file_release(struct inode *inode, struct file *file) | ||
365 | { | ||
366 | filemap_write_and_wait(inode->i_mapping); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
364 | int hostfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 371 | int hostfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
365 | { | 372 | { |
366 | struct inode *inode = file->f_mapping->host; | 373 | struct inode *inode = file->f_mapping->host; |
@@ -386,7 +393,7 @@ static const struct file_operations hostfs_file_fops = { | |||
386 | .write = do_sync_write, | 393 | .write = do_sync_write, |
387 | .mmap = generic_file_mmap, | 394 | .mmap = generic_file_mmap, |
388 | .open = hostfs_file_open, | 395 | .open = hostfs_file_open, |
389 | .release = NULL, | 396 | .release = hostfs_file_release, |
390 | .fsync = hostfs_fsync, | 397 | .fsync = hostfs_fsync, |
391 | }; | 398 | }; |
392 | 399 | ||