aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig.binfmt4
-rw-r--r--fs/Makefile1
-rw-r--r--fs/aio.c2
-rw-r--r--fs/binfmt_elf.c677
-rw-r--r--fs/compat_binfmt_elf.c131
-rw-r--r--fs/dlm/dir.c76
-rw-r--r--fs/dlm/dlm_internal.h16
-rw-r--r--fs/dlm/lock.c249
-rw-r--r--fs/dlm/lock.h2
-rw-r--r--fs/dlm/lockspace.c16
-rw-r--r--fs/dlm/lowcomms.c15
-rw-r--r--fs/dlm/main.c10
-rw-r--r--fs/dlm/member.c4
-rw-r--r--fs/dlm/member.h3
-rw-r--r--fs/dlm/memory.c32
-rw-r--r--fs/dlm/memory.h16
-rw-r--r--fs/dlm/midcomms.c15
-rw-r--r--fs/dlm/rcom.c25
-rw-r--r--fs/dlm/recover.c27
-rw-r--r--fs/dlm/recoverd.c11
-rw-r--r--fs/dlm/user.c29
-rw-r--r--fs/dlm/util.c82
-rw-r--r--fs/jbd/checkpoint.c3
-rw-r--r--fs/jbd/commit.c2
-rw-r--r--fs/jbd2/checkpoint.c3
-rw-r--r--fs/jbd2/commit.c2
26 files changed, 1051 insertions, 402 deletions
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index d4fc6095466d..7c3d5f923da1 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -23,6 +23,10 @@ config BINFMT_ELF
23 ld.so (check the file <file:Documentation/Changes> for location and 23 ld.so (check the file <file:Documentation/Changes> for location and
24 latest version). 24 latest version).
25 25
26config COMPAT_BINFMT_ELF
27 bool
28 depends on COMPAT && MMU
29
26config BINFMT_ELF_FDPIC 30config BINFMT_ELF_FDPIC
27 bool "Kernel support for FDPIC ELF binaries" 31 bool "Kernel support for FDPIC ELF binaries"
28 default y 32 default y
diff --git a/fs/Makefile b/fs/Makefile
index 500cf15cdb4b..1e7a11bd4da1 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
39obj-y += binfmt_script.o 39obj-y += binfmt_script.o
40 40
41obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o 41obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
42obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
42obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o 43obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
43obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o 44obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
44obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o 45obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
diff --git a/fs/aio.c b/fs/aio.c
index 9dec7d2d546e..8a37dbbf3437 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -397,7 +397,7 @@ void fastcall __put_ioctx(struct kioctx *ctx)
397 * This prevents races between the aio code path referencing the 397 * This prevents races between the aio code path referencing the
398 * req (after submitting it) and aio_complete() freeing the req. 398 * req (after submitting it) and aio_complete() freeing the req.
399 */ 399 */
400static struct kiocb *FASTCALL(__aio_get_req(struct kioctx *ctx)); 400static struct kiocb *__aio_get_req(struct kioctx *ctx);
401static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx) 401static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
402{ 402{
403 struct kiocb *req = NULL; 403 struct kiocb *req = NULL;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index f0b3171842f2..18ed6dd906c1 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -45,7 +45,8 @@
45 45
46static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); 46static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
47static int load_elf_library(struct file *); 47static int load_elf_library(struct file *);
48static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); 48static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
49 int, int, unsigned long);
49 50
50/* 51/*
51 * If we don't support core dumping, then supply a NULL so we 52 * If we don't support core dumping, then supply a NULL so we
@@ -298,33 +299,70 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
298#ifndef elf_map 299#ifndef elf_map
299 300
300static unsigned long elf_map(struct file *filep, unsigned long addr, 301static unsigned long elf_map(struct file *filep, unsigned long addr,
301 struct elf_phdr *eppnt, int prot, int type) 302 struct elf_phdr *eppnt, int prot, int type,
303 unsigned long total_size)
302{ 304{
303 unsigned long map_addr; 305 unsigned long map_addr;
304 unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); 306 unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
307 unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
308 addr = ELF_PAGESTART(addr);
309 size = ELF_PAGEALIGN(size);
305 310
306 down_write(&current->mm->mmap_sem);
307 /* mmap() will return -EINVAL if given a zero size, but a 311 /* mmap() will return -EINVAL if given a zero size, but a
308 * segment with zero filesize is perfectly valid */ 312 * segment with zero filesize is perfectly valid */
309 if (eppnt->p_filesz + pageoffset) 313 if (!size)
310 map_addr = do_mmap(filep, ELF_PAGESTART(addr), 314 return addr;
311 eppnt->p_filesz + pageoffset, prot, type, 315
312 eppnt->p_offset - pageoffset); 316 down_write(&current->mm->mmap_sem);
313 else 317 /*
314 map_addr = ELF_PAGESTART(addr); 318 * total_size is the size of the ELF (interpreter) image.
319 * The _first_ mmap needs to know the full size, otherwise
320 * randomization might put this image into an overlapping
321 * position with the ELF binary image. (since size < total_size)
322 * So we first map the 'big' image - and unmap the remainder at
323 * the end. (which unmap is needed for ELF images with holes.)
324 */
325 if (total_size) {
326 total_size = ELF_PAGEALIGN(total_size);
327 map_addr = do_mmap(filep, addr, total_size, prot, type, off);
328 if (!BAD_ADDR(map_addr))
329 do_munmap(current->mm, map_addr+size, total_size-size);
330 } else
331 map_addr = do_mmap(filep, addr, size, prot, type, off);
332
315 up_write(&current->mm->mmap_sem); 333 up_write(&current->mm->mmap_sem);
316 return(map_addr); 334 return(map_addr);
317} 335}
318 336
319#endif /* !elf_map */ 337#endif /* !elf_map */
320 338
339static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
340{
341 int i, first_idx = -1, last_idx = -1;
342
343 for (i = 0; i < nr; i++) {
344 if (cmds[i].p_type == PT_LOAD) {
345 last_idx = i;
346 if (first_idx == -1)
347 first_idx = i;
348 }
349 }
350 if (first_idx == -1)
351 return 0;
352
353 return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
354 ELF_PAGESTART(cmds[first_idx].p_vaddr);
355}
356
357
321/* This is much more generalized than the library routine read function, 358/* This is much more generalized than the library routine read function,
322 so we keep this separate. Technically the library read function 359 so we keep this separate. Technically the library read function
323 is only provided so that we can read a.out libraries that have 360 is only provided so that we can read a.out libraries that have
324 an ELF header */ 361 an ELF header */
325 362
326static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, 363static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
327 struct file *interpreter, unsigned long *interp_load_addr) 364 struct file *interpreter, unsigned long *interp_map_addr,
365 unsigned long no_base)
328{ 366{
329 struct elf_phdr *elf_phdata; 367 struct elf_phdr *elf_phdata;
330 struct elf_phdr *eppnt; 368 struct elf_phdr *eppnt;
@@ -332,6 +370,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
332 int load_addr_set = 0; 370 int load_addr_set = 0;
333 unsigned long last_bss = 0, elf_bss = 0; 371 unsigned long last_bss = 0, elf_bss = 0;
334 unsigned long error = ~0UL; 372 unsigned long error = ~0UL;
373 unsigned long total_size;
335 int retval, i, size; 374 int retval, i, size;
336 375
337 /* First of all, some simple consistency checks */ 376 /* First of all, some simple consistency checks */
@@ -370,6 +409,12 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
370 goto out_close; 409 goto out_close;
371 } 410 }
372 411
412 total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
413 if (!total_size) {
414 error = -EINVAL;
415 goto out_close;
416 }
417
373 eppnt = elf_phdata; 418 eppnt = elf_phdata;
374 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { 419 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
375 if (eppnt->p_type == PT_LOAD) { 420 if (eppnt->p_type == PT_LOAD) {
@@ -387,9 +432,14 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
387 vaddr = eppnt->p_vaddr; 432 vaddr = eppnt->p_vaddr;
388 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) 433 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
389 elf_type |= MAP_FIXED; 434 elf_type |= MAP_FIXED;
435 else if (no_base && interp_elf_ex->e_type == ET_DYN)
436 load_addr = -vaddr;
390 437
391 map_addr = elf_map(interpreter, load_addr + vaddr, 438 map_addr = elf_map(interpreter, load_addr + vaddr,
392 eppnt, elf_prot, elf_type); 439 eppnt, elf_prot, elf_type, total_size);
440 total_size = 0;
441 if (!*interp_map_addr)
442 *interp_map_addr = map_addr;
393 error = map_addr; 443 error = map_addr;
394 if (BAD_ADDR(map_addr)) 444 if (BAD_ADDR(map_addr))
395 goto out_close; 445 goto out_close;
@@ -455,8 +505,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
455 goto out_close; 505 goto out_close;
456 } 506 }
457 507
458 *interp_load_addr = load_addr; 508 error = load_addr;
459 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
460 509
461out_close: 510out_close:
462 kfree(elf_phdata); 511 kfree(elf_phdata);
@@ -546,14 +595,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
546 int load_addr_set = 0; 595 int load_addr_set = 0;
547 char * elf_interpreter = NULL; 596 char * elf_interpreter = NULL;
548 unsigned int interpreter_type = INTERPRETER_NONE; 597 unsigned int interpreter_type = INTERPRETER_NONE;
549 unsigned char ibcs2_interpreter = 0;
550 unsigned long error; 598 unsigned long error;
551 struct elf_phdr *elf_ppnt, *elf_phdata; 599 struct elf_phdr *elf_ppnt, *elf_phdata;
552 unsigned long elf_bss, elf_brk; 600 unsigned long elf_bss, elf_brk;
553 int elf_exec_fileno; 601 int elf_exec_fileno;
554 int retval, i; 602 int retval, i;
555 unsigned int size; 603 unsigned int size;
556 unsigned long elf_entry, interp_load_addr = 0; 604 unsigned long elf_entry;
605 unsigned long interp_load_addr = 0;
557 unsigned long start_code, end_code, start_data, end_data; 606 unsigned long start_code, end_code, start_data, end_data;
558 unsigned long reloc_func_desc = 0; 607 unsigned long reloc_func_desc = 0;
559 char passed_fileno[6]; 608 char passed_fileno[6];
@@ -663,14 +712,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
663 if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') 712 if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
664 goto out_free_interp; 713 goto out_free_interp;
665 714
666 /* If the program interpreter is one of these two,
667 * then assume an iBCS2 image. Otherwise assume
668 * a native linux image.
669 */
670 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
671 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
672 ibcs2_interpreter = 1;
673
674 /* 715 /*
675 * The early SET_PERSONALITY here is so that the lookup 716 * The early SET_PERSONALITY here is so that the lookup
676 * for the interpreter happens in the namespace of the 717 * for the interpreter happens in the namespace of the
@@ -690,7 +731,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
690 * switch really is going to happen - do this in 731 * switch really is going to happen - do this in
691 * flush_thread(). - akpm 732 * flush_thread(). - akpm
692 */ 733 */
693 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); 734 SET_PERSONALITY(loc->elf_ex, 0);
694 735
695 interpreter = open_exec(elf_interpreter); 736 interpreter = open_exec(elf_interpreter);
696 retval = PTR_ERR(interpreter); 737 retval = PTR_ERR(interpreter);
@@ -769,7 +810,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
769 goto out_free_dentry; 810 goto out_free_dentry;
770 } else { 811 } else {
771 /* Executables without an interpreter also need a personality */ 812 /* Executables without an interpreter also need a personality */
772 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); 813 SET_PERSONALITY(loc->elf_ex, 0);
773 } 814 }
774 815
775 /* OK, we are done with that, now set up the arg stuff, 816 /* OK, we are done with that, now set up the arg stuff,
@@ -803,7 +844,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
803 844
804 /* Do this immediately, since STACK_TOP as used in setup_arg_pages 845 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
805 may depend on the personality. */ 846 may depend on the personality. */
806 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); 847 SET_PERSONALITY(loc->elf_ex, 0);
807 if (elf_read_implies_exec(loc->elf_ex, executable_stack)) 848 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
808 current->personality |= READ_IMPLIES_EXEC; 849 current->personality |= READ_IMPLIES_EXEC;
809 850
@@ -825,9 +866,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
825 current->mm->start_stack = bprm->p; 866 current->mm->start_stack = bprm->p;
826 867
827 /* Now we do a little grungy work by mmaping the ELF image into 868 /* Now we do a little grungy work by mmaping the ELF image into
828 the correct location in memory. At this point, we assume that 869 the correct location in memory. */
829 the image should be loaded at fixed address, not at a variable
830 address. */
831 for(i = 0, elf_ppnt = elf_phdata; 870 for(i = 0, elf_ppnt = elf_phdata;
832 i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { 871 i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
833 int elf_prot = 0, elf_flags; 872 int elf_prot = 0, elf_flags;
@@ -881,11 +920,15 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
881 * default mmap base, as well as whatever program they 920 * default mmap base, as well as whatever program they
882 * might try to exec. This is because the brk will 921 * might try to exec. This is because the brk will
883 * follow the loader, and is not movable. */ 922 * follow the loader, and is not movable. */
923#ifdef CONFIG_X86
924 load_bias = 0;
925#else
884 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); 926 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
927#endif
885 } 928 }
886 929
887 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, 930 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
888 elf_prot, elf_flags); 931 elf_prot, elf_flags, 0);
889 if (BAD_ADDR(error)) { 932 if (BAD_ADDR(error)) {
890 send_sig(SIGKILL, current, 0); 933 send_sig(SIGKILL, current, 0);
891 retval = IS_ERR((void *)error) ? 934 retval = IS_ERR((void *)error) ?
@@ -961,13 +1004,25 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
961 } 1004 }
962 1005
963 if (elf_interpreter) { 1006 if (elf_interpreter) {
964 if (interpreter_type == INTERPRETER_AOUT) 1007 if (interpreter_type == INTERPRETER_AOUT) {
965 elf_entry = load_aout_interp(&loc->interp_ex, 1008 elf_entry = load_aout_interp(&loc->interp_ex,
966 interpreter); 1009 interpreter);
967 else 1010 } else {
1011 unsigned long uninitialized_var(interp_map_addr);
1012
968 elf_entry = load_elf_interp(&loc->interp_elf_ex, 1013 elf_entry = load_elf_interp(&loc->interp_elf_ex,
969 interpreter, 1014 interpreter,
970 &interp_load_addr); 1015 &interp_map_addr,
1016 load_bias);
1017 if (!IS_ERR((void *)elf_entry)) {
1018 /*
1019 * load_elf_interp() returns relocation
1020 * adjustment
1021 */
1022 interp_load_addr = elf_entry;
1023 elf_entry += loc->interp_elf_ex.e_entry;
1024 }
1025 }
971 if (BAD_ADDR(elf_entry)) { 1026 if (BAD_ADDR(elf_entry)) {
972 force_sig(SIGSEGV, current); 1027 force_sig(SIGSEGV, current);
973 retval = IS_ERR((void *)elf_entry) ? 1028 retval = IS_ERR((void *)elf_entry) ?
@@ -1021,6 +1076,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1021 current->mm->end_data = end_data; 1076 current->mm->end_data = end_data;
1022 current->mm->start_stack = bprm->p; 1077 current->mm->start_stack = bprm->p;
1023 1078
1079#ifdef arch_randomize_brk
1080 if (current->flags & PF_RANDOMIZE)
1081 current->mm->brk = current->mm->start_brk =
1082 arch_randomize_brk(current->mm);
1083#endif
1084
1024 if (current->personality & MMAP_PAGE_ZERO) { 1085 if (current->personality & MMAP_PAGE_ZERO) {
1025 /* Why this, you ask??? Well SVr4 maps page 0 as read-only, 1086 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1026 and some applications "depend" upon this behavior. 1087 and some applications "depend" upon this behavior.
@@ -1325,7 +1386,8 @@ static int writenote(struct memelfnote *men, struct file *file,
1325 if (!dump_seek(file, (off))) \ 1386 if (!dump_seek(file, (off))) \
1326 goto end_coredump; 1387 goto end_coredump;
1327 1388
1328static void fill_elf_header(struct elfhdr *elf, int segs) 1389static void fill_elf_header(struct elfhdr *elf, int segs,
1390 u16 machine, u32 flags, u8 osabi)
1329{ 1391{
1330 memcpy(elf->e_ident, ELFMAG, SELFMAG); 1392 memcpy(elf->e_ident, ELFMAG, SELFMAG);
1331 elf->e_ident[EI_CLASS] = ELF_CLASS; 1393 elf->e_ident[EI_CLASS] = ELF_CLASS;
@@ -1335,12 +1397,12 @@ static void fill_elf_header(struct elfhdr *elf, int segs)
1335 memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); 1397 memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
1336 1398
1337 elf->e_type = ET_CORE; 1399 elf->e_type = ET_CORE;
1338 elf->e_machine = ELF_ARCH; 1400 elf->e_machine = machine;
1339 elf->e_version = EV_CURRENT; 1401 elf->e_version = EV_CURRENT;
1340 elf->e_entry = 0; 1402 elf->e_entry = 0;
1341 elf->e_phoff = sizeof(struct elfhdr); 1403 elf->e_phoff = sizeof(struct elfhdr);
1342 elf->e_shoff = 0; 1404 elf->e_shoff = 0;
1343 elf->e_flags = ELF_CORE_EFLAGS; 1405 elf->e_flags = flags;
1344 elf->e_ehsize = sizeof(struct elfhdr); 1406 elf->e_ehsize = sizeof(struct elfhdr);
1345 elf->e_phentsize = sizeof(struct elf_phdr); 1407 elf->e_phentsize = sizeof(struct elf_phdr);
1346 elf->e_phnum = segs; 1408 elf->e_phnum = segs;
@@ -1447,6 +1509,238 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1447 return 0; 1509 return 0;
1448} 1510}
1449 1511
1512static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
1513{
1514 elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
1515 int i = 0;
1516 do
1517 i += 2;
1518 while (auxv[i - 2] != AT_NULL);
1519 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
1520}
1521
1522#ifdef CORE_DUMP_USE_REGSET
1523#include <linux/regset.h>
1524
1525struct elf_thread_core_info {
1526 struct elf_thread_core_info *next;
1527 struct task_struct *task;
1528 struct elf_prstatus prstatus;
1529 struct memelfnote notes[0];
1530};
1531
1532struct elf_note_info {
1533 struct elf_thread_core_info *thread;
1534 struct memelfnote psinfo;
1535 struct memelfnote auxv;
1536 size_t size;
1537 int thread_notes;
1538};
1539
1540static int fill_thread_core_info(struct elf_thread_core_info *t,
1541 const struct user_regset_view *view,
1542 long signr, size_t *total)
1543{
1544 unsigned int i;
1545
1546 /*
1547 * NT_PRSTATUS is the one special case, because the regset data
1548 * goes into the pr_reg field inside the note contents, rather
1549 * than being the whole note contents. We fill the reset in here.
1550 * We assume that regset 0 is NT_PRSTATUS.
1551 */
1552 fill_prstatus(&t->prstatus, t->task, signr);
1553 (void) view->regsets[0].get(t->task, &view->regsets[0],
1554 0, sizeof(t->prstatus.pr_reg),
1555 &t->prstatus.pr_reg, NULL);
1556
1557 fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
1558 sizeof(t->prstatus), &t->prstatus);
1559 *total += notesize(&t->notes[0]);
1560
1561 /*
1562 * Each other regset might generate a note too. For each regset
1563 * that has no core_note_type or is inactive, we leave t->notes[i]
1564 * all zero and we'll know to skip writing it later.
1565 */
1566 for (i = 1; i < view->n; ++i) {
1567 const struct user_regset *regset = &view->regsets[i];
1568 if (regset->core_note_type &&
1569 (!regset->active || regset->active(t->task, regset))) {
1570 int ret;
1571 size_t size = regset->n * regset->size;
1572 void *data = kmalloc(size, GFP_KERNEL);
1573 if (unlikely(!data))
1574 return 0;
1575 ret = regset->get(t->task, regset,
1576 0, size, data, NULL);
1577 if (unlikely(ret))
1578 kfree(data);
1579 else {
1580 if (regset->core_note_type != NT_PRFPREG)
1581 fill_note(&t->notes[i], "LINUX",
1582 regset->core_note_type,
1583 size, data);
1584 else {
1585 t->prstatus.pr_fpvalid = 1;
1586 fill_note(&t->notes[i], "CORE",
1587 NT_PRFPREG, size, data);
1588 }
1589 *total += notesize(&t->notes[i]);
1590 }
1591 }
1592 }
1593
1594 return 1;
1595}
1596
1597static int fill_note_info(struct elfhdr *elf, int phdrs,
1598 struct elf_note_info *info,
1599 long signr, struct pt_regs *regs)
1600{
1601 struct task_struct *dump_task = current;
1602 const struct user_regset_view *view = task_user_regset_view(dump_task);
1603 struct elf_thread_core_info *t;
1604 struct elf_prpsinfo *psinfo;
1605 struct task_struct *g, *p;
1606 unsigned int i;
1607
1608 info->size = 0;
1609 info->thread = NULL;
1610
1611 psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
1612 fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
1613
1614 if (psinfo == NULL)
1615 return 0;
1616
1617 /*
1618 * Figure out how many notes we're going to need for each thread.
1619 */
1620 info->thread_notes = 0;
1621 for (i = 0; i < view->n; ++i)
1622 if (view->regsets[i].core_note_type != 0)
1623 ++info->thread_notes;
1624
1625 /*
1626 * Sanity check. We rely on regset 0 being in NT_PRSTATUS,
1627 * since it is our one special case.
1628 */
1629 if (unlikely(info->thread_notes == 0) ||
1630 unlikely(view->regsets[0].core_note_type != NT_PRSTATUS)) {
1631 WARN_ON(1);
1632 return 0;
1633 }
1634
1635 /*
1636 * Initialize the ELF file header.
1637 */
1638 fill_elf_header(elf, phdrs,
1639 view->e_machine, view->e_flags, view->ei_osabi);
1640
1641 /*
1642 * Allocate a structure for each thread.
1643 */
1644 rcu_read_lock();
1645 do_each_thread(g, p)
1646 if (p->mm == dump_task->mm) {
1647 t = kzalloc(offsetof(struct elf_thread_core_info,
1648 notes[info->thread_notes]),
1649 GFP_ATOMIC);
1650 if (unlikely(!t)) {
1651 rcu_read_unlock();
1652 return 0;
1653 }
1654 t->task = p;
1655 if (p == dump_task || !info->thread) {
1656 t->next = info->thread;
1657 info->thread = t;
1658 } else {
1659 /*
1660 * Make sure to keep the original task at
1661 * the head of the list.
1662 */
1663 t->next = info->thread->next;
1664 info->thread->next = t;
1665 }
1666 }
1667 while_each_thread(g, p);
1668 rcu_read_unlock();
1669
1670 /*
1671 * Now fill in each thread's information.
1672 */
1673 for (t = info->thread; t != NULL; t = t->next)
1674 if (!fill_thread_core_info(t, view, signr, &info->size))
1675 return 0;
1676
1677 /*
1678 * Fill in the two process-wide notes.
1679 */
1680 fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm);
1681 info->size += notesize(&info->psinfo);
1682
1683 fill_auxv_note(&info->auxv, current->mm);
1684 info->size += notesize(&info->auxv);
1685
1686 return 1;
1687}
1688
1689static size_t get_note_info_size(struct elf_note_info *info)
1690{
1691 return info->size;
1692}
1693
1694/*
1695 * Write all the notes for each thread. When writing the first thread, the
1696 * process-wide notes are interleaved after the first thread-specific note.
1697 */
1698static int write_note_info(struct elf_note_info *info,
1699 struct file *file, loff_t *foffset)
1700{
1701 bool first = 1;
1702 struct elf_thread_core_info *t = info->thread;
1703
1704 do {
1705 int i;
1706
1707 if (!writenote(&t->notes[0], file, foffset))
1708 return 0;
1709
1710 if (first && !writenote(&info->psinfo, file, foffset))
1711 return 0;
1712 if (first && !writenote(&info->auxv, file, foffset))
1713 return 0;
1714
1715 for (i = 1; i < info->thread_notes; ++i)
1716 if (t->notes[i].data &&
1717 !writenote(&t->notes[i], file, foffset))
1718 return 0;
1719
1720 first = 0;
1721 t = t->next;
1722 } while (t);
1723
1724 return 1;
1725}
1726
1727static void free_note_info(struct elf_note_info *info)
1728{
1729 struct elf_thread_core_info *threads = info->thread;
1730 while (threads) {
1731 unsigned int i;
1732 struct elf_thread_core_info *t = threads;
1733 threads = t->next;
1734 WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus);
1735 for (i = 1; i < info->thread_notes; ++i)
1736 kfree(t->notes[i].data);
1737 kfree(t);
1738 }
1739 kfree(info->psinfo.data);
1740}
1741
1742#else
1743
1450/* Here is the structure in which status of each thread is captured. */ 1744/* Here is the structure in which status of each thread is captured. */
1451struct elf_thread_status 1745struct elf_thread_status
1452{ 1746{
@@ -1499,6 +1793,176 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1499 return sz; 1793 return sz;
1500} 1794}
1501 1795
1796struct elf_note_info {
1797 struct memelfnote *notes;
1798 struct elf_prstatus *prstatus; /* NT_PRSTATUS */
1799 struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
1800 struct list_head thread_list;
1801 elf_fpregset_t *fpu;
1802#ifdef ELF_CORE_COPY_XFPREGS
1803 elf_fpxregset_t *xfpu;
1804#endif
1805 int thread_status_size;
1806 int numnote;
1807};
1808
1809static int fill_note_info(struct elfhdr *elf, int phdrs,
1810 struct elf_note_info *info,
1811 long signr, struct pt_regs *regs)
1812{
1813#define NUM_NOTES 6
1814 struct list_head *t;
1815 struct task_struct *g, *p;
1816
1817 info->notes = NULL;
1818 info->prstatus = NULL;
1819 info->psinfo = NULL;
1820 info->fpu = NULL;
1821#ifdef ELF_CORE_COPY_XFPREGS
1822 info->xfpu = NULL;
1823#endif
1824 INIT_LIST_HEAD(&info->thread_list);
1825
1826 info->notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote),
1827 GFP_KERNEL);
1828 if (!info->notes)
1829 return 0;
1830 info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
1831 if (!info->psinfo)
1832 return 0;
1833 info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
1834 if (!info->prstatus)
1835 return 0;
1836 info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
1837 if (!info->fpu)
1838 return 0;
1839#ifdef ELF_CORE_COPY_XFPREGS
1840 info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL);
1841 if (!info->xfpu)
1842 return 0;
1843#endif
1844
1845 info->thread_status_size = 0;
1846 if (signr) {
1847 struct elf_thread_status *tmp;
1848 rcu_read_lock();
1849 do_each_thread(g, p)
1850 if (current->mm == p->mm && current != p) {
1851 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
1852 if (!tmp) {
1853 rcu_read_unlock();
1854 return 0;
1855 }
1856 tmp->thread = p;
1857 list_add(&tmp->list, &info->thread_list);
1858 }
1859 while_each_thread(g, p);
1860 rcu_read_unlock();
1861 list_for_each(t, &info->thread_list) {
1862 struct elf_thread_status *tmp;
1863 int sz;
1864
1865 tmp = list_entry(t, struct elf_thread_status, list);
1866 sz = elf_dump_thread_status(signr, tmp);
1867 info->thread_status_size += sz;
1868 }
1869 }
1870 /* now collect the dump for the current */
1871 memset(info->prstatus, 0, sizeof(*info->prstatus));
1872 fill_prstatus(info->prstatus, current, signr);
1873 elf_core_copy_regs(&info->prstatus->pr_reg, regs);
1874
1875 /* Set up header */
1876 fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS, ELF_OSABI);
1877
1878 /*
1879 * Set up the notes in similar form to SVR4 core dumps made
1880 * with info from their /proc.
1881 */
1882
1883 fill_note(info->notes + 0, "CORE", NT_PRSTATUS,
1884 sizeof(*info->prstatus), info->prstatus);
1885 fill_psinfo(info->psinfo, current->group_leader, current->mm);
1886 fill_note(info->notes + 1, "CORE", NT_PRPSINFO,
1887 sizeof(*info->psinfo), info->psinfo);
1888
1889 info->numnote = 2;
1890
1891 fill_auxv_note(&info->notes[info->numnote++], current->mm);
1892
1893 /* Try to dump the FPU. */
1894 info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs,
1895 info->fpu);
1896 if (info->prstatus->pr_fpvalid)
1897 fill_note(info->notes + info->numnote++,
1898 "CORE", NT_PRFPREG, sizeof(*info->fpu), info->fpu);
1899#ifdef ELF_CORE_COPY_XFPREGS
1900 if (elf_core_copy_task_xfpregs(current, info->xfpu))
1901 fill_note(info->notes + info->numnote++,
1902 "LINUX", ELF_CORE_XFPREG_TYPE,
1903 sizeof(*info->xfpu), info->xfpu);
1904#endif
1905
1906 return 1;
1907
1908#undef NUM_NOTES
1909}
1910
1911static size_t get_note_info_size(struct elf_note_info *info)
1912{
1913 int sz = 0;
1914 int i;
1915
1916 for (i = 0; i < info->numnote; i++)
1917 sz += notesize(info->notes + i);
1918
1919 sz += info->thread_status_size;
1920
1921 return sz;
1922}
1923
1924static int write_note_info(struct elf_note_info *info,
1925 struct file *file, loff_t *foffset)
1926{
1927 int i;
1928 struct list_head *t;
1929
1930 for (i = 0; i < info->numnote; i++)
1931 if (!writenote(info->notes + i, file, foffset))
1932 return 0;
1933
1934 /* write out the thread status notes section */
1935 list_for_each(t, &info->thread_list) {
1936 struct elf_thread_status *tmp =
1937 list_entry(t, struct elf_thread_status, list);
1938
1939 for (i = 0; i < tmp->num_notes; i++)
1940 if (!writenote(&tmp->notes[i], file, foffset))
1941 return 0;
1942 }
1943
1944 return 1;
1945}
1946
1947static void free_note_info(struct elf_note_info *info)
1948{
1949 while (!list_empty(&info->thread_list)) {
1950 struct list_head *tmp = info->thread_list.next;
1951 list_del(tmp);
1952 kfree(list_entry(tmp, struct elf_thread_status, list));
1953 }
1954
1955 kfree(info->prstatus);
1956 kfree(info->psinfo);
1957 kfree(info->notes);
1958 kfree(info->fpu);
1959#ifdef ELF_CORE_COPY_XFPREGS
1960 kfree(info->xfpu);
1961#endif
1962}
1963
1964#endif
1965
1502static struct vm_area_struct *first_vma(struct task_struct *tsk, 1966static struct vm_area_struct *first_vma(struct task_struct *tsk,
1503 struct vm_area_struct *gate_vma) 1967 struct vm_area_struct *gate_vma)
1504{ 1968{
@@ -1534,29 +1998,15 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
1534 */ 1998 */
1535static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) 1999static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
1536{ 2000{
1537#define NUM_NOTES 6
1538 int has_dumped = 0; 2001 int has_dumped = 0;
1539 mm_segment_t fs; 2002 mm_segment_t fs;
1540 int segs; 2003 int segs;
1541 size_t size = 0; 2004 size_t size = 0;
1542 int i;
1543 struct vm_area_struct *vma, *gate_vma; 2005 struct vm_area_struct *vma, *gate_vma;
1544 struct elfhdr *elf = NULL; 2006 struct elfhdr *elf = NULL;
1545 loff_t offset = 0, dataoff, foffset; 2007 loff_t offset = 0, dataoff, foffset;
1546 int numnote;
1547 struct memelfnote *notes = NULL;
1548 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
1549 struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */
1550 struct task_struct *g, *p;
1551 LIST_HEAD(thread_list);
1552 struct list_head *t;
1553 elf_fpregset_t *fpu = NULL;
1554#ifdef ELF_CORE_COPY_XFPREGS
1555 elf_fpxregset_t *xfpu = NULL;
1556#endif
1557 int thread_status_size = 0;
1558 elf_addr_t *auxv;
1559 unsigned long mm_flags; 2008 unsigned long mm_flags;
2009 struct elf_note_info info;
1560 2010
1561 /* 2011 /*
1562 * We no longer stop all VM operations. 2012 * We no longer stop all VM operations.
@@ -1574,52 +2024,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un
1574 elf = kmalloc(sizeof(*elf), GFP_KERNEL); 2024 elf = kmalloc(sizeof(*elf), GFP_KERNEL);
1575 if (!elf) 2025 if (!elf)
1576 goto cleanup; 2026 goto cleanup;
1577 prstatus = kmalloc(sizeof(*prstatus), GFP_KERNEL);
1578 if (!prstatus)
1579 goto cleanup;
1580 psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
1581 if (!psinfo)
1582 goto cleanup;
1583 notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), GFP_KERNEL);
1584 if (!notes)
1585 goto cleanup;
1586 fpu = kmalloc(sizeof(*fpu), GFP_KERNEL);
1587 if (!fpu)
1588 goto cleanup;
1589#ifdef ELF_CORE_COPY_XFPREGS
1590 xfpu = kmalloc(sizeof(*xfpu), GFP_KERNEL);
1591 if (!xfpu)
1592 goto cleanup;
1593#endif
1594
1595 if (signr) {
1596 struct elf_thread_status *tmp;
1597 rcu_read_lock();
1598 do_each_thread(g,p)
1599 if (current->mm == p->mm && current != p) {
1600 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
1601 if (!tmp) {
1602 rcu_read_unlock();
1603 goto cleanup;
1604 }
1605 tmp->thread = p;
1606 list_add(&tmp->list, &thread_list);
1607 }
1608 while_each_thread(g,p);
1609 rcu_read_unlock();
1610 list_for_each(t, &thread_list) {
1611 struct elf_thread_status *tmp;
1612 int sz;
1613
1614 tmp = list_entry(t, struct elf_thread_status, list);
1615 sz = elf_dump_thread_status(signr, tmp);
1616 thread_status_size += sz;
1617 }
1618 }
1619 /* now collect the dump for the current */
1620 memset(prstatus, 0, sizeof(*prstatus));
1621 fill_prstatus(prstatus, current, signr);
1622 elf_core_copy_regs(&prstatus->pr_reg, regs);
1623 2027
1624 segs = current->mm->map_count; 2028 segs = current->mm->map_count;
1625#ifdef ELF_CORE_EXTRA_PHDRS 2029#ifdef ELF_CORE_EXTRA_PHDRS
@@ -1630,42 +2034,16 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un
1630 if (gate_vma != NULL) 2034 if (gate_vma != NULL)
1631 segs++; 2035 segs++;
1632 2036
1633 /* Set up header */
1634 fill_elf_header(elf, segs + 1); /* including notes section */
1635
1636 has_dumped = 1;
1637 current->flags |= PF_DUMPCORE;
1638
1639 /* 2037 /*
1640 * Set up the notes in similar form to SVR4 core dumps made 2038 * Collect all the non-memory information about the process for the
1641 * with info from their /proc. 2039 * notes. This also sets up the file header.
1642 */ 2040 */
2041 if (!fill_note_info(elf, segs + 1, /* including notes section */
2042 &info, signr, regs))
2043 goto cleanup;
1643 2044
1644 fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus); 2045 has_dumped = 1;
1645 fill_psinfo(psinfo, current->group_leader, current->mm); 2046 current->flags |= PF_DUMPCORE;
1646 fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
1647
1648 numnote = 2;
1649
1650 auxv = (elf_addr_t *)current->mm->saved_auxv;
1651
1652 i = 0;
1653 do
1654 i += 2;
1655 while (auxv[i - 2] != AT_NULL);
1656 fill_note(&notes[numnote++], "CORE", NT_AUXV,
1657 i * sizeof(elf_addr_t), auxv);
1658
1659 /* Try to dump the FPU. */
1660 if ((prstatus->pr_fpvalid =
1661 elf_core_copy_task_fpregs(current, regs, fpu)))
1662 fill_note(notes + numnote++,
1663 "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
1664#ifdef ELF_CORE_COPY_XFPREGS
1665 if (elf_core_copy_task_xfpregs(current, xfpu))
1666 fill_note(notes + numnote++,
1667 "LINUX", ELF_CORE_XFPREG_TYPE, sizeof(*xfpu), xfpu);
1668#endif
1669 2047
1670 fs = get_fs(); 2048 fs = get_fs();
1671 set_fs(KERNEL_DS); 2049 set_fs(KERNEL_DS);
@@ -1678,12 +2056,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un
1678 /* Write notes phdr entry */ 2056 /* Write notes phdr entry */
1679 { 2057 {
1680 struct elf_phdr phdr; 2058 struct elf_phdr phdr;
1681 int sz = 0; 2059 size_t sz = get_note_info_size(&info);
1682
1683 for (i = 0; i < numnote; i++)
1684 sz += notesize(notes + i);
1685
1686 sz += thread_status_size;
1687 2060
1688 sz += elf_coredump_extra_notes_size(); 2061 sz += elf_coredump_extra_notes_size();
1689 2062
@@ -1728,23 +2101,12 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un
1728#endif 2101#endif
1729 2102
1730 /* write out the notes section */ 2103 /* write out the notes section */
1731 for (i = 0; i < numnote; i++) 2104 if (!write_note_info(&info, file, &foffset))
1732 if (!writenote(notes + i, file, &foffset)) 2105 goto end_coredump;
1733 goto end_coredump;
1734 2106
1735 if (elf_coredump_extra_notes_write(file, &foffset)) 2107 if (elf_coredump_extra_notes_write(file, &foffset))
1736 goto end_coredump; 2108 goto end_coredump;
1737 2109
1738 /* write out the thread status notes section */
1739 list_for_each(t, &thread_list) {
1740 struct elf_thread_status *tmp =
1741 list_entry(t, struct elf_thread_status, list);
1742
1743 for (i = 0; i < tmp->num_notes; i++)
1744 if (!writenote(&tmp->notes[i], file, &foffset))
1745 goto end_coredump;
1746 }
1747
1748 /* Align to page */ 2110 /* Align to page */
1749 DUMP_SEEK(dataoff - foffset); 2111 DUMP_SEEK(dataoff - foffset);
1750 2112
@@ -1795,22 +2157,9 @@ end_coredump:
1795 set_fs(fs); 2157 set_fs(fs);
1796 2158
1797cleanup: 2159cleanup:
1798 while (!list_empty(&thread_list)) {
1799 struct list_head *tmp = thread_list.next;
1800 list_del(tmp);
1801 kfree(list_entry(tmp, struct elf_thread_status, list));
1802 }
1803
1804 kfree(elf); 2160 kfree(elf);
1805 kfree(prstatus); 2161 free_note_info(&info);
1806 kfree(psinfo);
1807 kfree(notes);
1808 kfree(fpu);
1809#ifdef ELF_CORE_COPY_XFPREGS
1810 kfree(xfpu);
1811#endif
1812 return has_dumped; 2162 return has_dumped;
1813#undef NUM_NOTES
1814} 2163}
1815 2164
1816#endif /* USE_ELF_CORE_DUMP */ 2165#endif /* USE_ELF_CORE_DUMP */
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
new file mode 100644
index 000000000000..0adced2f296f
--- /dev/null
+++ b/fs/compat_binfmt_elf.c
@@ -0,0 +1,131 @@
1/*
2 * 32-bit compatibility support for ELF format executables and core dumps.
3 *
4 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU General Public License v.2.
9 *
10 * Red Hat Author: Roland McGrath.
11 *
12 * This file is used in a 64-bit kernel that wants to support 32-bit ELF.
13 * asm/elf.h is responsible for defining the compat_* and COMPAT_* macros
14 * used below, with definitions appropriate for 32-bit ABI compatibility.
15 *
16 * We use macros to rename the ABI types and machine-dependent
17 * functions used in binfmt_elf.c to compat versions.
18 */
19
20#include <linux/elfcore-compat.h>
21#include <linux/time.h>
22
23/*
24 * Rename the basic ELF layout types to refer to the 32-bit class of files.
25 */
26#undef ELF_CLASS
27#define ELF_CLASS ELFCLASS32
28
29#undef elfhdr
30#undef elf_phdr
31#undef elf_note
32#undef elf_addr_t
33#define elfhdr elf32_hdr
34#define elf_phdr elf32_phdr
35#define elf_note elf32_note
36#define elf_addr_t Elf32_Addr
37
38/*
39 * The machine-dependent core note format types are defined in elfcore-compat.h,
40 * which requires asm/elf.h to define compat_elf_gregset_t et al.
41 */
42#define elf_prstatus compat_elf_prstatus
43#define elf_prpsinfo compat_elf_prpsinfo
44
45/*
46 * Compat version of cputime_to_compat_timeval, perhaps this
47 * should be an inline in <linux/compat.h>.
48 */
49static void cputime_to_compat_timeval(const cputime_t cputime,
50 struct compat_timeval *value)
51{
52 struct timeval tv;
53 cputime_to_timeval(cputime, &tv);
54 value->tv_sec = tv.tv_sec;
55 value->tv_usec = tv.tv_usec;
56}
57
58#undef cputime_to_timeval
59#define cputime_to_timeval cputime_to_compat_timeval
60
61
62/*
63 * To use this file, asm/elf.h must define compat_elf_check_arch.
64 * The other following macros can be defined if the compat versions
65 * differ from the native ones, or omitted when they match.
66 */
67
68#undef ELF_ARCH
69#undef elf_check_arch
70#define elf_check_arch compat_elf_check_arch
71
72#ifdef COMPAT_ELF_PLATFORM
73#undef ELF_PLATFORM
74#define ELF_PLATFORM COMPAT_ELF_PLATFORM
75#endif
76
77#ifdef COMPAT_ELF_HWCAP
78#undef ELF_HWCAP
79#define ELF_HWCAP COMPAT_ELF_HWCAP
80#endif
81
82#ifdef COMPAT_ARCH_DLINFO
83#undef ARCH_DLINFO
84#define ARCH_DLINFO COMPAT_ARCH_DLINFO
85#endif
86
87#ifdef COMPAT_ELF_ET_DYN_BASE
88#undef ELF_ET_DYN_BASE
89#define ELF_ET_DYN_BASE COMPAT_ELF_ET_DYN_BASE
90#endif
91
92#ifdef COMPAT_ELF_EXEC_PAGESIZE
93#undef ELF_EXEC_PAGESIZE
94#define ELF_EXEC_PAGESIZE COMPAT_ELF_EXEC_PAGESIZE
95#endif
96
97#ifdef COMPAT_ELF_PLAT_INIT
98#undef ELF_PLAT_INIT
99#define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT
100#endif
101
102#ifdef COMPAT_SET_PERSONALITY
103#undef SET_PERSONALITY
104#define SET_PERSONALITY COMPAT_SET_PERSONALITY
105#endif
106
107#ifdef compat_start_thread
108#undef start_thread
109#define start_thread compat_start_thread
110#endif
111
112#ifdef compat_arch_setup_additional_pages
113#undef ARCH_HAS_SETUP_ADDITIONAL_PAGES
114#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
115#undef arch_setup_additional_pages
116#define arch_setup_additional_pages compat_arch_setup_additional_pages
117#endif
118
119/*
120 * Rename a few of the symbols that binfmt_elf.c will define.
121 * These are all local so the names don't really matter, but it
122 * might make some debugging less confusing not to duplicate them.
123 */
124#define elf_format compat_elf_format
125#define init_elf_binfmt init_compat_elf_binfmt
126#define exit_elf_binfmt exit_compat_elf_binfmt
127
128/*
129 * We share all the actual code with the native (64-bit) version.
130 */
131#include "binfmt_elf.c"
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index 46754553fdcc..ff97ba924333 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -49,7 +49,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len)
49 spin_unlock(&ls->ls_recover_list_lock); 49 spin_unlock(&ls->ls_recover_list_lock);
50 50
51 if (!found) 51 if (!found)
52 de = allocate_direntry(ls, len); 52 de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_KERNEL);
53 return de; 53 return de;
54} 54}
55 55
@@ -62,7 +62,7 @@ void dlm_clear_free_entries(struct dlm_ls *ls)
62 de = list_entry(ls->ls_recover_list.next, struct dlm_direntry, 62 de = list_entry(ls->ls_recover_list.next, struct dlm_direntry,
63 list); 63 list);
64 list_del(&de->list); 64 list_del(&de->list);
65 free_direntry(de); 65 kfree(de);
66 } 66 }
67 spin_unlock(&ls->ls_recover_list_lock); 67 spin_unlock(&ls->ls_recover_list_lock);
68} 68}
@@ -171,7 +171,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen
171 } 171 }
172 172
173 list_del(&de->list); 173 list_del(&de->list);
174 free_direntry(de); 174 kfree(de);
175 out: 175 out:
176 write_unlock(&ls->ls_dirtbl[bucket].lock); 176 write_unlock(&ls->ls_dirtbl[bucket].lock);
177} 177}
@@ -302,7 +302,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
302 302
303 write_unlock(&ls->ls_dirtbl[bucket].lock); 303 write_unlock(&ls->ls_dirtbl[bucket].lock);
304 304
305 de = allocate_direntry(ls, namelen); 305 de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
306 if (!de) 306 if (!de)
307 return -ENOMEM; 307 return -ENOMEM;
308 308
@@ -313,7 +313,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
313 write_lock(&ls->ls_dirtbl[bucket].lock); 313 write_lock(&ls->ls_dirtbl[bucket].lock);
314 tmp = search_bucket(ls, name, namelen, bucket); 314 tmp = search_bucket(ls, name, namelen, bucket);
315 if (tmp) { 315 if (tmp) {
316 free_direntry(de); 316 kfree(de);
317 de = tmp; 317 de = tmp;
318 } else { 318 } else {
319 list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); 319 list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list);
@@ -329,49 +329,47 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen,
329 return get_entry(ls, nodeid, name, namelen, r_nodeid); 329 return get_entry(ls, nodeid, name, namelen, r_nodeid);
330} 330}
331 331
332/* Copy the names of master rsb's into the buffer provided. 332static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
333 Only select names whose dir node is the given nodeid. */ 333{
334 struct dlm_rsb *r;
335
336 down_read(&ls->ls_root_sem);
337 list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
338 if (len == r->res_length && !memcmp(name, r->res_name, len)) {
339 up_read(&ls->ls_root_sem);
340 return r;
341 }
342 }
343 up_read(&ls->ls_root_sem);
344 return NULL;
345}
346
347/* Find the rsb where we left off (or start again), then send rsb names
348 for rsb's we're master of and whose directory node matches the requesting
349 node. inbuf is the rsb name last sent, inlen is the name's length */
334 350
335void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, 351void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
336 char *outbuf, int outlen, int nodeid) 352 char *outbuf, int outlen, int nodeid)
337{ 353{
338 struct list_head *list; 354 struct list_head *list;
339 struct dlm_rsb *start_r = NULL, *r = NULL; 355 struct dlm_rsb *r;
340 int offset = 0, start_namelen, error, dir_nodeid; 356 int offset = 0, dir_nodeid;
341 char *start_name;
342 uint16_t be_namelen; 357 uint16_t be_namelen;
343 358
344 /*
345 * Find the rsb where we left off (or start again)
346 */
347
348 start_namelen = inlen;
349 start_name = inbuf;
350
351 if (start_namelen > 1) {
352 /*
353 * We could also use a find_rsb_root() function here that
354 * searched the ls_root_list.
355 */
356 error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER,
357 &start_r);
358 DLM_ASSERT(!error && start_r,
359 printk("error %d\n", error););
360 DLM_ASSERT(!list_empty(&start_r->res_root_list),
361 dlm_print_rsb(start_r););
362 dlm_put_rsb(start_r);
363 }
364
365 /*
366 * Send rsb names for rsb's we're master of and whose directory node
367 * matches the requesting node.
368 */
369
370 down_read(&ls->ls_root_sem); 359 down_read(&ls->ls_root_sem);
371 if (start_r) 360
372 list = start_r->res_root_list.next; 361 if (inlen > 1) {
373 else 362 r = find_rsb_root(ls, inbuf, inlen);
363 if (!r) {
364 inbuf[inlen - 1] = '\0';
365 log_error(ls, "copy_master_names from %d start %d %s",
366 nodeid, inlen, inbuf);
367 goto out;
368 }
369 list = r->res_root_list.next;
370 } else {
374 list = ls->ls_root_list.next; 371 list = ls->ls_root_list.next;
372 }
375 373
376 for (offset = 0; list != &ls->ls_root_list; list = list->next) { 374 for (offset = 0; list != &ls->ls_root_list; list = list->next) {
377 r = list_entry(list, struct dlm_rsb, res_root_list); 375 r = list_entry(list, struct dlm_rsb, res_root_list);
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index d2fc2384c3be..ec61bbaf25df 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -570,5 +570,21 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
570 return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0; 570 return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0;
571} 571}
572 572
573int dlm_netlink_init(void);
574void dlm_netlink_exit(void);
575void dlm_timeout_warn(struct dlm_lkb *lkb);
576
577#ifdef CONFIG_DLM_DEBUG
578int dlm_register_debugfs(void);
579void dlm_unregister_debugfs(void);
580int dlm_create_debug_file(struct dlm_ls *ls);
581void dlm_delete_debug_file(struct dlm_ls *ls);
582#else
583static inline int dlm_register_debugfs(void) { return 0; }
584static inline void dlm_unregister_debugfs(void) { }
585static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
586static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
587#endif
588
573#endif /* __DLM_INTERNAL_DOT_H__ */ 589#endif /* __DLM_INTERNAL_DOT_H__ */
574 590
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 3915b8e14146..ff4a198fa677 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -88,7 +88,6 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
88static int receive_extralen(struct dlm_message *ms); 88static int receive_extralen(struct dlm_message *ms);
89static void do_purge(struct dlm_ls *ls, int nodeid, int pid); 89static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
90static void del_timeout(struct dlm_lkb *lkb); 90static void del_timeout(struct dlm_lkb *lkb);
91void dlm_timeout_warn(struct dlm_lkb *lkb);
92 91
93/* 92/*
94 * Lock compatibilty matrix - thanks Steve 93 * Lock compatibilty matrix - thanks Steve
@@ -335,7 +334,7 @@ static struct dlm_rsb *create_rsb(struct dlm_ls *ls, char *name, int len)
335{ 334{
336 struct dlm_rsb *r; 335 struct dlm_rsb *r;
337 336
338 r = allocate_rsb(ls, len); 337 r = dlm_allocate_rsb(ls, len);
339 if (!r) 338 if (!r)
340 return NULL; 339 return NULL;
341 340
@@ -478,7 +477,7 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
478 error = _search_rsb(ls, name, namelen, bucket, 0, &tmp); 477 error = _search_rsb(ls, name, namelen, bucket, 0, &tmp);
479 if (!error) { 478 if (!error) {
480 write_unlock(&ls->ls_rsbtbl[bucket].lock); 479 write_unlock(&ls->ls_rsbtbl[bucket].lock);
481 free_rsb(r); 480 dlm_free_rsb(r);
482 r = tmp; 481 r = tmp;
483 goto out; 482 goto out;
484 } 483 }
@@ -490,12 +489,6 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
490 return error; 489 return error;
491} 490}
492 491
493int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
494 unsigned int flags, struct dlm_rsb **r_ret)
495{
496 return find_rsb(ls, name, namelen, flags, r_ret);
497}
498
499/* This is only called to add a reference when the code already holds 492/* This is only called to add a reference when the code already holds
500 a valid reference to the rsb, so there's no need for locking. */ 493 a valid reference to the rsb, so there's no need for locking. */
501 494
@@ -519,7 +512,7 @@ static void toss_rsb(struct kref *kref)
519 list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss); 512 list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss);
520 r->res_toss_time = jiffies; 513 r->res_toss_time = jiffies;
521 if (r->res_lvbptr) { 514 if (r->res_lvbptr) {
522 free_lvb(r->res_lvbptr); 515 dlm_free_lvb(r->res_lvbptr);
523 r->res_lvbptr = NULL; 516 r->res_lvbptr = NULL;
524 } 517 }
525} 518}
@@ -589,7 +582,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
589 uint32_t lkid = 0; 582 uint32_t lkid = 0;
590 uint16_t bucket; 583 uint16_t bucket;
591 584
592 lkb = allocate_lkb(ls); 585 lkb = dlm_allocate_lkb(ls);
593 if (!lkb) 586 if (!lkb)
594 return -ENOMEM; 587 return -ENOMEM;
595 588
@@ -683,8 +676,8 @@ static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
683 676
684 /* for local/process lkbs, lvbptr points to caller's lksb */ 677 /* for local/process lkbs, lvbptr points to caller's lksb */
685 if (lkb->lkb_lvbptr && is_master_copy(lkb)) 678 if (lkb->lkb_lvbptr && is_master_copy(lkb))
686 free_lvb(lkb->lkb_lvbptr); 679 dlm_free_lvb(lkb->lkb_lvbptr);
687 free_lkb(lkb); 680 dlm_free_lkb(lkb);
688 return 1; 681 return 1;
689 } else { 682 } else {
690 write_unlock(&ls->ls_lkbtbl[bucket].lock); 683 write_unlock(&ls->ls_lkbtbl[bucket].lock);
@@ -988,7 +981,7 @@ static int shrink_bucket(struct dlm_ls *ls, int b)
988 981
989 if (is_master(r)) 982 if (is_master(r))
990 dir_remove(r); 983 dir_remove(r);
991 free_rsb(r); 984 dlm_free_rsb(r);
992 count++; 985 count++;
993 } else { 986 } else {
994 write_unlock(&ls->ls_rsbtbl[b].lock); 987 write_unlock(&ls->ls_rsbtbl[b].lock);
@@ -1171,7 +1164,7 @@ static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
1171 return; 1164 return;
1172 1165
1173 if (!r->res_lvbptr) 1166 if (!r->res_lvbptr)
1174 r->res_lvbptr = allocate_lvb(r->res_ls); 1167 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
1175 1168
1176 if (!r->res_lvbptr) 1169 if (!r->res_lvbptr)
1177 return; 1170 return;
@@ -1203,7 +1196,7 @@ static void set_lvb_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
1203 return; 1196 return;
1204 1197
1205 if (!r->res_lvbptr) 1198 if (!r->res_lvbptr)
1206 r->res_lvbptr = allocate_lvb(r->res_ls); 1199 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
1207 1200
1208 if (!r->res_lvbptr) 1201 if (!r->res_lvbptr)
1209 return; 1202 return;
@@ -1852,7 +1845,7 @@ static void send_blocking_asts_all(struct dlm_rsb *r, struct dlm_lkb *lkb)
1852static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb) 1845static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1853{ 1846{
1854 struct dlm_ls *ls = r->res_ls; 1847 struct dlm_ls *ls = r->res_ls;
1855 int error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid(); 1848 int i, error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid();
1856 1849
1857 if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) { 1850 if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) {
1858 rsb_clear_flag(r, RSB_MASTER_UNCERTAIN); 1851 rsb_clear_flag(r, RSB_MASTER_UNCERTAIN);
@@ -1886,7 +1879,7 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1886 return 1; 1879 return 1;
1887 } 1880 }
1888 1881
1889 for (;;) { 1882 for (i = 0; i < 2; i++) {
1890 /* It's possible for dlm_scand to remove an old rsb for 1883 /* It's possible for dlm_scand to remove an old rsb for
1891 this same resource from the toss list, us to create 1884 this same resource from the toss list, us to create
1892 a new one, look up the master locally, and find it 1885 a new one, look up the master locally, and find it
@@ -1900,6 +1893,8 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1900 log_debug(ls, "dir_lookup error %d %s", error, r->res_name); 1893 log_debug(ls, "dir_lookup error %d %s", error, r->res_name);
1901 schedule(); 1894 schedule();
1902 } 1895 }
1896 if (error && error != -EEXIST)
1897 return error;
1903 1898
1904 if (ret_nodeid == our_nodeid) { 1899 if (ret_nodeid == our_nodeid) {
1905 r->res_first_lkid = 0; 1900 r->res_first_lkid = 0;
@@ -1941,8 +1936,11 @@ static void confirm_master(struct dlm_rsb *r, int error)
1941 break; 1936 break;
1942 1937
1943 case -EAGAIN: 1938 case -EAGAIN:
1944 /* the remote master didn't queue our NOQUEUE request; 1939 case -EBADR:
1945 make a waiting lkb the first_lkid */ 1940 case -ENOTBLK:
1941 /* the remote request failed and won't be retried (it was
1942 a NOQUEUE, or has been canceled/unlocked); make a waiting
1943 lkb the first_lkid */
1946 1944
1947 r->res_first_lkid = 0; 1945 r->res_first_lkid = 0;
1948 1946
@@ -2108,17 +2106,18 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
2108 /* an lkb may be waiting for an rsb lookup to complete where the 2106 /* an lkb may be waiting for an rsb lookup to complete where the
2109 lookup was initiated by another lock */ 2107 lookup was initiated by another lock */
2110 2108
2111 if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) { 2109 if (!list_empty(&lkb->lkb_rsb_lookup)) {
2112 if (!list_empty(&lkb->lkb_rsb_lookup)) { 2110 if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
2113 log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id); 2111 log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id);
2114 list_del_init(&lkb->lkb_rsb_lookup); 2112 list_del_init(&lkb->lkb_rsb_lookup);
2115 queue_cast(lkb->lkb_resource, lkb, 2113 queue_cast(lkb->lkb_resource, lkb,
2116 args->flags & DLM_LKF_CANCEL ? 2114 args->flags & DLM_LKF_CANCEL ?
2117 -DLM_ECANCEL : -DLM_EUNLOCK); 2115 -DLM_ECANCEL : -DLM_EUNLOCK);
2118 unhold_lkb(lkb); /* undoes create_lkb() */ 2116 unhold_lkb(lkb); /* undoes create_lkb() */
2119 rv = -EBUSY;
2120 goto out;
2121 } 2117 }
2118 /* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */
2119 rv = -EBUSY;
2120 goto out;
2122 } 2121 }
2123 2122
2124 /* cancel not allowed with another cancel/unlock in progress */ 2123 /* cancel not allowed with another cancel/unlock in progress */
@@ -2986,7 +2985,7 @@ static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb,
2986 2985
2987 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 2986 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
2988 if (!lkb->lkb_lvbptr) 2987 if (!lkb->lkb_lvbptr)
2989 lkb->lkb_lvbptr = allocate_lvb(ls); 2988 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
2990 if (!lkb->lkb_lvbptr) 2989 if (!lkb->lkb_lvbptr)
2991 return -ENOMEM; 2990 return -ENOMEM;
2992 len = receive_extralen(ms); 2991 len = receive_extralen(ms);
@@ -3006,11 +3005,9 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3006 lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); 3005 lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST);
3007 lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); 3006 lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP);
3008 3007
3009 DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb););
3010
3011 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 3008 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
3012 /* lkb was just created so there won't be an lvb yet */ 3009 /* lkb was just created so there won't be an lvb yet */
3013 lkb->lkb_lvbptr = allocate_lvb(ls); 3010 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
3014 if (!lkb->lkb_lvbptr) 3011 if (!lkb->lkb_lvbptr)
3015 return -ENOMEM; 3012 return -ENOMEM;
3016 } 3013 }
@@ -3021,16 +3018,6 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3021static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, 3018static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3022 struct dlm_message *ms) 3019 struct dlm_message *ms)
3023{ 3020{
3024 if (lkb->lkb_nodeid != ms->m_header.h_nodeid) {
3025 log_error(ls, "convert_args nodeid %d %d lkid %x %x",
3026 lkb->lkb_nodeid, ms->m_header.h_nodeid,
3027 lkb->lkb_id, lkb->lkb_remid);
3028 return -EINVAL;
3029 }
3030
3031 if (!is_master_copy(lkb))
3032 return -EINVAL;
3033
3034 if (lkb->lkb_status != DLM_LKSTS_GRANTED) 3021 if (lkb->lkb_status != DLM_LKSTS_GRANTED)
3035 return -EBUSY; 3022 return -EBUSY;
3036 3023
@@ -3046,8 +3033,6 @@ static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3046static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, 3033static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3047 struct dlm_message *ms) 3034 struct dlm_message *ms)
3048{ 3035{
3049 if (!is_master_copy(lkb))
3050 return -EINVAL;
3051 if (receive_lvb(ls, lkb, ms)) 3036 if (receive_lvb(ls, lkb, ms))
3052 return -ENOMEM; 3037 return -ENOMEM;
3053 return 0; 3038 return 0;
@@ -3063,6 +3048,50 @@ static void setup_stub_lkb(struct dlm_ls *ls, struct dlm_message *ms)
3063 lkb->lkb_remid = ms->m_lkid; 3048 lkb->lkb_remid = ms->m_lkid;
3064} 3049}
3065 3050
3051/* This is called after the rsb is locked so that we can safely inspect
3052 fields in the lkb. */
3053
3054static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
3055{
3056 int from = ms->m_header.h_nodeid;
3057 int error = 0;
3058
3059 switch (ms->m_type) {
3060 case DLM_MSG_CONVERT:
3061 case DLM_MSG_UNLOCK:
3062 case DLM_MSG_CANCEL:
3063 if (!is_master_copy(lkb) || lkb->lkb_nodeid != from)
3064 error = -EINVAL;
3065 break;
3066
3067 case DLM_MSG_CONVERT_REPLY:
3068 case DLM_MSG_UNLOCK_REPLY:
3069 case DLM_MSG_CANCEL_REPLY:
3070 case DLM_MSG_GRANT:
3071 case DLM_MSG_BAST:
3072 if (!is_process_copy(lkb) || lkb->lkb_nodeid != from)
3073 error = -EINVAL;
3074 break;
3075
3076 case DLM_MSG_REQUEST_REPLY:
3077 if (!is_process_copy(lkb))
3078 error = -EINVAL;
3079 else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from)
3080 error = -EINVAL;
3081 break;
3082
3083 default:
3084 error = -EINVAL;
3085 }
3086
3087 if (error)
3088 log_error(lkb->lkb_resource->res_ls,
3089 "ignore invalid message %d from %d %x %x %x %d",
3090 ms->m_type, from, lkb->lkb_id, lkb->lkb_remid,
3091 lkb->lkb_flags, lkb->lkb_nodeid);
3092 return error;
3093}
3094
3066static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) 3095static void receive_request(struct dlm_ls *ls, struct dlm_message *ms)
3067{ 3096{
3068 struct dlm_lkb *lkb; 3097 struct dlm_lkb *lkb;
@@ -3124,17 +3153,21 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
3124 hold_rsb(r); 3153 hold_rsb(r);
3125 lock_rsb(r); 3154 lock_rsb(r);
3126 3155
3156 error = validate_message(lkb, ms);
3157 if (error)
3158 goto out;
3159
3127 receive_flags(lkb, ms); 3160 receive_flags(lkb, ms);
3128 error = receive_convert_args(ls, lkb, ms); 3161 error = receive_convert_args(ls, lkb, ms);
3129 if (error) 3162 if (error)
3130 goto out; 3163 goto out_reply;
3131 reply = !down_conversion(lkb); 3164 reply = !down_conversion(lkb);
3132 3165
3133 error = do_convert(r, lkb); 3166 error = do_convert(r, lkb);
3134 out: 3167 out_reply:
3135 if (reply) 3168 if (reply)
3136 send_convert_reply(r, lkb, error); 3169 send_convert_reply(r, lkb, error);
3137 3170 out:
3138 unlock_rsb(r); 3171 unlock_rsb(r);
3139 put_rsb(r); 3172 put_rsb(r);
3140 dlm_put_lkb(lkb); 3173 dlm_put_lkb(lkb);
@@ -3160,15 +3193,19 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
3160 hold_rsb(r); 3193 hold_rsb(r);
3161 lock_rsb(r); 3194 lock_rsb(r);
3162 3195
3196 error = validate_message(lkb, ms);
3197 if (error)
3198 goto out;
3199
3163 receive_flags(lkb, ms); 3200 receive_flags(lkb, ms);
3164 error = receive_unlock_args(ls, lkb, ms); 3201 error = receive_unlock_args(ls, lkb, ms);
3165 if (error) 3202 if (error)
3166 goto out; 3203 goto out_reply;
3167 3204
3168 error = do_unlock(r, lkb); 3205 error = do_unlock(r, lkb);
3169 out: 3206 out_reply:
3170 send_unlock_reply(r, lkb, error); 3207 send_unlock_reply(r, lkb, error);
3171 3208 out:
3172 unlock_rsb(r); 3209 unlock_rsb(r);
3173 put_rsb(r); 3210 put_rsb(r);
3174 dlm_put_lkb(lkb); 3211 dlm_put_lkb(lkb);
@@ -3196,9 +3233,13 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms)
3196 hold_rsb(r); 3233 hold_rsb(r);
3197 lock_rsb(r); 3234 lock_rsb(r);
3198 3235
3236 error = validate_message(lkb, ms);
3237 if (error)
3238 goto out;
3239
3199 error = do_cancel(r, lkb); 3240 error = do_cancel(r, lkb);
3200 send_cancel_reply(r, lkb, error); 3241 send_cancel_reply(r, lkb, error);
3201 3242 out:
3202 unlock_rsb(r); 3243 unlock_rsb(r);
3203 put_rsb(r); 3244 put_rsb(r);
3204 dlm_put_lkb(lkb); 3245 dlm_put_lkb(lkb);
@@ -3217,22 +3258,26 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
3217 3258
3218 error = find_lkb(ls, ms->m_remid, &lkb); 3259 error = find_lkb(ls, ms->m_remid, &lkb);
3219 if (error) { 3260 if (error) {
3220 log_error(ls, "receive_grant no lkb"); 3261 log_debug(ls, "receive_grant from %d no lkb %x",
3262 ms->m_header.h_nodeid, ms->m_remid);
3221 return; 3263 return;
3222 } 3264 }
3223 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3224 3265
3225 r = lkb->lkb_resource; 3266 r = lkb->lkb_resource;
3226 3267
3227 hold_rsb(r); 3268 hold_rsb(r);
3228 lock_rsb(r); 3269 lock_rsb(r);
3229 3270
3271 error = validate_message(lkb, ms);
3272 if (error)
3273 goto out;
3274
3230 receive_flags_reply(lkb, ms); 3275 receive_flags_reply(lkb, ms);
3231 if (is_altmode(lkb)) 3276 if (is_altmode(lkb))
3232 munge_altmode(lkb, ms); 3277 munge_altmode(lkb, ms);
3233 grant_lock_pc(r, lkb, ms); 3278 grant_lock_pc(r, lkb, ms);
3234 queue_cast(r, lkb, 0); 3279 queue_cast(r, lkb, 0);
3235 3280 out:
3236 unlock_rsb(r); 3281 unlock_rsb(r);
3237 put_rsb(r); 3282 put_rsb(r);
3238 dlm_put_lkb(lkb); 3283 dlm_put_lkb(lkb);
@@ -3246,18 +3291,22 @@ static void receive_bast(struct dlm_ls *ls, struct dlm_message *ms)
3246 3291
3247 error = find_lkb(ls, ms->m_remid, &lkb); 3292 error = find_lkb(ls, ms->m_remid, &lkb);
3248 if (error) { 3293 if (error) {
3249 log_error(ls, "receive_bast no lkb"); 3294 log_debug(ls, "receive_bast from %d no lkb %x",
3295 ms->m_header.h_nodeid, ms->m_remid);
3250 return; 3296 return;
3251 } 3297 }
3252 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3253 3298
3254 r = lkb->lkb_resource; 3299 r = lkb->lkb_resource;
3255 3300
3256 hold_rsb(r); 3301 hold_rsb(r);
3257 lock_rsb(r); 3302 lock_rsb(r);
3258 3303
3259 queue_bast(r, lkb, ms->m_bastmode); 3304 error = validate_message(lkb, ms);
3305 if (error)
3306 goto out;
3260 3307
3308 queue_bast(r, lkb, ms->m_bastmode);
3309 out:
3261 unlock_rsb(r); 3310 unlock_rsb(r);
3262 put_rsb(r); 3311 put_rsb(r);
3263 dlm_put_lkb(lkb); 3312 dlm_put_lkb(lkb);
@@ -3323,15 +3372,19 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
3323 3372
3324 error = find_lkb(ls, ms->m_remid, &lkb); 3373 error = find_lkb(ls, ms->m_remid, &lkb);
3325 if (error) { 3374 if (error) {
3326 log_error(ls, "receive_request_reply no lkb"); 3375 log_debug(ls, "receive_request_reply from %d no lkb %x",
3376 ms->m_header.h_nodeid, ms->m_remid);
3327 return; 3377 return;
3328 } 3378 }
3329 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3330 3379
3331 r = lkb->lkb_resource; 3380 r = lkb->lkb_resource;
3332 hold_rsb(r); 3381 hold_rsb(r);
3333 lock_rsb(r); 3382 lock_rsb(r);
3334 3383
3384 error = validate_message(lkb, ms);
3385 if (error)
3386 goto out;
3387
3335 mstype = lkb->lkb_wait_type; 3388 mstype = lkb->lkb_wait_type;
3336 error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY); 3389 error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY);
3337 if (error) 3390 if (error)
@@ -3383,6 +3436,7 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
3383 if (is_overlap(lkb)) { 3436 if (is_overlap(lkb)) {
3384 /* we'll ignore error in cancel/unlock reply */ 3437 /* we'll ignore error in cancel/unlock reply */
3385 queue_cast_overlap(r, lkb); 3438 queue_cast_overlap(r, lkb);
3439 confirm_master(r, result);
3386 unhold_lkb(lkb); /* undoes create_lkb() */ 3440 unhold_lkb(lkb); /* undoes create_lkb() */
3387 } else 3441 } else
3388 _request_lock(r, lkb); 3442 _request_lock(r, lkb);
@@ -3463,6 +3517,10 @@ static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3463 hold_rsb(r); 3517 hold_rsb(r);
3464 lock_rsb(r); 3518 lock_rsb(r);
3465 3519
3520 error = validate_message(lkb, ms);
3521 if (error)
3522 goto out;
3523
3466 /* stub reply can happen with waiters_mutex held */ 3524 /* stub reply can happen with waiters_mutex held */
3467 error = remove_from_waiters_ms(lkb, ms); 3525 error = remove_from_waiters_ms(lkb, ms);
3468 if (error) 3526 if (error)
@@ -3481,10 +3539,10 @@ static void receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms)
3481 3539
3482 error = find_lkb(ls, ms->m_remid, &lkb); 3540 error = find_lkb(ls, ms->m_remid, &lkb);
3483 if (error) { 3541 if (error) {
3484 log_error(ls, "receive_convert_reply no lkb"); 3542 log_debug(ls, "receive_convert_reply from %d no lkb %x",
3543 ms->m_header.h_nodeid, ms->m_remid);
3485 return; 3544 return;
3486 } 3545 }
3487 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3488 3546
3489 _receive_convert_reply(lkb, ms); 3547 _receive_convert_reply(lkb, ms);
3490 dlm_put_lkb(lkb); 3548 dlm_put_lkb(lkb);
@@ -3498,6 +3556,10 @@ static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3498 hold_rsb(r); 3556 hold_rsb(r);
3499 lock_rsb(r); 3557 lock_rsb(r);
3500 3558
3559 error = validate_message(lkb, ms);
3560 if (error)
3561 goto out;
3562
3501 /* stub reply can happen with waiters_mutex held */ 3563 /* stub reply can happen with waiters_mutex held */
3502 error = remove_from_waiters_ms(lkb, ms); 3564 error = remove_from_waiters_ms(lkb, ms);
3503 if (error) 3565 if (error)
@@ -3529,10 +3591,10 @@ static void receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms)
3529 3591
3530 error = find_lkb(ls, ms->m_remid, &lkb); 3592 error = find_lkb(ls, ms->m_remid, &lkb);
3531 if (error) { 3593 if (error) {
3532 log_error(ls, "receive_unlock_reply no lkb"); 3594 log_debug(ls, "receive_unlock_reply from %d no lkb %x",
3595 ms->m_header.h_nodeid, ms->m_remid);
3533 return; 3596 return;
3534 } 3597 }
3535 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3536 3598
3537 _receive_unlock_reply(lkb, ms); 3599 _receive_unlock_reply(lkb, ms);
3538 dlm_put_lkb(lkb); 3600 dlm_put_lkb(lkb);
@@ -3546,6 +3608,10 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3546 hold_rsb(r); 3608 hold_rsb(r);
3547 lock_rsb(r); 3609 lock_rsb(r);
3548 3610
3611 error = validate_message(lkb, ms);
3612 if (error)
3613 goto out;
3614
3549 /* stub reply can happen with waiters_mutex held */ 3615 /* stub reply can happen with waiters_mutex held */
3550 error = remove_from_waiters_ms(lkb, ms); 3616 error = remove_from_waiters_ms(lkb, ms);
3551 if (error) 3617 if (error)
@@ -3577,10 +3643,10 @@ static void receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms)
3577 3643
3578 error = find_lkb(ls, ms->m_remid, &lkb); 3644 error = find_lkb(ls, ms->m_remid, &lkb);
3579 if (error) { 3645 if (error) {
3580 log_error(ls, "receive_cancel_reply no lkb"); 3646 log_debug(ls, "receive_cancel_reply from %d no lkb %x",
3647 ms->m_header.h_nodeid, ms->m_remid);
3581 return; 3648 return;
3582 } 3649 }
3583 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3584 3650
3585 _receive_cancel_reply(lkb, ms); 3651 _receive_cancel_reply(lkb, ms);
3586 dlm_put_lkb(lkb); 3652 dlm_put_lkb(lkb);
@@ -3640,6 +3706,13 @@ static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
3640 3706
3641static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms) 3707static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms)
3642{ 3708{
3709 if (!dlm_is_member(ls, ms->m_header.h_nodeid)) {
3710 log_debug(ls, "ignore non-member message %d from %d %x %x %d",
3711 ms->m_type, ms->m_header.h_nodeid, ms->m_lkid,
3712 ms->m_remid, ms->m_result);
3713 return;
3714 }
3715
3643 switch (ms->m_type) { 3716 switch (ms->m_type) {
3644 3717
3645 /* messages sent to a master node */ 3718 /* messages sent to a master node */
@@ -3778,8 +3851,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
3778 3851
3779 ls = dlm_find_lockspace_global(hd->h_lockspace); 3852 ls = dlm_find_lockspace_global(hd->h_lockspace);
3780 if (!ls) { 3853 if (!ls) {
3781 log_print("invalid h_lockspace %x from %d cmd %d type %d", 3854 if (dlm_config.ci_log_debug)
3782 hd->h_lockspace, nodeid, hd->h_cmd, type); 3855 log_print("invalid lockspace %x from %d cmd %d type %d",
3856 hd->h_lockspace, nodeid, hd->h_cmd, type);
3783 3857
3784 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) 3858 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
3785 dlm_send_ls_not_ready(nodeid, rc); 3859 dlm_send_ls_not_ready(nodeid, rc);
@@ -3806,6 +3880,7 @@ static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb)
3806 ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; 3880 ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
3807 ls->ls_stub_ms.m_result = -EINPROGRESS; 3881 ls->ls_stub_ms.m_result = -EINPROGRESS;
3808 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3882 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3883 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3809 _receive_convert_reply(lkb, &ls->ls_stub_ms); 3884 _receive_convert_reply(lkb, &ls->ls_stub_ms);
3810 3885
3811 /* Same special case as in receive_rcom_lock_args() */ 3886 /* Same special case as in receive_rcom_lock_args() */
@@ -3847,6 +3922,7 @@ static int waiter_needs_recovery(struct dlm_ls *ls, struct dlm_lkb *lkb)
3847void dlm_recover_waiters_pre(struct dlm_ls *ls) 3922void dlm_recover_waiters_pre(struct dlm_ls *ls)
3848{ 3923{
3849 struct dlm_lkb *lkb, *safe; 3924 struct dlm_lkb *lkb, *safe;
3925 int wait_type, stub_unlock_result, stub_cancel_result;
3850 3926
3851 mutex_lock(&ls->ls_waiters_mutex); 3927 mutex_lock(&ls->ls_waiters_mutex);
3852 3928
@@ -3865,7 +3941,33 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3865 if (!waiter_needs_recovery(ls, lkb)) 3941 if (!waiter_needs_recovery(ls, lkb))
3866 continue; 3942 continue;
3867 3943
3868 switch (lkb->lkb_wait_type) { 3944 wait_type = lkb->lkb_wait_type;
3945 stub_unlock_result = -DLM_EUNLOCK;
3946 stub_cancel_result = -DLM_ECANCEL;
3947
3948 /* Main reply may have been received leaving a zero wait_type,
3949 but a reply for the overlapping op may not have been
3950 received. In that case we need to fake the appropriate
3951 reply for the overlap op. */
3952
3953 if (!wait_type) {
3954 if (is_overlap_cancel(lkb)) {
3955 wait_type = DLM_MSG_CANCEL;
3956 if (lkb->lkb_grmode == DLM_LOCK_IV)
3957 stub_cancel_result = 0;
3958 }
3959 if (is_overlap_unlock(lkb)) {
3960 wait_type = DLM_MSG_UNLOCK;
3961 if (lkb->lkb_grmode == DLM_LOCK_IV)
3962 stub_unlock_result = -ENOENT;
3963 }
3964
3965 log_debug(ls, "rwpre overlap %x %x %d %d %d",
3966 lkb->lkb_id, lkb->lkb_flags, wait_type,
3967 stub_cancel_result, stub_unlock_result);
3968 }
3969
3970 switch (wait_type) {
3869 3971
3870 case DLM_MSG_REQUEST: 3972 case DLM_MSG_REQUEST:
3871 lkb->lkb_flags |= DLM_IFL_RESEND; 3973 lkb->lkb_flags |= DLM_IFL_RESEND;
@@ -3878,8 +3980,9 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3878 case DLM_MSG_UNLOCK: 3980 case DLM_MSG_UNLOCK:
3879 hold_lkb(lkb); 3981 hold_lkb(lkb);
3880 ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; 3982 ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY;
3881 ls->ls_stub_ms.m_result = -DLM_EUNLOCK; 3983 ls->ls_stub_ms.m_result = stub_unlock_result;
3882 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3984 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3985 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3883 _receive_unlock_reply(lkb, &ls->ls_stub_ms); 3986 _receive_unlock_reply(lkb, &ls->ls_stub_ms);
3884 dlm_put_lkb(lkb); 3987 dlm_put_lkb(lkb);
3885 break; 3988 break;
@@ -3887,15 +3990,16 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3887 case DLM_MSG_CANCEL: 3990 case DLM_MSG_CANCEL:
3888 hold_lkb(lkb); 3991 hold_lkb(lkb);
3889 ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; 3992 ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY;
3890 ls->ls_stub_ms.m_result = -DLM_ECANCEL; 3993 ls->ls_stub_ms.m_result = stub_cancel_result;
3891 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3994 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3995 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3892 _receive_cancel_reply(lkb, &ls->ls_stub_ms); 3996 _receive_cancel_reply(lkb, &ls->ls_stub_ms);
3893 dlm_put_lkb(lkb); 3997 dlm_put_lkb(lkb);
3894 break; 3998 break;
3895 3999
3896 default: 4000 default:
3897 log_error(ls, "invalid lkb wait_type %d", 4001 log_error(ls, "invalid lkb wait_type %d %d",
3898 lkb->lkb_wait_type); 4002 lkb->lkb_wait_type, wait_type);
3899 } 4003 }
3900 schedule(); 4004 schedule();
3901 } 4005 }
@@ -4184,7 +4288,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
4184 lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP); 4288 lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP);
4185 4289
4186 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 4290 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
4187 lkb->lkb_lvbptr = allocate_lvb(ls); 4291 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
4188 if (!lkb->lkb_lvbptr) 4292 if (!lkb->lkb_lvbptr)
4189 return -ENOMEM; 4293 return -ENOMEM;
4190 lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - 4294 lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
@@ -4259,7 +4363,7 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
4259 put_rsb(r); 4363 put_rsb(r);
4260 out: 4364 out:
4261 if (error) 4365 if (error)
4262 log_print("recover_master_copy %d %x", error, rl->rl_lkid); 4366 log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid);
4263 rl->rl_result = error; 4367 rl->rl_result = error;
4264 return error; 4368 return error;
4265} 4369}
@@ -4342,7 +4446,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4342 } 4446 }
4343 } 4447 }
4344 4448
4345 /* After ua is attached to lkb it will be freed by free_lkb(). 4449 /* After ua is attached to lkb it will be freed by dlm_free_lkb().
4346 When DLM_IFL_USER is set, the dlm knows that this is a userspace 4450 When DLM_IFL_USER is set, the dlm knows that this is a userspace
4347 lock and that lkb_astparam is the dlm_user_args structure. */ 4451 lock and that lkb_astparam is the dlm_user_args structure. */
4348 4452
@@ -4679,6 +4783,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4679 } 4783 }
4680 4784
4681 list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) { 4785 list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
4786 lkb->lkb_ast_type = 0;
4682 list_del(&lkb->lkb_astqueue); 4787 list_del(&lkb->lkb_astqueue);
4683 dlm_put_lkb(lkb); 4788 dlm_put_lkb(lkb);
4684 } 4789 }
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index ada04680a1e5..27b6ed302911 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -19,8 +19,6 @@ void dlm_print_lkb(struct dlm_lkb *lkb);
19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); 19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
20void dlm_receive_buffer(struct dlm_header *hd, int nodeid); 20void dlm_receive_buffer(struct dlm_header *hd, int nodeid);
21int dlm_modes_compat(int mode1, int mode2); 21int dlm_modes_compat(int mode1, int mode2);
22int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
23 unsigned int flags, struct dlm_rsb **r_ret);
24void dlm_put_rsb(struct dlm_rsb *r); 22void dlm_put_rsb(struct dlm_rsb *r);
25void dlm_hold_rsb(struct dlm_rsb *r); 23void dlm_hold_rsb(struct dlm_rsb *r);
26int dlm_put_lkb(struct dlm_lkb *lkb); 24int dlm_put_lkb(struct dlm_lkb *lkb);
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 5c108c49cb8c..b180fdc51085 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -24,14 +24,6 @@
24#include "recover.h" 24#include "recover.h"
25#include "requestqueue.h" 25#include "requestqueue.h"
26 26
27#ifdef CONFIG_DLM_DEBUG
28int dlm_create_debug_file(struct dlm_ls *ls);
29void dlm_delete_debug_file(struct dlm_ls *ls);
30#else
31static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
32static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
33#endif
34
35static int ls_count; 27static int ls_count;
36static struct mutex ls_lock; 28static struct mutex ls_lock;
37static struct list_head lslist; 29static struct list_head lslist;
@@ -684,9 +676,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
684 dlm_del_ast(lkb); 676 dlm_del_ast(lkb);
685 677
686 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY) 678 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
687 free_lvb(lkb->lkb_lvbptr); 679 dlm_free_lvb(lkb->lkb_lvbptr);
688 680
689 free_lkb(lkb); 681 dlm_free_lkb(lkb);
690 } 682 }
691 } 683 }
692 dlm_astd_resume(); 684 dlm_astd_resume();
@@ -704,7 +696,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
704 res_hashchain); 696 res_hashchain);
705 697
706 list_del(&rsb->res_hashchain); 698 list_del(&rsb->res_hashchain);
707 free_rsb(rsb); 699 dlm_free_rsb(rsb);
708 } 700 }
709 701
710 head = &ls->ls_rsbtbl[i].toss; 702 head = &ls->ls_rsbtbl[i].toss;
@@ -712,7 +704,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
712 rsb = list_entry(head->next, struct dlm_rsb, 704 rsb = list_entry(head->next, struct dlm_rsb,
713 res_hashchain); 705 res_hashchain);
714 list_del(&rsb->res_hashchain); 706 list_del(&rsb->res_hashchain);
715 free_rsb(rsb); 707 dlm_free_rsb(rsb);
716 } 708 }
717 } 709 }
718 710
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index e9923ca9c2d9..7c1e5e5cccd8 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -864,7 +864,7 @@ static void sctp_init_assoc(struct connection *con)
864static void tcp_connect_to_sock(struct connection *con) 864static void tcp_connect_to_sock(struct connection *con)
865{ 865{
866 int result = -EHOSTUNREACH; 866 int result = -EHOSTUNREACH;
867 struct sockaddr_storage saddr; 867 struct sockaddr_storage saddr, src_addr;
868 int addr_len; 868 int addr_len;
869 struct socket *sock; 869 struct socket *sock;
870 870
@@ -898,6 +898,17 @@ static void tcp_connect_to_sock(struct connection *con)
898 con->connect_action = tcp_connect_to_sock; 898 con->connect_action = tcp_connect_to_sock;
899 add_sock(sock, con); 899 add_sock(sock, con);
900 900
901 /* Bind to our cluster-known address connecting to avoid
902 routing problems */
903 memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr));
904 make_sockaddr(&src_addr, 0, &addr_len);
905 result = sock->ops->bind(sock, (struct sockaddr *) &src_addr,
906 addr_len);
907 if (result < 0) {
908 log_print("could not bind for connect: %d", result);
909 /* This *may* not indicate a critical error */
910 }
911
901 make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); 912 make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
902 913
903 log_print("connecting to %d", con->nodeid); 914 log_print("connecting to %d", con->nodeid);
@@ -1426,6 +1437,8 @@ void dlm_lowcomms_stop(void)
1426 con = __nodeid2con(i, 0); 1437 con = __nodeid2con(i, 0);
1427 if (con) { 1438 if (con) {
1428 close_connection(con, true); 1439 close_connection(con, true);
1440 if (con->othercon)
1441 kmem_cache_free(con_cache, con->othercon);
1429 kmem_cache_free(con_cache, con); 1442 kmem_cache_free(con_cache, con);
1430 } 1443 }
1431 } 1444 }
diff --git a/fs/dlm/main.c b/fs/dlm/main.c
index eca2907f2386..58487fb95a4c 100644
--- a/fs/dlm/main.c
+++ b/fs/dlm/main.c
@@ -18,16 +18,6 @@
18#include "memory.h" 18#include "memory.h"
19#include "config.h" 19#include "config.h"
20 20
21#ifdef CONFIG_DLM_DEBUG
22int dlm_register_debugfs(void);
23void dlm_unregister_debugfs(void);
24#else
25static inline int dlm_register_debugfs(void) { return 0; }
26static inline void dlm_unregister_debugfs(void) { }
27#endif
28int dlm_netlink_init(void);
29void dlm_netlink_exit(void);
30
31static int __init init_dlm(void) 21static int __init init_dlm(void)
32{ 22{
33 int error; 23 int error;
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index e9cdcab306e2..fa17f5a27883 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -70,7 +70,7 @@ static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb)
70 ls->ls_num_nodes--; 70 ls->ls_num_nodes--;
71} 71}
72 72
73static int dlm_is_member(struct dlm_ls *ls, int nodeid) 73int dlm_is_member(struct dlm_ls *ls, int nodeid)
74{ 74{
75 struct dlm_member *memb; 75 struct dlm_member *memb;
76 76
diff --git a/fs/dlm/member.h b/fs/dlm/member.h
index 927c08c19214..7a26fca1e0b5 100644
--- a/fs/dlm/member.h
+++ b/fs/dlm/member.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -19,6 +19,7 @@ void dlm_clear_members(struct dlm_ls *ls);
19void dlm_clear_members_gone(struct dlm_ls *ls); 19void dlm_clear_members_gone(struct dlm_ls *ls);
20int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out); 20int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out);
21int dlm_is_removed(struct dlm_ls *ls, int nodeid); 21int dlm_is_removed(struct dlm_ls *ls, int nodeid);
22int dlm_is_member(struct dlm_ls *ls, int nodeid);
22 23
23#endif /* __MEMBER_DOT_H__ */ 24#endif /* __MEMBER_DOT_H__ */
24 25
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c
index ecf0e5cb2035..f7783867491a 100644
--- a/fs/dlm/memory.c
+++ b/fs/dlm/memory.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -35,7 +35,7 @@ void dlm_memory_exit(void)
35 kmem_cache_destroy(lkb_cache); 35 kmem_cache_destroy(lkb_cache);
36} 36}
37 37
38char *allocate_lvb(struct dlm_ls *ls) 38char *dlm_allocate_lvb(struct dlm_ls *ls)
39{ 39{
40 char *p; 40 char *p;
41 41
@@ -43,7 +43,7 @@ char *allocate_lvb(struct dlm_ls *ls)
43 return p; 43 return p;
44} 44}
45 45
46void free_lvb(char *p) 46void dlm_free_lvb(char *p)
47{ 47{
48 kfree(p); 48 kfree(p);
49} 49}
@@ -51,7 +51,7 @@ void free_lvb(char *p)
51/* FIXME: have some minimal space built-in to rsb for the name and 51/* FIXME: have some minimal space built-in to rsb for the name and
52 kmalloc a separate name if needed, like dentries are done */ 52 kmalloc a separate name if needed, like dentries are done */
53 53
54struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen) 54struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
55{ 55{
56 struct dlm_rsb *r; 56 struct dlm_rsb *r;
57 57
@@ -61,14 +61,14 @@ struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen)
61 return r; 61 return r;
62} 62}
63 63
64void free_rsb(struct dlm_rsb *r) 64void dlm_free_rsb(struct dlm_rsb *r)
65{ 65{
66 if (r->res_lvbptr) 66 if (r->res_lvbptr)
67 free_lvb(r->res_lvbptr); 67 dlm_free_lvb(r->res_lvbptr);
68 kfree(r); 68 kfree(r);
69} 69}
70 70
71struct dlm_lkb *allocate_lkb(struct dlm_ls *ls) 71struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
72{ 72{
73 struct dlm_lkb *lkb; 73 struct dlm_lkb *lkb;
74 74
@@ -76,7 +76,7 @@ struct dlm_lkb *allocate_lkb(struct dlm_ls *ls)
76 return lkb; 76 return lkb;
77} 77}
78 78
79void free_lkb(struct dlm_lkb *lkb) 79void dlm_free_lkb(struct dlm_lkb *lkb)
80{ 80{
81 if (lkb->lkb_flags & DLM_IFL_USER) { 81 if (lkb->lkb_flags & DLM_IFL_USER) {
82 struct dlm_user_args *ua; 82 struct dlm_user_args *ua;
@@ -90,19 +90,3 @@ void free_lkb(struct dlm_lkb *lkb)
90 kmem_cache_free(lkb_cache, lkb); 90 kmem_cache_free(lkb_cache, lkb);
91} 91}
92 92
93struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen)
94{
95 struct dlm_direntry *de;
96
97 DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,
98 printk("namelen = %d\n", namelen););
99
100 de = kzalloc(sizeof(*de) + namelen, GFP_KERNEL);
101 return de;
102}
103
104void free_direntry(struct dlm_direntry *de)
105{
106 kfree(de);
107}
108
diff --git a/fs/dlm/memory.h b/fs/dlm/memory.h
index 6ead158ccc5c..485fb29143bd 100644
--- a/fs/dlm/memory.h
+++ b/fs/dlm/memory.h
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -16,14 +16,12 @@
16 16
17int dlm_memory_init(void); 17int dlm_memory_init(void);
18void dlm_memory_exit(void); 18void dlm_memory_exit(void);
19struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen); 19struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen);
20void free_rsb(struct dlm_rsb *r); 20void dlm_free_rsb(struct dlm_rsb *r);
21struct dlm_lkb *allocate_lkb(struct dlm_ls *ls); 21struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls);
22void free_lkb(struct dlm_lkb *l); 22void dlm_free_lkb(struct dlm_lkb *l);
23struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen); 23char *dlm_allocate_lvb(struct dlm_ls *ls);
24void free_direntry(struct dlm_direntry *de); 24void dlm_free_lvb(char *l);
25char *allocate_lvb(struct dlm_ls *ls);
26void free_lvb(char *l);
27 25
28#endif /* __MEMORY_DOT_H__ */ 26#endif /* __MEMORY_DOT_H__ */
29 27
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index f8c69dda16a0..e69926e984db 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -58,8 +58,12 @@ static void copy_from_cb(void *dst, const void *base, unsigned offset,
58int dlm_process_incoming_buffer(int nodeid, const void *base, 58int dlm_process_incoming_buffer(int nodeid, const void *base,
59 unsigned offset, unsigned len, unsigned limit) 59 unsigned offset, unsigned len, unsigned limit)
60{ 60{
61 unsigned char __tmp[DLM_INBUF_LEN]; 61 union {
62 struct dlm_header *msg = (struct dlm_header *) __tmp; 62 unsigned char __buf[DLM_INBUF_LEN];
63 /* this is to force proper alignment on some arches */
64 struct dlm_header dlm;
65 } __tmp;
66 struct dlm_header *msg = &__tmp.dlm;
63 int ret = 0; 67 int ret = 0;
64 int err = 0; 68 int err = 0;
65 uint16_t msglen; 69 uint16_t msglen;
@@ -100,8 +104,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
100 in the buffer on the stack (which should work for most 104 in the buffer on the stack (which should work for most
101 ordinary messages). */ 105 ordinary messages). */
102 106
103 if (msglen > sizeof(__tmp) && 107 if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
104 msg == (struct dlm_header *) __tmp) {
105 msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); 108 msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
106 if (msg == NULL) 109 if (msg == NULL)
107 return ret; 110 return ret;
@@ -119,7 +122,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
119 dlm_receive_buffer(msg, nodeid); 122 dlm_receive_buffer(msg, nodeid);
120 } 123 }
121 124
122 if (msg != (struct dlm_header *) __tmp) 125 if (msg != &__tmp.dlm)
123 kfree(msg); 126 kfree(msg);
124 127
125 return err ? err : ret; 128 return err ? err : ret;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index ae2fd97fa4ad..026824cd3acb 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -197,11 +197,6 @@ static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
197 spin_unlock(&ls->ls_rcom_spin); 197 spin_unlock(&ls->ls_rcom_spin);
198} 198}
199 199
200static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
201{
202 receive_sync_reply(ls, rc_in);
203}
204
205int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) 200int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
206{ 201{
207 struct dlm_rcom *rc; 202 struct dlm_rcom *rc;
@@ -254,11 +249,6 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
254 send_rcom(ls, mh, rc); 249 send_rcom(ls, mh, rc);
255} 250}
256 251
257static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
258{
259 receive_sync_reply(ls, rc_in);
260}
261
262int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) 252int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
263{ 253{
264 struct dlm_rcom *rc; 254 struct dlm_rcom *rc;
@@ -381,11 +371,6 @@ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
381 send_rcom(ls, mh, rc); 371 send_rcom(ls, mh, rc);
382} 372}
383 373
384static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
385{
386 dlm_recover_process_copy(ls, rc_in);
387}
388
389/* If the lockspace doesn't exist then still send a status message 374/* If the lockspace doesn't exist then still send a status message
390 back; it's possible that it just doesn't have its global_id yet. */ 375 back; it's possible that it just doesn't have its global_id yet. */
391 376
@@ -481,11 +466,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
481 break; 466 break;
482 467
483 case DLM_RCOM_STATUS_REPLY: 468 case DLM_RCOM_STATUS_REPLY:
484 receive_rcom_status_reply(ls, rc); 469 receive_sync_reply(ls, rc);
485 break; 470 break;
486 471
487 case DLM_RCOM_NAMES_REPLY: 472 case DLM_RCOM_NAMES_REPLY:
488 receive_rcom_names_reply(ls, rc); 473 receive_sync_reply(ls, rc);
489 break; 474 break;
490 475
491 case DLM_RCOM_LOOKUP_REPLY: 476 case DLM_RCOM_LOOKUP_REPLY:
@@ -493,11 +478,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
493 break; 478 break;
494 479
495 case DLM_RCOM_LOCK_REPLY: 480 case DLM_RCOM_LOCK_REPLY:
496 receive_rcom_lock_reply(ls, rc); 481 dlm_recover_process_copy(ls, rc);
497 break; 482 break;
498 483
499 default: 484 default:
500 DLM_ASSERT(0, printk("rc_type=%x\n", rc->rc_type);); 485 log_error(ls, "receive_rcom bad type %d", rc->rc_type);
501 } 486 }
502 out: 487 out:
503 return; 488 return;
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index c2cc7694cd16..df075dc300fa 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -629,7 +629,7 @@ static void recover_lvb(struct dlm_rsb *r)
629 goto out; 629 goto out;
630 630
631 if (!r->res_lvbptr) { 631 if (!r->res_lvbptr) {
632 r->res_lvbptr = allocate_lvb(r->res_ls); 632 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
633 if (!r->res_lvbptr) 633 if (!r->res_lvbptr)
634 goto out; 634 goto out;
635 } 635 }
@@ -731,6 +731,20 @@ int dlm_create_root_list(struct dlm_ls *ls)
731 list_add(&r->res_root_list, &ls->ls_root_list); 731 list_add(&r->res_root_list, &ls->ls_root_list);
732 dlm_hold_rsb(r); 732 dlm_hold_rsb(r);
733 } 733 }
734
735 /* If we're using a directory, add tossed rsbs to the root
736 list; they'll have entries created in the new directory,
737 but no other recovery steps should do anything with them. */
738
739 if (dlm_no_directory(ls)) {
740 read_unlock(&ls->ls_rsbtbl[i].lock);
741 continue;
742 }
743
744 list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) {
745 list_add(&r->res_root_list, &ls->ls_root_list);
746 dlm_hold_rsb(r);
747 }
734 read_unlock(&ls->ls_rsbtbl[i].lock); 748 read_unlock(&ls->ls_rsbtbl[i].lock);
735 } 749 }
736 out: 750 out:
@@ -750,6 +764,11 @@ void dlm_release_root_list(struct dlm_ls *ls)
750 up_write(&ls->ls_root_sem); 764 up_write(&ls->ls_root_sem);
751} 765}
752 766
767/* If not using a directory, clear the entire toss list, there's no benefit to
768 caching the master value since it's fixed. If we are using a dir, keep the
769 rsb's we're the master of. Recovery will add them to the root list and from
770 there they'll be entered in the rebuilt directory. */
771
753void dlm_clear_toss_list(struct dlm_ls *ls) 772void dlm_clear_toss_list(struct dlm_ls *ls)
754{ 773{
755 struct dlm_rsb *r, *safe; 774 struct dlm_rsb *r, *safe;
@@ -759,8 +778,10 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
759 write_lock(&ls->ls_rsbtbl[i].lock); 778 write_lock(&ls->ls_rsbtbl[i].lock);
760 list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss, 779 list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss,
761 res_hashchain) { 780 res_hashchain) {
762 list_del(&r->res_hashchain); 781 if (dlm_no_directory(ls) || !is_master(r)) {
763 free_rsb(r); 782 list_del(&r->res_hashchain);
783 dlm_free_rsb(r);
784 }
764 } 785 }
765 write_unlock(&ls->ls_rsbtbl[i].lock); 786 write_unlock(&ls->ls_rsbtbl[i].lock);
766 } 787 }
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c
index 4b89e20eebe7..997f9531d594 100644
--- a/fs/dlm/recoverd.c
+++ b/fs/dlm/recoverd.c
@@ -67,17 +67,18 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
67 dlm_astd_resume(); 67 dlm_astd_resume();
68 68
69 /* 69 /*
70 * This list of root rsb's will be the basis of most of the recovery 70 * Free non-master tossed rsb's. Master rsb's are kept on toss
71 * routines. 71 * list and put on root list to be included in resdir recovery.
72 */ 72 */
73 73
74 dlm_create_root_list(ls); 74 dlm_clear_toss_list(ls);
75 75
76 /* 76 /*
77 * Free all the tossed rsb's so we don't have to recover them. 77 * This list of root rsb's will be the basis of most of the recovery
78 * routines.
78 */ 79 */
79 80
80 dlm_clear_toss_list(ls); 81 dlm_create_root_list(ls);
81 82
82 /* 83 /*
83 * Add or remove nodes from the lockspace's ls_nodes list. 84 * Add or remove nodes from the lockspace's ls_nodes list.
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 4f741546f4bb..7cbc6826239b 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -24,8 +24,7 @@
24#include "lvb_table.h" 24#include "lvb_table.h"
25#include "user.h" 25#include "user.h"
26 26
27static const char *name_prefix="dlm"; 27static const char name_prefix[] = "dlm";
28static struct miscdevice ctl_device;
29static const struct file_operations device_fops; 28static const struct file_operations device_fops;
30 29
31#ifdef CONFIG_COMPAT 30#ifdef CONFIG_COMPAT
@@ -82,7 +81,8 @@ struct dlm_lock_result32 {
82}; 81};
83 82
84static void compat_input(struct dlm_write_request *kb, 83static void compat_input(struct dlm_write_request *kb,
85 struct dlm_write_request32 *kb32) 84 struct dlm_write_request32 *kb32,
85 int max_namelen)
86{ 86{
87 kb->version[0] = kb32->version[0]; 87 kb->version[0] = kb32->version[0];
88 kb->version[1] = kb32->version[1]; 88 kb->version[1] = kb32->version[1];
@@ -112,7 +112,11 @@ static void compat_input(struct dlm_write_request *kb,
112 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; 112 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
113 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; 113 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
114 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); 114 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
115 memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen); 115 if (kb->i.lock.namelen <= max_namelen)
116 memcpy(kb->i.lock.name, kb32->i.lock.name,
117 kb->i.lock.namelen);
118 else
119 kb->i.lock.namelen = max_namelen;
116 } 120 }
117} 121}
118 122
@@ -236,12 +240,12 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
236 spin_unlock(&proc->asts_spin); 240 spin_unlock(&proc->asts_spin);
237 241
238 if (eol) { 242 if (eol) {
239 spin_lock(&ua->proc->locks_spin); 243 spin_lock(&proc->locks_spin);
240 if (!list_empty(&lkb->lkb_ownqueue)) { 244 if (!list_empty(&lkb->lkb_ownqueue)) {
241 list_del_init(&lkb->lkb_ownqueue); 245 list_del_init(&lkb->lkb_ownqueue);
242 dlm_put_lkb(lkb); 246 dlm_put_lkb(lkb);
243 } 247 }
244 spin_unlock(&ua->proc->locks_spin); 248 spin_unlock(&proc->locks_spin);
245 } 249 }
246 out: 250 out:
247 mutex_unlock(&ls->ls_clear_proc_locks); 251 mutex_unlock(&ls->ls_clear_proc_locks);
@@ -529,7 +533,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
529 533
530 if (proc) 534 if (proc)
531 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); 535 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
532 compat_input(kbuf, k32buf); 536 compat_input(kbuf, k32buf,
537 count - sizeof(struct dlm_write_request32));
533 kfree(k32buf); 538 kfree(k32buf);
534 } 539 }
535#endif 540#endif
@@ -896,14 +901,16 @@ static const struct file_operations ctl_device_fops = {
896 .owner = THIS_MODULE, 901 .owner = THIS_MODULE,
897}; 902};
898 903
904static struct miscdevice ctl_device = {
905 .name = "dlm-control",
906 .fops = &ctl_device_fops,
907 .minor = MISC_DYNAMIC_MINOR,
908};
909
899int dlm_user_init(void) 910int dlm_user_init(void)
900{ 911{
901 int error; 912 int error;
902 913
903 ctl_device.name = "dlm-control";
904 ctl_device.fops = &ctl_device_fops;
905 ctl_device.minor = MISC_DYNAMIC_MINOR;
906
907 error = misc_register(&ctl_device); 914 error = misc_register(&ctl_device);
908 if (error) 915 if (error)
909 log_print("misc_register failed for control device"); 916 log_print("misc_register failed for control device");
diff --git a/fs/dlm/util.c b/fs/dlm/util.c
index 963889cf6740..4d9c1f4e1bd1 100644
--- a/fs/dlm/util.c
+++ b/fs/dlm/util.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -14,6 +14,14 @@
14#include "rcom.h" 14#include "rcom.h"
15#include "util.h" 15#include "util.h"
16 16
17#define DLM_ERRNO_EDEADLK 35
18#define DLM_ERRNO_EBADR 53
19#define DLM_ERRNO_EBADSLT 57
20#define DLM_ERRNO_EPROTO 71
21#define DLM_ERRNO_EOPNOTSUPP 95
22#define DLM_ERRNO_ETIMEDOUT 110
23#define DLM_ERRNO_EINPROGRESS 115
24
17static void header_out(struct dlm_header *hd) 25static void header_out(struct dlm_header *hd)
18{ 26{
19 hd->h_version = cpu_to_le32(hd->h_version); 27 hd->h_version = cpu_to_le32(hd->h_version);
@@ -30,11 +38,54 @@ static void header_in(struct dlm_header *hd)
30 hd->h_length = le16_to_cpu(hd->h_length); 38 hd->h_length = le16_to_cpu(hd->h_length);
31} 39}
32 40
33void dlm_message_out(struct dlm_message *ms) 41/* higher errno values are inconsistent across architectures, so select
42 one set of values for on the wire */
43
44static int to_dlm_errno(int err)
45{
46 switch (err) {
47 case -EDEADLK:
48 return -DLM_ERRNO_EDEADLK;
49 case -EBADR:
50 return -DLM_ERRNO_EBADR;
51 case -EBADSLT:
52 return -DLM_ERRNO_EBADSLT;
53 case -EPROTO:
54 return -DLM_ERRNO_EPROTO;
55 case -EOPNOTSUPP:
56 return -DLM_ERRNO_EOPNOTSUPP;
57 case -ETIMEDOUT:
58 return -DLM_ERRNO_ETIMEDOUT;
59 case -EINPROGRESS:
60 return -DLM_ERRNO_EINPROGRESS;
61 }
62 return err;
63}
64
65static int from_dlm_errno(int err)
34{ 66{
35 struct dlm_header *hd = (struct dlm_header *) ms; 67 switch (err) {
68 case -DLM_ERRNO_EDEADLK:
69 return -EDEADLK;
70 case -DLM_ERRNO_EBADR:
71 return -EBADR;
72 case -DLM_ERRNO_EBADSLT:
73 return -EBADSLT;
74 case -DLM_ERRNO_EPROTO:
75 return -EPROTO;
76 case -DLM_ERRNO_EOPNOTSUPP:
77 return -EOPNOTSUPP;
78 case -DLM_ERRNO_ETIMEDOUT:
79 return -ETIMEDOUT;
80 case -DLM_ERRNO_EINPROGRESS:
81 return -EINPROGRESS;
82 }
83 return err;
84}
36 85
37 header_out(hd); 86void dlm_message_out(struct dlm_message *ms)
87{
88 header_out(&ms->m_header);
38 89
39 ms->m_type = cpu_to_le32(ms->m_type); 90 ms->m_type = cpu_to_le32(ms->m_type);
40 ms->m_nodeid = cpu_to_le32(ms->m_nodeid); 91 ms->m_nodeid = cpu_to_le32(ms->m_nodeid);
@@ -53,14 +104,12 @@ void dlm_message_out(struct dlm_message *ms)
53 ms->m_rqmode = cpu_to_le32(ms->m_rqmode); 104 ms->m_rqmode = cpu_to_le32(ms->m_rqmode);
54 ms->m_bastmode = cpu_to_le32(ms->m_bastmode); 105 ms->m_bastmode = cpu_to_le32(ms->m_bastmode);
55 ms->m_asts = cpu_to_le32(ms->m_asts); 106 ms->m_asts = cpu_to_le32(ms->m_asts);
56 ms->m_result = cpu_to_le32(ms->m_result); 107 ms->m_result = cpu_to_le32(to_dlm_errno(ms->m_result));
57} 108}
58 109
59void dlm_message_in(struct dlm_message *ms) 110void dlm_message_in(struct dlm_message *ms)
60{ 111{
61 struct dlm_header *hd = (struct dlm_header *) ms; 112 header_in(&ms->m_header);
62
63 header_in(hd);
64 113
65 ms->m_type = le32_to_cpu(ms->m_type); 114 ms->m_type = le32_to_cpu(ms->m_type);
66 ms->m_nodeid = le32_to_cpu(ms->m_nodeid); 115 ms->m_nodeid = le32_to_cpu(ms->m_nodeid);
@@ -79,7 +128,7 @@ void dlm_message_in(struct dlm_message *ms)
79 ms->m_rqmode = le32_to_cpu(ms->m_rqmode); 128 ms->m_rqmode = le32_to_cpu(ms->m_rqmode);
80 ms->m_bastmode = le32_to_cpu(ms->m_bastmode); 129 ms->m_bastmode = le32_to_cpu(ms->m_bastmode);
81 ms->m_asts = le32_to_cpu(ms->m_asts); 130 ms->m_asts = le32_to_cpu(ms->m_asts);
82 ms->m_result = le32_to_cpu(ms->m_result); 131 ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
83} 132}
84 133
85static void rcom_lock_out(struct rcom_lock *rl) 134static void rcom_lock_out(struct rcom_lock *rl)
@@ -126,10 +175,9 @@ static void rcom_config_in(struct rcom_config *rf)
126 175
127void dlm_rcom_out(struct dlm_rcom *rc) 176void dlm_rcom_out(struct dlm_rcom *rc)
128{ 177{
129 struct dlm_header *hd = (struct dlm_header *) rc;
130 int type = rc->rc_type; 178 int type = rc->rc_type;
131 179
132 header_out(hd); 180 header_out(&rc->rc_header);
133 181
134 rc->rc_type = cpu_to_le32(rc->rc_type); 182 rc->rc_type = cpu_to_le32(rc->rc_type);
135 rc->rc_result = cpu_to_le32(rc->rc_result); 183 rc->rc_result = cpu_to_le32(rc->rc_result);
@@ -137,7 +185,7 @@ void dlm_rcom_out(struct dlm_rcom *rc)
137 rc->rc_seq = cpu_to_le64(rc->rc_seq); 185 rc->rc_seq = cpu_to_le64(rc->rc_seq);
138 rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); 186 rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply);
139 187
140 if (type == DLM_RCOM_LOCK) 188 if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
141 rcom_lock_out((struct rcom_lock *) rc->rc_buf); 189 rcom_lock_out((struct rcom_lock *) rc->rc_buf);
142 190
143 else if (type == DLM_RCOM_STATUS_REPLY) 191 else if (type == DLM_RCOM_STATUS_REPLY)
@@ -146,9 +194,9 @@ void dlm_rcom_out(struct dlm_rcom *rc)
146 194
147void dlm_rcom_in(struct dlm_rcom *rc) 195void dlm_rcom_in(struct dlm_rcom *rc)
148{ 196{
149 struct dlm_header *hd = (struct dlm_header *) rc; 197 int type;
150 198
151 header_in(hd); 199 header_in(&rc->rc_header);
152 200
153 rc->rc_type = le32_to_cpu(rc->rc_type); 201 rc->rc_type = le32_to_cpu(rc->rc_type);
154 rc->rc_result = le32_to_cpu(rc->rc_result); 202 rc->rc_result = le32_to_cpu(rc->rc_result);
@@ -156,10 +204,12 @@ void dlm_rcom_in(struct dlm_rcom *rc)
156 rc->rc_seq = le64_to_cpu(rc->rc_seq); 204 rc->rc_seq = le64_to_cpu(rc->rc_seq);
157 rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); 205 rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
158 206
159 if (rc->rc_type == DLM_RCOM_LOCK) 207 type = rc->rc_type;
208
209 if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
160 rcom_lock_in((struct rcom_lock *) rc->rc_buf); 210 rcom_lock_in((struct rcom_lock *) rc->rc_buf);
161 211
162 else if (rc->rc_type == DLM_RCOM_STATUS_REPLY) 212 else if (type == DLM_RCOM_STATUS_REPLY)
163 rcom_config_in((struct rcom_config *) rc->rc_buf); 213 rcom_config_in((struct rcom_config *) rc->rc_buf);
164} 214}
165 215
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 0f69c416eebc..a5432bbbfb88 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -347,7 +347,8 @@ restart:
347 break; 347 break;
348 } 348 }
349 retry = __process_buffer(journal, jh, bhs,&batch_count); 349 retry = __process_buffer(journal, jh, bhs,&batch_count);
350 if (!retry && lock_need_resched(&journal->j_list_lock)){ 350 if (!retry && (need_resched() ||
351 spin_needbreak(&journal->j_list_lock))) {
351 spin_unlock(&journal->j_list_lock); 352 spin_unlock(&journal->j_list_lock);
352 retry = 1; 353 retry = 1;
353 break; 354 break;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 610264b99a8e..31853eb65b4c 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -265,7 +265,7 @@ write_out_data:
265 put_bh(bh); 265 put_bh(bh);
266 } 266 }
267 267
268 if (lock_need_resched(&journal->j_list_lock)) { 268 if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
269 spin_unlock(&journal->j_list_lock); 269 spin_unlock(&journal->j_list_lock);
270 goto write_out_data; 270 goto write_out_data;
271 } 271 }
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 1b7f282c1ae9..6914598022ce 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -353,7 +353,8 @@ restart:
353 } 353 }
354 retry = __process_buffer(journal, jh, bhs, &batch_count, 354 retry = __process_buffer(journal, jh, bhs, &batch_count,
355 transaction); 355 transaction);
356 if (!retry && lock_need_resched(&journal->j_list_lock)){ 356 if (!retry && (need_resched() ||
357 spin_needbreak(&journal->j_list_lock))) {
357 spin_unlock(&journal->j_list_lock); 358 spin_unlock(&journal->j_list_lock);
358 retry = 1; 359 retry = 1;
359 break; 360 break;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index da8d0eb3b7b9..4f302d279279 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -341,7 +341,7 @@ write_out_data:
341 put_bh(bh); 341 put_bh(bh);
342 } 342 }
343 343
344 if (lock_need_resched(&journal->j_list_lock)) { 344 if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
345 spin_unlock(&journal->j_list_lock); 345 spin_unlock(&journal->j_list_lock);
346 goto write_out_data; 346 goto write_out_data;
347 } 347 }