Pull non-mm updates from Andrew Morton: "Mainly singleton patches, documented in their respective changelogs. Notable series include: - Some maintenance and performance work for ocfs2 in Heming Zhao's series "improve write IO performance when fragmentation is high". - Some ocfs2 bugfixes from Su Yue in the series "ocfs2 bugs fixes exposed by fstests". - kfifo header rework from Andy Shevchenko in the series "kfifo: Clean up kfifo.h". - GDB script fixes from Florian Rommel in the series "scripts/gdb: Fixes for $lx_current and $lx_per_cpu". - After much discussion, a coding-style update from Barry Song explaining one reason why inline functions are preferred over macros. The series is "codingstyle: avoid unused parameters for a function-like macro"" * tag 'mm-nonmm-stable-2024-05-19-11-56' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (62 commits) fs/proc: fix softlockup in __read_vmcore nilfs2: convert BUG_ON() in nilfs_finish_roll_forward() to WARN_ON() scripts: checkpatch: check unused parameters for function-like macro Documentation: coding-style: ask function-like macros to evaluate parameters nilfs2: use __field_struct() for a bitwise field selftests/kcmp: remove unused open mode nilfs2: remove calls to folio_set_error() and folio_clear_error() kernel/watchdog_perf.c: tidy up kerneldoc watchdog: allow nmi watchdog to use raw perf event watchdog: handle comma separated nmi_watchdog command line nilfs2: make superblock data array index computation sparse friendly squashfs: remove calls to set the folio error flag squashfs: convert squashfs_symlink_read_folio to use folio APIs scripts/gdb: fix detection of current CPU in KGDB scripts/gdb: make get_thread_info accept pointers scripts/gdb: fix parameter handling in $lx_per_cpu scripts/gdb: fix failing KGDB detection during probe kfifo: don't use "proxy" headers media: stih-cec: add missing io.h media: rc: add missing io.h ...
Unified · Split
| @@ -136,10 +136,6 @@ System kernel config options · 135 unmodified lines | |||
| 136 | 136 | ||
| 137 | CONFIG_KEXEC_CORE=y | 137 | CONFIG_KEXEC_CORE=y |
| 138 | 138 | ||
| 139 | Subsequently, CRASH_CORE is selected by KEXEC_CORE:: | ||
| 140 | |||
| 141 | CONFIG_CRASH_CORE=y | ||
| 142 | |||
| 143 | 2) Enable "sysfs file system support" in "Filesystem" -> "Pseudo | 139 | 2) Enable "sysfs file system support" in "Filesystem" -> "Pseudo |
| 144 | filesystems." This is usually enabled by default:: | 140 | filesystems." This is usually enabled by default:: |
| 145 | 141 | ||
| @@ -168,6 +164,10 @@ Dump-capture kernel config options (Arch Independent) · 22 unmodified lines | |||
| 168 | 164 | ||
| 169 | CONFIG_CRASH_DUMP=y | 165 | CONFIG_CRASH_DUMP=y |
| 170 | 166 | ||
| 167 | And this will select VMCORE_INFO and CRASH_RESERVE:: | ||
| 168 | CONFIG_VMCORE_INFO=y | ||
| 169 | CONFIG_CRASH_RESERVE=y | ||
| 170 | |||
| 171 | 2) Enable "/proc/vmcore support" under "Filesystems" -> "Pseudo filesystems":: | 171 | 2) Enable "/proc/vmcore support" under "Filesystems" -> "Pseudo filesystems":: |
| 172 | 172 | ||
| 173 | CONFIG_PROC_VMCORE=y | 173 | CONFIG_PROC_VMCORE=y |
| @@ -3787,10 +3787,12 @@ · 3786 unmodified lines | |||
| 3787 | Format: [state][,regs][,debounce][,die] | 3787 | Format: [state][,regs][,debounce][,die] |
| 3788 | 3788 | ||
| 3789 | nmi_watchdog= [KNL,BUGS=X86] Debugging features for SMP kernels | 3789 | nmi_watchdog= [KNL,BUGS=X86] Debugging features for SMP kernels |
| 3790 | Format: [panic,][nopanic,][num] | 3790 | Format: [panic,][nopanic,][rNNN,][num] |
| 3791 | Valid num: 0 or 1 | 3791 | Valid num: 0 or 1 |
| 3792 | 0 - turn hardlockup detector in nmi_watchdog off | 3792 | 0 - turn hardlockup detector in nmi_watchdog off |
| 3793 | 1 - turn hardlockup detector in nmi_watchdog on | 3793 | 1 - turn hardlockup detector in nmi_watchdog on |
| 3794 | rNNN - configure the watchdog with raw perf event 0xNNN | ||
| 3795 | |||
| 3794 | When panic is specified, panic when an NMI watchdog | 3796 | When panic is specified, panic when an NMI watchdog |
| 3795 | timeout occurs (or 'nopanic' to not panic on an NMI | 3797 | timeout occurs (or 'nopanic' to not panic on an NMI |
| 3796 | watchdog, if CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is set) | 3798 | watchdog, if CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is set) |
| @@ -7507,4 +7509,3 @@ · 3710 unmodified lines | |||
| 7507 | memory, and other data can't be written using | 7509 | memory, and other data can't be written using |
| 7508 | xmon commands. | 7510 | xmon commands. |
| 7509 | off xmon is disabled. | 7511 | off xmon is disabled. |
| 7510 | |||
| @@ -906,6 +906,20 @@ Macros, Attributes and Symbols · 905 unmodified lines | |||
| 906 | 906 | ||
| 907 | See: https://lore.kernel.org/lkml/1399671106.2912.21.camel@joe-AO725/ | 907 | See: https://lore.kernel.org/lkml/1399671106.2912.21.camel@joe-AO725/ |
| 908 | 908 | ||
| 909 | **MACRO_ARG_UNUSED** | ||
| 910 | If function-like macros do not utilize a parameter, it might result | ||
| 911 | in a build warning. We advocate for utilizing static inline functions | ||
| 912 | to replace such macros. | ||
| 913 | For example, for a macro such as the one below:: | ||
| 914 | |||
| 915 | #define test(a) do { } while (0) | ||
| 916 | |||
| 917 | there would be a warning like below:: | ||
| 918 | |||
| 919 | WARNING: Argument 'a' is not used in function-like macro. | ||
| 920 | |||
| 921 | See: https://www.kernel.org/doc/html/latest/process/coding-style.html#macros-enums-and-rtl | ||
| 922 | |||
| 909 | **SINGLE_STATEMENT_DO_WHILE_MACRO** | 923 | **SINGLE_STATEMENT_DO_WHILE_MACRO** |
| 910 | For the multi-statement macros, it is necessary to use the do-while | 924 | For the multi-statement macros, it is necessary to use the do-while |
| 911 | loop to avoid unpredictable code paths. The do-while loop helps to | 925 | loop to avoid unpredictable code paths. The do-while loop helps to |
| @@ -827,6 +827,29 @@ Macros with multiple statements should be enclosed in a do - while block: · 826 unmodified lines | |||
| 827 | do_this(b, c); \ | 827 | do_this(b, c); \ |
| 828 | } while (0) | 828 | } while (0) |
| 829 | 829 | ||
| 830 | Function-like macros with unused parameters should be replaced by static | ||
| 831 | inline functions to avoid the issue of unused variables: | ||
| 832 | |||
| 833 | .. code-block:: c | ||
| 834 | |||
| 835 | static inline void fun(struct foo *foo) | ||
| 836 | { | ||
| 837 | } | ||
| 838 | |||
| 839 | Due to historical practices, many files still employ the "cast to (void)" | ||
| 840 | approach to evaluate parameters. However, this method is not advisable. | ||
| 841 | Inline functions address the issue of "expression with side effects | ||
| 842 | evaluated more than once", circumvent unused-variable problems, and | ||
| 843 | are generally better documented than macros for some reason. | ||
| 844 | |||
| 845 | .. code-block:: c | ||
| 846 | |||
| 847 | /* | ||
| 848 | * Avoid doing this whenever possible and instead opt for static | ||
| 849 | * inline functions | ||
| 850 | */ | ||
| 851 | #define macrofun(foo) do { (void) (foo); } while (0) | ||
| 852 | |||
| 830 | Things to avoid when using macros: | 853 | Things to avoid when using macros: |
| 831 | 854 | ||
| 832 | 1) macros that affect control flow: | 855 | 1) macros that affect control flow: |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | #include <linux/jump_label.h> | 4 | #include <linux/jump_label.h> |
| 5 | #include <linux/uaccess.h> | 5 | #include <linux/uaccess.h> |
| 6 | #include <linux/export.h> | 6 | #include <linux/export.h> |
| 7 | #include <linux/instrumented.h> | ||
| 7 | #include <linux/string.h> | 8 | #include <linux/string.h> |
| 8 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| 9 | 10 | ||
| @@ -61,10 +62,20 @@ unsigned long copy_mc_enhanced_fast_string(void *dst, const void *src, unsigned · 51 unmodified lines | |||
| 61 | */ | 62 | */ |
| 62 | unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigned len) | 63 | unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigned len) |
| 63 | { | 64 | { |
| 64 | if (copy_mc_fragile_enabled) | 65 | unsigned long ret; |
| 65 | return copy_mc_fragile(dst, src, len); | 66 | |
| 66 | if (static_cpu_has(X86_FEATURE_ERMS)) | 67 | if (copy_mc_fragile_enabled) { |
| 67 | return copy_mc_enhanced_fast_string(dst, src, len); | 68 | instrument_memcpy_before(dst, src, len); |
| 69 | ret = copy_mc_fragile(dst, src, len); | ||
| 70 | instrument_memcpy_after(dst, src, len, ret); | ||
| 71 | return ret; | ||
| 72 | } | ||
| 73 | if (static_cpu_has(X86_FEATURE_ERMS)) { | ||
| 74 | instrument_memcpy_before(dst, src, len); | ||
| 75 | ret = copy_mc_enhanced_fast_string(dst, src, len); | ||
| 76 | instrument_memcpy_after(dst, src, len, ret); | ||
| 77 | return ret; | ||
| 78 | } | ||
| 68 | memcpy(dst, src, len); | 79 | memcpy(dst, src, len); |
| 69 | return 0; | 80 | return 0; |
| 70 | } | 81 | } |
| @@ -75,6 +86,7 @@ unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, un · 4 unmodified lines | |||
| 75 | unsigned long ret; | 86 | unsigned long ret; |
| 76 | 87 | ||
| 77 | if (copy_mc_fragile_enabled) { | 88 | if (copy_mc_fragile_enabled) { |
| 89 | instrument_copy_to_user(dst, src, len); | ||
| 78 | __uaccess_begin(); | 90 | __uaccess_begin(); |
| 79 | ret = copy_mc_fragile((__force void *)dst, src, len); | 91 | ret = copy_mc_fragile((__force void *)dst, src, len); |
| 80 | __uaccess_end(); | 92 | __uaccess_end(); |
| @@ -82,6 +94,7 @@ unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, un · 1 unmodified line | |||
| 82 | } | 94 | } |
| 83 | 95 | ||
| 84 | if (static_cpu_has(X86_FEATURE_ERMS)) { | 96 | if (static_cpu_has(X86_FEATURE_ERMS)) { |
| 97 | instrument_copy_to_user(dst, src, len); | ||
| 85 | __uaccess_begin(); | 98 | __uaccess_begin(); |
| 86 | ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); | 99 | ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); |
| 87 | __uaccess_end(); | 100 | __uaccess_end(); |
| @@ -131,8 +131,7 @@ static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc) · 130 unmodified lines | |||
| 131 | ldm_crit ("Cannot find TOCBLOCK, database may be corrupt."); | 131 | ldm_crit ("Cannot find TOCBLOCK, database may be corrupt."); |
| 132 | return false; | 132 | return false; |
| 133 | } | 133 | } |
| 134 | strncpy (toc->bitmap1_name, data + 0x24, sizeof (toc->bitmap1_name)); | 134 | strscpy_pad(toc->bitmap1_name, data + 0x24, sizeof(toc->bitmap1_name)); |
| 135 | toc->bitmap1_name[sizeof (toc->bitmap1_name) - 1] = 0; | ||
| 136 | toc->bitmap1_start = get_unaligned_be64(data + 0x2E); | 135 | toc->bitmap1_start = get_unaligned_be64(data + 0x2E); |
| 137 | toc->bitmap1_size = get_unaligned_be64(data + 0x36); | 136 | toc->bitmap1_size = get_unaligned_be64(data + 0x36); |
| 138 | 137 | ||
| @@ -142,8 +141,7 @@ static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc) · 3 unmodified lines | |||
| 142 | TOC_BITMAP1, toc->bitmap1_name); | 141 | TOC_BITMAP1, toc->bitmap1_name); |
| 143 | return false; | 142 | return false; |
| 144 | } | 143 | } |
| 145 | strncpy (toc->bitmap2_name, data + 0x46, sizeof (toc->bitmap2_name)); | 144 | strscpy_pad(toc->bitmap2_name, data + 0x46, sizeof(toc->bitmap2_name)); |
| 146 | toc->bitmap2_name[sizeof (toc->bitmap2_name) - 1] = 0; | ||
| 147 | toc->bitmap2_start = get_unaligned_be64(data + 0x50); | 145 | toc->bitmap2_start = get_unaligned_be64(data + 0x50); |
| 148 | toc->bitmap2_size = get_unaligned_be64(data + 0x58); | 146 | toc->bitmap2_size = get_unaligned_be64(data + 0x58); |
| 149 | if (strncmp (toc->bitmap2_name, TOC_BITMAP2, | 147 | if (strncmp (toc->bitmap2_name, TOC_BITMAP2, |
| @@ -871,7 +871,7 @@ intel_th_alloc(struct device *dev, const struct intel_th_drvdata *drvdata, · 870 unmodified lines | |||
| 871 | if (!th) | 871 | if (!th) |
| 872 | return ERR_PTR(-ENOMEM); | 872 | return ERR_PTR(-ENOMEM); |
| 873 | 873 | ||
| 874 | th->id = ida_simple_get(&intel_th_ida, 0, 0, GFP_KERNEL); | 874 | th->id = ida_alloc(&intel_th_ida, GFP_KERNEL); |
| 875 | if (th->id < 0) { | 875 | if (th->id < 0) { |
| 876 | err = th->id; | 876 | err = th->id; |
| 877 | goto err_alloc; | 877 | goto err_alloc; |
| @@ -931,7 +931,7 @@ err_chrdev: · 53 unmodified lines | |||
| 931 | "intel_th/output"); | 931 | "intel_th/output"); |
| 932 | 932 | ||
| 933 | err_ida: | 933 | err_ida: |
| 934 | ida_simple_remove(&intel_th_ida, th->id); | 934 | ida_free(&intel_th_ida, th->id); |
| 935 | 935 | ||
| 936 | err_alloc: | 936 | err_alloc: |
| 937 | kfree(th); | 937 | kfree(th); |
| @@ -964,7 +964,7 @@ void intel_th_free(struct intel_th *th) · 26 unmodified lines | |||
| 964 | __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, | 964 | __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, |
| 965 | "intel_th/output"); | 965 | "intel_th/output"); |
| 966 | 966 | ||
| 967 | ida_simple_remove(&intel_th_ida, th->id); | 967 | ida_free(&intel_th_ida, th->id); |
| 968 | 968 | ||
| 969 | kfree(th); | 969 | kfree(th); |
| 970 | } | 970 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | */ | 6 | */ |
| 7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| 8 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
| 9 | #include <linux/io.h> | ||
| 9 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 10 | #include <linux/mfd/syscon.h> | 11 | #include <linux/mfd/syscon.h> |
| 11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
| 9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/io.h> | ||
| 11 | #include <linux/of.h> | 12 | #include <linux/of.h> |
| 12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 13 | #include <linux/reset.h> | 14 | #include <linux/reset.h> |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/io.h> | ||
| 21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 22 | #include <linux/serial_reg.h> | 23 | #include <linux/serial_reg.h> |
| 23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| 8 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
| 9 | #include <linux/io.h> | ||
| 9 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 10 | #include <linux/of.h> | 11 | #include <linux/of.h> |
| 11 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
| 14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 15 | #include <linux/io.h> | ||
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| @@ -64,7 +64,7 @@ static void mux_chip_release(struct device *dev) · 63 unmodified lines | |||
| 64 | { | 64 | { |
| 65 | struct mux_chip *mux_chip = to_mux_chip(dev); | 65 | struct mux_chip *mux_chip = to_mux_chip(dev); |
| 66 | 66 | ||
| 67 | ida_simple_remove(&mux_ida, mux_chip->id); | 67 | ida_free(&mux_ida, mux_chip->id); |
| 68 | kfree(mux_chip); | 68 | kfree(mux_chip); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| @@ -111,7 +111,7 @@ struct mux_chip *mux_chip_alloc(struct device *dev, · 40 unmodified lines | |||
| 111 | mux_chip->dev.of_node = dev->of_node; | 111 | mux_chip->dev.of_node = dev->of_node; |
| 112 | dev_set_drvdata(&mux_chip->dev, mux_chip); | 112 | dev_set_drvdata(&mux_chip->dev, mux_chip); |
| 113 | 113 | ||
| 114 | mux_chip->id = ida_simple_get(&mux_ida, 0, 0, GFP_KERNEL); | 114 | mux_chip->id = ida_alloc(&mux_ida, GFP_KERNEL); |
| 115 | if (mux_chip->id < 0) { | 115 | if (mux_chip->id < 0) { |
| 116 | int err = mux_chip->id; | 116 | int err = mux_chip->id; |
| 117 | 117 | ||
| @@ -148,7 +148,7 @@ static void parport_attach(struct parport *port) · 147 unmodified lines | |||
| 148 | return; | 148 | return; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | index = ida_simple_get(&pps_client_index, 0, 0, GFP_KERNEL); | 151 | index = ida_alloc(&pps_client_index, GFP_KERNEL); |
| 152 | memset(&pps_client_cb, 0, sizeof(pps_client_cb)); | 152 | memset(&pps_client_cb, 0, sizeof(pps_client_cb)); |
| 153 | pps_client_cb.private = device; | 153 | pps_client_cb.private = device; |
| 154 | pps_client_cb.irq_func = parport_irq; | 154 | pps_client_cb.irq_func = parport_irq; |
| @@ -188,7 +188,7 @@ err_release_dev: · 33 unmodified lines | |||
| 188 | err_unregister_dev: | 188 | err_unregister_dev: |
| 189 | parport_unregister_device(device->pardev); | 189 | parport_unregister_device(device->pardev); |
| 190 | err_free: | 190 | err_free: |
| 191 | ida_simple_remove(&pps_client_index, index); | 191 | ida_free(&pps_client_index, index); |
| 192 | kfree(device); | 192 | kfree(device); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| @@ -208,7 +208,7 @@ static void parport_detach(struct parport *port) · 13 unmodified lines | |||
| 208 | pps_unregister_source(device->pps); | 208 | pps_unregister_source(device->pps); |
| 209 | parport_release(pardev); | 209 | parport_release(pardev); |
| 210 | parport_unregister_device(pardev); | 210 | parport_unregister_device(pardev); |
| 211 | ida_simple_remove(&pps_client_index, device->index); | 211 | ida_free(&pps_client_index, device->index); |
| 212 | kfree(device); | 212 | kfree(device); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| @@ -1934,7 +1934,7 @@ static void free_note_info(struct elf_note_info *info) · 1933 unmodified lines | |||
| 1934 | threads = t->next; | 1934 | threads = t->next; |
| 1935 | WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus); | 1935 | WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus); |
| 1936 | for (i = 1; i < info->thread_notes; ++i) | 1936 | for (i = 1; i < info->thread_notes; ++i) |
| 1937 | kfree(t->notes[i].data); | 1937 | kvfree(t->notes[i].data); |
| 1938 | kfree(t); | 1938 | kfree(t); |
| 1939 | } | 1939 | } |
| 1940 | kfree(info->psinfo.data); | 1940 | kfree(info->psinfo.data); |
| @@ -269,6 +269,18 @@ enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, }; · 268 unmodified lines | |||
| 269 | /** | 269 | /** |
| 270 | * fat_parse_long - Parse extended directory entry. | 270 | * fat_parse_long - Parse extended directory entry. |
| 271 | * | 271 | * |
| 272 | * @dir: Pointer to the inode that represents the directory. | ||
| 273 | * @pos: On input, contains the starting position to read from. | ||
| 274 | * On output, updated with the new position. | ||
| 275 | * @bh: Pointer to the buffer head that may be used for reading directory | ||
| 276 | * entries. May be updated. | ||
| 277 | * @de: On input, points to the current directory entry. | ||
| 278 | * On output, points to the next directory entry. | ||
| 279 | * @unicode: Pointer to a buffer where the parsed Unicode long filename will be | ||
| 280 | * stored. | ||
| 281 | * @nr_slots: Pointer to a variable that will store the number of longname | ||
| 282 | * slots found. | ||
| 283 | * | ||
| 272 | * This function returns zero on success, negative value on error, or one of | 284 | * This function returns zero on success, negative value on error, or one of |
| 273 | * the following: | 285 | * the following: |
| 274 | * | 286 | * |
| @@ -1857,13 +1857,22 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *btree, · 1856 unmodified lines | |||
| 1857 | } | 1857 | } |
| 1858 | 1858 | ||
| 1859 | /** | 1859 | /** |
| 1860 | * nilfs_btree_convert_and_insert - | 1860 | * nilfs_btree_convert_and_insert - Convert and insert entries into a B-tree |
| 1861 | * @bmap: | 1861 | * @btree: NILFS B-tree structure |
| 1862 | * @key: | 1862 | * @key: Key of the new entry to be inserted |
| 1863 | * @ptr: | 1863 | * @ptr: Pointer (block number) associated with the key to be inserted |
| 1864 | * @keys: | 1864 | * @keys: Array of keys to be inserted in addition to @key |
| 1865 | * @ptrs: | 1865 | * @ptrs: Array of pointers associated with @keys |
| 1866 | * @n: | 1866 | * @n: Number of keys and pointers in @keys and @ptrs |
| 1867 | * | ||
| 1868 | * This function is used to insert a new entry specified by @key and @ptr, | ||
| 1869 | * along with additional entries specified by @keys and @ptrs arrays, into a | ||
| 1870 | * NILFS B-tree. | ||
| 1871 | * It prepares the necessary changes by allocating the required blocks and any | ||
| 1872 | * necessary intermediate nodes. It converts configurations from other forms of | ||
| 1873 | * block mapping (the one that currently exists is direct mapping) to a B-tree. | ||
| 1874 | * | ||
| 1875 | * Return: 0 on success or a negative error code on failure. | ||
| 1867 | */ | 1876 | */ |
| 1868 | int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree, | 1877 | int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree, |
| 1869 | __u64 key, __u64 ptr, | 1878 | __u64 key, __u64 ptr, |
| @@ -174,7 +174,6 @@ Eend: · 173 unmodified lines | |||
| 174 | dir->i_ino, (folio->index << PAGE_SHIFT) + offs, | 174 | dir->i_ino, (folio->index << PAGE_SHIFT) + offs, |
| 175 | (unsigned long)le64_to_cpu(p->inode)); | 175 | (unsigned long)le64_to_cpu(p->inode)); |
| 176 | fail: | 176 | fail: |
| 177 | folio_set_error(folio); | ||
| 178 | return false; | 177 | return false; |
| 179 | } | 178 | } |
| 180 | 179 | ||
| @@ -175,6 +175,7 @@ int nilfs_init_gcinode(struct inode *inode) · 174 unmodified lines | |||
| 175 | 175 | ||
| 176 | /** | 176 | /** |
| 177 | * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes | 177 | * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes |
| 178 | * @nilfs: NILFS filesystem instance | ||
| 178 | */ | 179 | */ |
| 179 | void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) | 180 | void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) |
| 180 | { | 181 | { |
| @@ -335,8 +335,8 @@ void __nilfs_error(struct super_block *sb, const char *function, · 334 unmodified lines | |||
| 335 | 335 | ||
| 336 | extern struct nilfs_super_block * | 336 | extern struct nilfs_super_block * |
| 337 | nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **); | 337 | nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **); |
| 338 | extern int nilfs_store_magic_and_option(struct super_block *, | 338 | extern int nilfs_store_magic(struct super_block *sb, |
| 339 | struct nilfs_super_block *, char *); | 339 | struct nilfs_super_block *sbp); |
| 340 | extern int nilfs_check_feature_compatibility(struct super_block *, | 340 | extern int nilfs_check_feature_compatibility(struct super_block *, |
| 341 | struct nilfs_super_block *); | 341 | struct nilfs_super_block *); |
| 342 | extern void nilfs_set_log_cursor(struct nilfs_super_block *, | 342 | extern void nilfs_set_log_cursor(struct nilfs_super_block *, |
| @@ -563,6 +563,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, · 562 unmodified lines | |||
| 563 | * checkpoint | 563 | * checkpoint |
| 564 | * @nilfs: nilfs object | 564 | * @nilfs: nilfs object |
| 565 | * @sb: super block instance | 565 | * @sb: super block instance |
| 566 | * @root: NILFS root instance | ||
| 566 | * @ri: pointer to a nilfs_recovery_info | 567 | * @ri: pointer to a nilfs_recovery_info |
| 567 | */ | 568 | */ |
| 568 | static int nilfs_do_roll_forward(struct the_nilfs *nilfs, | 569 | static int nilfs_do_roll_forward(struct the_nilfs *nilfs, |
| @@ -698,7 +699,9 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, · 129 unmodified lines | |||
| 698 | return; | 699 | return; |
| 699 | 700 | ||
| 700 | bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize); | 701 | bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize); |
| 701 | BUG_ON(!bh); | 702 | if (WARN_ON(!bh)) |
| 703 | return; /* should never happen */ | ||
| 704 | |||
| 702 | memset(bh->b_data, 0, bh->b_size); | 705 | memset(bh->b_data, 0, bh->b_size); |
| 703 | set_buffer_dirty(bh); | 706 | set_buffer_dirty(bh); |
| 704 | err = sync_dirty_buffer(bh); | 707 | err = sync_dirty_buffer(bh); |
| @@ -1725,14 +1725,8 @@ static void nilfs_end_folio_io(struct folio *folio, int err) · 1724 unmodified lines | |||
| 1725 | return; | 1725 | return; |
| 1726 | } | 1726 | } |
| 1727 | 1727 | ||
| 1728 | if (!err) { | 1728 | if (err || !nilfs_folio_buffers_clean(folio)) |
| 1729 | if (!nilfs_folio_buffers_clean(folio)) | ||
| 1730 | filemap_dirty_folio(folio->mapping, folio); | ||
| 1731 | folio_clear_error(folio); | ||
| 1732 | } else { | ||
| 1733 | filemap_dirty_folio(folio->mapping, folio); | 1729 | filemap_dirty_folio(folio->mapping, folio); |
| 1734 | folio_set_error(folio); | ||
| 1735 | } | ||
| 1736 | 1730 | ||
| 1737 | folio_end_writeback(folio); | 1731 | folio_end_writeback(folio); |
| 1738 | } | 1732 | } |
| @@ -29,13 +29,13 @@ · 28 unmodified lines | |||
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
| 32 | #include <linux/parser.h> | ||
| 33 | #include <linux/crc32.h> | 32 | #include <linux/crc32.h> |
| 34 | #include <linux/vfs.h> | 33 | #include <linux/vfs.h> |
| 35 | #include <linux/writeback.h> | 34 | #include <linux/writeback.h> |
| 36 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
| 37 | #include <linux/mount.h> | 36 | #include <linux/mount.h> |
| 38 | #include <linux/fs_context.h> | 37 | #include <linux/fs_context.h> |
| 38 | #include <linux/fs_parser.h> | ||
| 39 | #include "nilfs.h" | 39 | #include "nilfs.h" |
| 40 | #include "export.h" | 40 | #include "export.h" |
| 41 | #include "mdt.h" | 41 | #include "mdt.h" |
| @@ -61,7 +61,6 @@ struct kmem_cache *nilfs_segbuf_cachep; · 19 unmodified lines | |||
| 61 | struct kmem_cache *nilfs_btree_path_cache; | 61 | struct kmem_cache *nilfs_btree_path_cache; |
| 62 | 62 | ||
| 63 | static int nilfs_setup_super(struct super_block *sb, int is_mount); | 63 | static int nilfs_setup_super(struct super_block *sb, int is_mount); |
| 64 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); | ||
| 65 | 64 | ||
| 66 | void __nilfs_msg(struct super_block *sb, const char *fmt, ...) | 65 | void __nilfs_msg(struct super_block *sb, const char *fmt, ...) |
| 67 | { | 66 | { |
| @@ -702,105 +701,98 @@ static const struct super_operations nilfs_sops = { · 634 unmodified lines | |||
| 702 | .freeze_fs = nilfs_freeze, | 701 | .freeze_fs = nilfs_freeze, |
| 703 | .unfreeze_fs = nilfs_unfreeze, | 702 | .unfreeze_fs = nilfs_unfreeze, |
| 704 | .statfs = nilfs_statfs, | 703 | .statfs = nilfs_statfs, |
| 705 | .remount_fs = nilfs_remount, | ||
| 706 | .show_options = nilfs_show_options | 704 | .show_options = nilfs_show_options |
| 707 | }; | 705 | }; |
| 708 | 706 | ||
| 709 | enum { | 707 | enum { |
| 710 | Opt_err_cont, Opt_err_panic, Opt_err_ro, | 708 | Opt_err, Opt_barrier, Opt_snapshot, Opt_order, Opt_norecovery, |
| 711 | Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, | 709 | Opt_discard, |
| 712 | Opt_discard, Opt_nodiscard, Opt_err, | ||
| 713 | }; | 710 | }; |
| 714 | 711 | ||
| 715 | static match_table_t tokens = { | 712 | static const struct constant_table nilfs_param_err[] = { |
| 716 | {Opt_err_cont, "errors=continue"}, | 713 | {"continue", NILFS_MOUNT_ERRORS_CONT}, |
| 717 | {Opt_err_panic, "errors=panic"}, | 714 | {"panic", NILFS_MOUNT_ERRORS_PANIC}, |
| 718 | {Opt_err_ro, "errors=remount-ro"}, | 715 | {"remount-ro", NILFS_MOUNT_ERRORS_RO}, |
| 719 | {Opt_barrier, "barrier"}, | 716 | {} |
| 720 | {Opt_nobarrier, "nobarrier"}, | ||
| 721 | {Opt_snapshot, "cp=%u"}, | ||
| 722 | {Opt_order, "order=%s"}, | ||
| 723 | {Opt_norecovery, "norecovery"}, | ||
| 724 | {Opt_discard, "discard"}, | ||
| 725 | {Opt_nodiscard, "nodiscard"}, | ||
| 726 | {Opt_err, NULL} | ||
| 727 | }; | 717 | }; |
| 728 | 718 | ||
| 729 | static int parse_options(char *options, struct super_block *sb, int is_remount) | 719 | static const struct fs_parameter_spec nilfs_param_spec[] = { |
| 730 | { | 720 | fsparam_enum ("errors", Opt_err, nilfs_param_err), |
| 731 | struct the_nilfs *nilfs = sb->s_fs_info; | 721 | fsparam_flag_no ("barrier", Opt_barrier), |
| 732 | char *p; | 722 | fsparam_u64 ("cp", Opt_snapshot), |
| 733 | substring_t args[MAX_OPT_ARGS]; | 723 | fsparam_string ("order", Opt_order), |
| 734 | 724 | fsparam_flag ("norecovery", Opt_norecovery), | |
| 735 | if (!options) | 725 | fsparam_flag_no ("discard", Opt_discard), |
| 736 | return 1; | 726 | {} |
| 737 | 727 | }; | |
| 738 | while ((p = strsep(&options, ",")) != NULL) { | ||
| 739 | int token; | ||
| 740 | 728 | ||
| 741 | if (!*p) | 729 | struct nilfs_fs_context { |
| 742 | continue; | 730 | unsigned long ns_mount_opt; |
| 731 | __u64 cno; | ||
| 732 | }; | ||
| 743 | 733 | ||
| 744 | token = match_token(p, tokens, args); | 734 | static int nilfs_parse_param(struct fs_context *fc, struct fs_parameter *param) |
| 745 | switch (token) { | 735 | { |
| 746 | case Opt_barrier: | 736 | struct nilfs_fs_context *nilfs = fc->fs_private; |
| 747 | nilfs_set_opt(nilfs, BARRIER); | 737 | int is_remount = fc->purpose == FS_CONTEXT_FOR_RECONFIGURE; |
| 748 | break; | 738 | struct fs_parse_result result; |
| 749 | case Opt_nobarrier: | 739 | int opt; |
| 740 | |||
| 741 | opt = fs_parse(fc, nilfs_param_spec, param, &result); | ||
| 742 | if (opt < 0) | ||
| 743 | return opt; | ||
| 744 | |||
| 745 | switch (opt) { | ||
| 746 | case Opt_barrier: | ||
| 747 | if (result.negated) | ||
| 750 | nilfs_clear_opt(nilfs, BARRIER); | 748 | nilfs_clear_opt(nilfs, BARRIER); |
| 751 | break; | 749 | else |
| 752 | case Opt_order: | 750 | nilfs_set_opt(nilfs, BARRIER); |
| 753 | if (strcmp(args[0].from, "relaxed") == 0) | 751 | break; |
| 754 | /* Ordered data semantics */ | 752 | case Opt_order: |
| 755 | nilfs_clear_opt(nilfs, STRICT_ORDER); | 753 | if (strcmp(param->string, "relaxed") == 0) |
| 756 | else if (strcmp(args[0].from, "strict") == 0) | 754 | /* Ordered data semantics */ |
| 757 | /* Strict in-order semantics */ | 755 | nilfs_clear_opt(nilfs, STRICT_ORDER); |
| 758 | nilfs_set_opt(nilfs, STRICT_ORDER); | 756 | else if (strcmp(param->string, "strict") == 0) |
| 759 | else | 757 | /* Strict in-order semantics */ |
| 760 | return 0; | 758 | nilfs_set_opt(nilfs, STRICT_ORDER); |
| 761 | break; | 759 | else |
| 762 | case Opt_err_panic: | 760 | return -EINVAL; |
| 763 | nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_PANIC); | 761 | break; |
| 764 | break; | 762 | case Opt_err: |
| 765 | case Opt_err_ro: | 763 | nilfs->ns_mount_opt &= ~NILFS_MOUNT_ERROR_MODE; |
| 766 | nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_RO); | 764 | nilfs->ns_mount_opt |= result.uint_32; |
| 767 | break; | 765 | break; |
| 768 | case Opt_err_cont: | 766 | case Opt_snapshot: |
| 769 | nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_CONT); | 767 | if (is_remount) { |
| 770 | break; | 768 | struct super_block *sb = fc->root->d_sb; |
| 771 | case Opt_snapshot: | 769 | |
| 772 | if (is_remount) { | 770 | nilfs_err(sb, |
| 773 | nilfs_err(sb, | 771 | "\"%s\" option is invalid for remount", |
| 774 | "\"%s\" option is invalid for remount", | 772 | param->key); |
| 775 | p); | 773 | return -EINVAL; |
| 776 | return 0; | 774 | } |
| 777 | } | 775 | if (result.uint_64 == 0) { |
| 778 | break; | 776 | nilfs_err(NULL, |
| 779 | case Opt_norecovery: | 777 | "invalid option \"cp=0\": invalid checkpoint number 0"); |
| 780 | nilfs_set_opt(nilfs, NORECOVERY); | 778 | return -EINVAL; |
| 781 | break; | ||
| 782 | case Opt_discard: | ||
| 783 | nilfs_set_opt(nilfs, DISCARD); | ||
| 784 | break; | ||
| 785 | case Opt_nodiscard: | ||
| 786 | nilfs_clear_opt(nilfs, DISCARD); | ||
| 787 | break; | ||
| 788 | default: | ||
| 789 | nilfs_err(sb, "unrecognized mount option \"%s\"", p); | ||
| 790 | return 0; | ||
| 791 | } | 779 | } |
| 780 | nilfs->cno = result.uint_64; | ||
| 781 | break; | ||
| 782 | case Opt_norecovery: | ||
| 783 | nilfs_set_opt(nilfs, NORECOVERY); | ||
| 784 | break; | ||
| 785 | case Opt_discard: | ||
| 786 | if (result.negated) | ||
| 787 | nilfs_clear_opt(nilfs, DISCARD); | ||
| 788 | else | ||
| 789 | nilfs_set_opt(nilfs, DISCARD); | ||
| 790 | break; | ||
| 791 | default: | ||
| 792 | return -EINVAL; | ||
| 792 | } | 793 | } |
| 793 | return 1; | ||
| 794 | } | ||
| 795 | |||
| 796 | static inline void | ||
| 797 | nilfs_set_default_options(struct super_block *sb, | ||
| 798 | struct nilfs_super_block *sbp) | ||
| 799 | { | ||
| 800 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
| 801 | 794 | ||
| 802 | nilfs->ns_mount_opt = | 795 | return 0; |
| 803 | NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER; | ||
| 804 | } | 796 | } |
| 805 | 797 | ||
| 806 | static int nilfs_setup_super(struct super_block *sb, int is_mount) | 798 | static int nilfs_setup_super(struct super_block *sb, int is_mount) |
| @@ -857,9 +849,8 @@ struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb, · 50 unmodified lines | |||
| 857 | return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset); | 849 | return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset); |
| 858 | } | 850 | } |
| 859 | 851 | ||
| 860 | int nilfs_store_magic_and_option(struct super_block *sb, | 852 | int nilfs_store_magic(struct super_block *sb, |
| 861 | struct nilfs_super_block *sbp, | 853 | struct nilfs_super_block *sbp) |
| 862 | char *data) | ||
| 863 | { | 854 | { |
| 864 | struct the_nilfs *nilfs = sb->s_fs_info; | 855 | struct the_nilfs *nilfs = sb->s_fs_info; |
| 865 | 856 | ||
| @@ -870,14 +861,12 @@ int nilfs_store_magic_and_option(struct super_block *sb, · 4 unmodified lines | |||
| 870 | sb->s_flags |= SB_NOATIME; | 861 | sb->s_flags |= SB_NOATIME; |
| 871 | #endif | 862 | #endif |
| 872 | 863 | ||
| 873 | nilfs_set_default_options(sb, sbp); | ||
| 874 | |||
| 875 | nilfs->ns_resuid = le16_to_cpu(sbp->s_def_resuid); | 864 | nilfs->ns_resuid = le16_to_cpu(sbp->s_def_resuid); |
| 876 | nilfs->ns_resgid = le16_to_cpu(sbp->s_def_resgid); | 865 | nilfs->ns_resgid = le16_to_cpu(sbp->s_def_resgid); |
| 877 | nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); | 866 | nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); |
| 878 | nilfs->ns_watermark = le32_to_cpu(sbp->s_c_block_max); | 867 | nilfs->ns_watermark = le32_to_cpu(sbp->s_c_block_max); |
| 879 | 868 | ||
| 880 | return !parse_options(data, sb, 0) ? -EINVAL : 0; | 869 | return 0; |
| 881 | } | 870 | } |
| 882 | 871 | ||
| 883 | int nilfs_check_feature_compatibility(struct super_block *sb, | 872 | int nilfs_check_feature_compatibility(struct super_block *sb, |
| @@ -1035,17 +1024,17 @@ int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno) · 151 unmodified lines | |||
| 1035 | /** | 1024 | /** |
| 1036 | * nilfs_fill_super() - initialize a super block instance | 1025 | * nilfs_fill_super() - initialize a super block instance |
| 1037 | * @sb: super_block | 1026 | * @sb: super_block |
| 1038 | * @data: mount options | 1027 | * @fc: filesystem context |
| 1039 | * @silent: silent mode flag | ||
| 1040 | * | 1028 | * |
| 1041 | * This function is called exclusively by nilfs->ns_mount_mutex. | 1029 | * This function is called exclusively by nilfs->ns_mount_mutex. |
| 1042 | * So, the recovery process is protected from other simultaneous mounts. | 1030 | * So, the recovery process is protected from other simultaneous mounts. |
| 1043 | */ | 1031 | */ |
| 1044 | static int | 1032 | static int |
| 1045 | nilfs_fill_super(struct super_block *sb, void *data, int silent) | 1033 | nilfs_fill_super(struct super_block *sb, struct fs_context *fc) |
| 1046 | { | 1034 | { |
| 1047 | struct the_nilfs *nilfs; | 1035 | struct the_nilfs *nilfs; |
| 1048 | struct nilfs_root *fsroot; | 1036 | struct nilfs_root *fsroot; |
| 1037 | struct nilfs_fs_context *ctx = fc->fs_private; | ||
| 1049 | __u64 cno; | 1038 | __u64 cno; |
| 1050 | int err; | 1039 | int err; |
| 1051 | 1040 | ||
| @@ -1055,10 +1044,13 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) · 3 unmodified lines | |||
| 1055 | 1044 | ||
| 1056 | sb->s_fs_info = nilfs; | 1045 | sb->s_fs_info = nilfs; |
| 1057 | 1046 | ||
| 1058 | err = init_nilfs(nilfs, sb, (char *)data); | 1047 | err = init_nilfs(nilfs, sb); |
| 1059 | if (err) | 1048 | if (err) |
| 1060 | goto failed_nilfs; | 1049 | goto failed_nilfs; |
| 1061 | 1050 | ||
| 1051 | /* Copy in parsed mount options */ | ||
| 1052 | nilfs->ns_mount_opt = ctx->ns_mount_opt; | ||
| 1053 | |||
| 1062 | sb->s_op = &nilfs_sops; | 1054 | sb->s_op = &nilfs_sops; |
| 1063 | sb->s_export_op = &nilfs_export_ops; | 1055 | sb->s_export_op = &nilfs_export_ops; |
| 1064 | sb->s_root = NULL; | 1056 | sb->s_root = NULL; |
| @@ -1117,34 +1109,25 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) · 52 unmodified lines | |||
| 1117 | return err; | 1109 | return err; |
| 1118 | } | 1110 | } |
| 1119 | 1111 | ||
| 1120 | static int nilfs_remount(struct super_block *sb, int *flags, char *data) | 1112 | static int nilfs_reconfigure(struct fs_context *fc) |
| 1121 | { | 1113 | { |
| 1114 | struct nilfs_fs_context *ctx = fc->fs_private; | ||
| 1115 | struct super_block *sb = fc->root->d_sb; | ||
| 1122 | struct the_nilfs *nilfs = sb->s_fs_info; | 1116 | struct the_nilfs *nilfs = sb->s_fs_info; |
| 1123 | unsigned long old_sb_flags; | ||
| 1124 | unsigned long old_mount_opt; | ||
| 1125 | int err; | 1117 | int err; |
| 1126 | 1118 | ||
| 1127 | sync_filesystem(sb); | 1119 | sync_filesystem(sb); |
| 1128 | old_sb_flags = sb->s_flags; | ||
| 1129 | old_mount_opt = nilfs->ns_mount_opt; | ||
| 1130 | |||
| 1131 | if (!parse_options(data, sb, 1)) { | ||
| 1132 | err = -EINVAL; | ||
| 1133 | goto restore_opts; | ||
| 1134 | } | ||
| 1135 | sb->s_flags = (sb->s_flags & ~SB_POSIXACL); | ||
| 1136 | 1120 | ||
| 1137 | err = -EINVAL; | 1121 | err = -EINVAL; |
| 1138 | 1122 | ||
| 1139 | if (!nilfs_valid_fs(nilfs)) { | 1123 | if (!nilfs_valid_fs(nilfs)) { |
| 1140 | nilfs_warn(sb, | 1124 | nilfs_warn(sb, |
| 1141 | "couldn't remount because the filesystem is in an incomplete recovery state"); | 1125 | "couldn't remount because the filesystem is in an incomplete recovery state"); |
| 1142 | goto restore_opts; | 1126 | goto ignore_opts; |
| 1143 | } | 1127 | } |
| 1144 | 1128 | if ((bool)(fc->sb_flags & SB_RDONLY) == sb_rdonly(sb)) | |
| 1145 | if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) | ||
| 1146 | goto out; | 1129 | goto out; |
| 1147 | if (*flags & SB_RDONLY) { | 1130 | if (fc->sb_flags & SB_RDONLY) { |
| 1148 | sb->s_flags |= SB_RDONLY; | 1131 | sb->s_flags |= SB_RDONLY; |
| 1149 | 1132 | ||
| 1150 | /* | 1133 | /* |
| @@ -1172,138 +1155,67 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) · 21 unmodified lines | |||
| 1172 | "couldn't remount RDWR because of unsupported optional features (%llx)", | 1155 | "couldn't remount RDWR because of unsupported optional features (%llx)", |
| 1173 | (unsigned long long)features); | 1156 | (unsigned long long)features); |
| 1174 | err = -EROFS; | 1157 | err = -EROFS; |
| 1175 | goto restore_opts; | 1158 | goto ignore_opts; |
| 1176 | } | 1159 | } |
| 1177 | 1160 | ||
| 1178 | sb->s_flags &= ~SB_RDONLY; | 1161 | sb->s_flags &= ~SB_RDONLY; |
| 1179 | 1162 | ||
| 1180 | root = NILFS_I(d_inode(sb->s_root))->i_root; | 1163 | root = NILFS_I(d_inode(sb->s_root))->i_root; |
| 1181 | err = nilfs_attach_log_writer(sb, root); | 1164 | err = nilfs_attach_log_writer(sb, root); |
| 1182 | if (err) | 1165 | if (err) { |
| 1183 | goto restore_opts; | 1166 | sb->s_flags |= SB_RDONLY; |
| 1167 | goto ignore_opts; | ||
| 1168 | } | ||
| 1184 | 1169 | ||
| 1185 | down_write(&nilfs->ns_sem); | 1170 | down_write(&nilfs->ns_sem); |
| 1186 | nilfs_setup_super(sb, true); | 1171 | nilfs_setup_super(sb, true); |
| 1187 | up_write(&nilfs->ns_sem); | 1172 | up_write(&nilfs->ns_sem); |
| 1188 | } | 1173 | } |
| 1189 | out: | 1174 | out: |
| 1190 | return 0; | 1175 | sb->s_flags = (sb->s_flags & ~SB_POSIXACL); |
| 1191 | 1176 | /* Copy over parsed remount options */ | |
| 1192 | restore_opts: | 1177 | nilfs->ns_mount_opt = ctx->ns_mount_opt; |
| 1193 | sb->s_flags = old_sb_flags; | ||
| 1194 | nilfs->ns_mount_opt = old_mount_opt; | ||
| 1195 | return err; | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | struct nilfs_super_data { | ||
| 1199 | __u64 cno; | ||
| 1200 | int flags; | ||
| 1201 | }; | ||
| 1202 | |||
| 1203 | static int nilfs_parse_snapshot_option(const char *option, | ||
| 1204 | const substring_t *arg, | ||
| 1205 | struct nilfs_super_data *sd) | ||
| 1206 | { | ||
| 1207 | unsigned long long val; | ||
| 1208 | const char *msg = NULL; | ||
| 1209 | int err; | ||
| 1210 | |||
| 1211 | if (!(sd->flags & SB_RDONLY)) { | ||
| 1212 | msg = "read-only option is not specified"; | ||
| 1213 | goto parse_error; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | err = kstrtoull(arg->from, 0, &val); | ||
| 1217 | if (err) { | ||
| 1218 | if (err == -ERANGE) | ||
| 1219 | msg = "too large checkpoint number"; | ||
| 1220 | else | ||
| 1221 | msg = "malformed argument"; | ||
| 1222 | goto parse_error; | ||
| 1223 | } else if (val == 0) { | ||
| 1224 | msg = "invalid checkpoint number 0"; | ||
| 1225 | goto parse_error; | ||
| 1226 | } | ||
| 1227 | sd->cno = val; | ||
| 1228 | return 0; | ||
| 1229 | |||
| 1230 | parse_error: | ||
| 1231 | nilfs_err(NULL, "invalid option \"%s\": %s", option, msg); | ||
| 1232 | return 1; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | /** | ||
| 1236 | * nilfs_identify - pre-read mount options needed to identify mount instance | ||
| 1237 | * @data: mount options | ||
| 1238 | * @sd: nilfs_super_data | ||
| 1239 | */ | ||
| 1240 | static int nilfs_identify(char *data, struct nilfs_super_data *sd) | ||
| 1241 | { | ||
| 1242 | char *p, *options = data; | ||
| 1243 | substring_t args[MAX_OPT_ARGS]; | ||
| 1244 | int token; | ||
| 1245 | int ret = 0; | ||
| 1246 | |||
| 1247 | do { | ||
| 1248 | p = strsep(&options, ","); | ||
| 1249 | if (p != NULL && *p) { | ||
| 1250 | token = match_token(p, tokens, args); | ||
| 1251 | if (token == Opt_snapshot) | ||
| 1252 | ret = nilfs_parse_snapshot_option(p, &args[0], | ||
| 1253 | sd); | ||
| 1254 | } | ||
| 1255 | if (!options) | ||
| 1256 | break; | ||
| 1257 | BUG_ON(options == data); | ||
| 1258 | *(options - 1) = ','; | ||
| 1259 | } while (!ret); | ||
| 1260 | return ret; | ||
| 1261 | } | ||
| 1262 | 1178 | ||
| 1263 | static int nilfs_set_bdev_super(struct super_block *s, void *data) | ||
| 1264 | { | ||
| 1265 | s->s_dev = *(dev_t *)data; | ||
| 1266 | return 0; | 1179 | return 0; |
| 1267 | } | ||
| 1268 | 1180 | ||
| 1269 | static int nilfs_test_bdev_super(struct super_block *s, void *data) | 1181 | ignore_opts: |
| 1270 | { | 1182 | return err; |
| 1271 | return !(s->s_iflags & SB_I_RETIRED) && s->s_dev == *(dev_t *)data; | ||
| 1272 | } | 1183 | } |
| 1273 | 1184 | ||
| 1274 | static struct dentry * | 1185 | static int |
| 1275 | nilfs_mount(struct file_system_type *fs_type, int flags, | 1186 | nilfs_get_tree(struct fs_context *fc) |
| 1276 | const char *dev_name, void *data) | ||
| 1277 | { | 1187 | { |
| 1278 | struct nilfs_super_data sd = { .flags = flags }; | 1188 | struct nilfs_fs_context *ctx = fc->fs_private; |
| 1279 | struct super_block *s; | 1189 | struct super_block *s; |
| 1280 | dev_t dev; | 1190 | dev_t dev; |
| 1281 | int err; | 1191 | int err; |
| 1282 | 1192 | ||
| 1283 | if (nilfs_identify(data, &sd)) | 1193 | if (ctx->cno && !(fc->sb_flags & SB_RDONLY)) { |
| 1284 | return ERR_PTR(-EINVAL); | 1194 | nilfs_err(NULL, |
| 1195 | "invalid option \"cp=%llu\": read-only option is not specified", | ||
| 1196 | ctx->cno); | ||
| 1197 | return -EINVAL; | ||
| 1198 | } | ||
| 1285 | 1199 | ||
| 1286 | err = lookup_bdev(dev_name, &dev); | 1200 | err = lookup_bdev(fc->source, &dev); |
| 1287 | if (err) | 1201 | if (err) |
| 1288 | return ERR_PTR(err); | 1202 | return err; |
| 1289 | 1203 | ||
| 1290 | s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, flags, | 1204 | s = sget_dev(fc, dev); |
| 1291 | &dev); | ||
| 1292 | if (IS_ERR(s)) | 1205 | if (IS_ERR(s)) |
| 1293 | return ERR_CAST(s); | 1206 | return PTR_ERR(s); |
| 1294 | 1207 | ||
| 1295 | if (!s->s_root) { | 1208 | if (!s->s_root) { |
| 1296 | err = setup_bdev_super(s, flags, NULL); | 1209 | err = setup_bdev_super(s, fc->sb_flags, fc); |
| 1297 | if (!err) | 1210 | if (!err) |
| 1298 | err = nilfs_fill_super(s, data, | 1211 | err = nilfs_fill_super(s, fc); |
| 1299 | flags & SB_SILENT ? 1 : 0); | ||
| 1300 | if (err) | 1212 | if (err) |
| 1301 | goto failed_super; | 1213 | goto failed_super; |
| 1302 | 1214 | ||
| 1303 | s->s_flags |= SB_ACTIVE; | 1215 | s->s_flags |= SB_ACTIVE; |
| 1304 | } else if (!sd.cno) { | 1216 | } else if (!ctx->cno) { |
| 1305 | if (nilfs_tree_is_busy(s->s_root)) { | 1217 | if (nilfs_tree_is_busy(s->s_root)) { |
| 1306 | if ((flags ^ s->s_flags) & SB_RDONLY) { | 1218 | if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) { |
| 1307 | nilfs_err(s, | 1219 | nilfs_err(s, |
| 1308 | "the device already has a %s mount.", | 1220 | "the device already has a %s mount.", |
| 1309 | sb_rdonly(s) ? "read-only" : "read/write"); | 1221 | sb_rdonly(s) ? "read-only" : "read/write"); |
| @@ -1312,37 +1224,75 @@ nilfs_mount(struct file_system_type *fs_type, int flags, · 2 unmodified lines | |||
| 1312 | } | 1224 | } |
| 1313 | } else { | 1225 | } else { |
| 1314 | /* | 1226 | /* |
| 1315 | * Try remount to setup mount states if the current | 1227 | * Try reconfigure to setup mount states if the current |
| 1316 | * tree is not mounted and only snapshots use this sb. | 1228 | * tree is not mounted and only snapshots use this sb. |
| 1229 | * | ||
| 1230 | * Since nilfs_reconfigure() requires fc->root to be | ||
| 1231 | * set, set it first and release it on failure. | ||
| 1317 | */ | 1232 | */ |
| 1318 | err = nilfs_remount(s, &flags, data); | 1233 | fc->root = dget(s->s_root); |
| 1319 | if (err) | 1234 | err = nilfs_reconfigure(fc); |
| 1235 | if (err) { | ||
| 1236 | dput(fc->root); | ||
| 1237 | fc->root = NULL; /* prevent double release */ | ||
| 1320 | goto failed_super; | 1238 | goto failed_super; |
| 1239 | } | ||
| 1240 | return 0; | ||
| 1321 | } | 1241 | } |
| 1322 | } | 1242 | } |
| 1323 | 1243 | ||
| 1324 | if (sd.cno) { | 1244 | if (ctx->cno) { |
| 1325 | struct dentry *root_dentry; | 1245 | struct dentry *root_dentry; |
| 1326 | 1246 | ||
| 1327 | err = nilfs_attach_snapshot(s, sd.cno, &root_dentry); | 1247 | err = nilfs_attach_snapshot(s, ctx->cno, &root_dentry); |
| 1328 | if (err) | 1248 | if (err) |
| 1329 | goto failed_super; | 1249 | goto failed_super; |
| 1330 | return root_dentry; | 1250 | fc->root = root_dentry; |
| 1251 | return 0; | ||
| 1331 | } | 1252 | } |
| 1332 | 1253 | ||
| 1333 | return dget(s->s_root); | 1254 | fc->root = dget(s->s_root); |
| 1255 | return 0; | ||
| 1334 | 1256 | ||
| 1335 | failed_super: | 1257 | failed_super: |
| 1336 | deactivate_locked_super(s); | 1258 | deactivate_locked_super(s); |
| 1337 | return ERR_PTR(err); | 1259 | return err; |
| 1260 | } | ||
| 1261 | |||
| 1262 | static void nilfs_free_fc(struct fs_context *fc) | ||
| 1263 | { | ||
| 1264 | kfree(fc->fs_private); | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | static const struct fs_context_operations nilfs_context_ops = { | ||
| 1268 | .parse_param = nilfs_parse_param, | ||
| 1269 | .get_tree = nilfs_get_tree, | ||
| 1270 | .reconfigure = nilfs_reconfigure, | ||
| 1271 | .free = nilfs_free_fc, | ||
| 1272 | }; | ||
| 1273 | |||
| 1274 | static int nilfs_init_fs_context(struct fs_context *fc) | ||
| 1275 | { | ||
| 1276 | struct nilfs_fs_context *ctx; | ||
| 1277 | |||
| 1278 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 1279 | if (!ctx) | ||
| 1280 | return -ENOMEM; | ||
| 1281 | |||
| 1282 | ctx->ns_mount_opt = NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER; | ||
| 1283 | fc->fs_private = ctx; | ||
| 1284 | fc->ops = &nilfs_context_ops; | ||
| 1285 | |||
| 1286 | return 0; | ||
| 1338 | } | 1287 | } |
| 1339 | 1288 | ||
| 1340 | struct file_system_type nilfs_fs_type = { | 1289 | struct file_system_type nilfs_fs_type = { |
| 1341 | .owner = THIS_MODULE, | 1290 | .owner = THIS_MODULE, |
| 1342 | .name = "nilfs2", | 1291 | .name = "nilfs2", |
| 1343 | .mount = nilfs_mount, | ||
| 1344 | .kill_sb = kill_block_super, | 1292 | .kill_sb = kill_block_super, |
| 1345 | .fs_flags = FS_REQUIRES_DEV, | 1293 | .fs_flags = FS_REQUIRES_DEV, |
| 1294 | .init_fs_context = nilfs_init_fs_context, | ||
| 1295 | .parameters = nilfs_param_spec, | ||
| 1346 | }; | 1296 | }; |
| 1347 | MODULE_ALIAS_FS("nilfs2"); | 1297 | MODULE_ALIAS_FS("nilfs2"); |
| 1348 | 1298 | ||
| @@ -592,7 +592,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, · 591 unmodified lines | |||
| 592 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | 592 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
| 593 | struct buffer_head **sbh = nilfs->ns_sbh; | 593 | struct buffer_head **sbh = nilfs->ns_sbh; |
| 594 | u64 sb2off, devsize = bdev_nr_bytes(nilfs->ns_bdev); | 594 | u64 sb2off, devsize = bdev_nr_bytes(nilfs->ns_bdev); |
| 595 | int valid[2], swp = 0; | 595 | int valid[2], swp = 0, older; |
| 596 | 596 | ||
| 597 | if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) { | 597 | if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) { |
| 598 | nilfs_err(sb, "device size too small"); | 598 | nilfs_err(sb, "device size too small"); |
| @@ -648,9 +648,25 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, · 49 unmodified lines | |||
| 648 | if (swp) | 648 | if (swp) |
| 649 | nilfs_swap_super_block(nilfs); | 649 | nilfs_swap_super_block(nilfs); |
| 650 | 650 | ||
| 651 | /* | ||
| 652 | * Calculate the array index of the older superblock data. | ||
| 653 | * If one has been dropped, set index 0 pointing to the remaining one, | ||
| 654 | * otherwise set index 1 pointing to the old one (including if both | ||
| 655 | * are the same). | ||
| 656 | * | ||
| 657 | * Divided case valid[0] valid[1] swp -> older | ||
| 658 | * ------------------------------------------------------------- | ||
| 659 | * Both SBs are invalid 0 0 N/A (Error) | ||
| 660 | * SB1 is invalid 0 1 1 0 | ||
| 661 | * SB2 is invalid 1 0 0 0 | ||
| 662 | * SB2 is newer 1 1 1 0 | ||
| 663 | * SB2 is older or the same 1 1 0 1 | ||
| 664 | */ | ||
| 665 | older = valid[1] ^ swp; | ||
| 666 | |||
| 651 | nilfs->ns_sbwcount = 0; | 667 | nilfs->ns_sbwcount = 0; |
| 652 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); | 668 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); |
| 653 | nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq); | 669 | nilfs->ns_prot_seq = le64_to_cpu(sbp[older]->s_last_seq); |
| 654 | *sbpp = sbp[0]; | 670 | *sbpp = sbp[0]; |
| 655 | return 0; | 671 | return 0; |
| 656 | } | 672 | } |
| @@ -659,7 +675,6 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, · 2 unmodified lines | |||
| 659 | * init_nilfs - initialize a NILFS instance. | 675 | * init_nilfs - initialize a NILFS instance. |
| 660 | * @nilfs: the_nilfs structure | 676 | * @nilfs: the_nilfs structure |
| 661 | * @sb: super block | 677 | * @sb: super block |
| 662 | * @data: mount options | ||
| 663 | * | 678 | * |
| 664 | * init_nilfs() performs common initialization per block device (e.g. | 679 | * init_nilfs() performs common initialization per block device (e.g. |
| 665 | * reading the super block, getting disk layout information, initializing | 680 | * reading the super block, getting disk layout information, initializing |
| @@ -668,7 +683,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, · 2 unmodified lines | |||
| 668 | * Return Value: On success, 0 is returned. On error, a negative error | 683 | * Return Value: On success, 0 is returned. On error, a negative error |
| 669 | * code is returned. | 684 | * code is returned. |
| 670 | */ | 685 | */ |
| 671 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) | 686 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb) |
| 672 | { | 687 | { |
| 673 | struct nilfs_super_block *sbp; | 688 | struct nilfs_super_block *sbp; |
| 674 | int blocksize; | 689 | int blocksize; |
| @@ -686,7 +701,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) · 11 unmodified lines | |||
| 686 | if (err) | 701 | if (err) |
| 687 | goto out; | 702 | goto out; |
| 688 | 703 | ||
| 689 | err = nilfs_store_magic_and_option(sb, sbp, data); | 704 | err = nilfs_store_magic(sb, sbp); |
| 690 | if (err) | 705 | if (err) |
| 691 | goto failed_sbh; | 706 | goto failed_sbh; |
| 692 | 707 | ||
| @@ -219,10 +219,6 @@ THE_NILFS_FNS(PURGING, purging) · 218 unmodified lines | |||
| 219 | #define nilfs_set_opt(nilfs, opt) \ | 219 | #define nilfs_set_opt(nilfs, opt) \ |
| 220 | ((nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt) | 220 | ((nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt) |
| 221 | #define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt) | 221 | #define nilfs_test_opt(nilfs, opt) ((nilfs)->ns_mount_opt & NILFS_MOUNT_##opt) |
| 222 | #define nilfs_write_opt(nilfs, mask, opt) \ | ||
| 223 | ((nilfs)->ns_mount_opt = \ | ||
| 224 | (((nilfs)->ns_mount_opt & ~NILFS_MOUNT_##mask) | \ | ||
| 225 | NILFS_MOUNT_##opt)) \ | ||
| 226 | 222 | ||
| 227 | /** | 223 | /** |
| 228 | * struct nilfs_root - nilfs root object | 224 | * struct nilfs_root - nilfs root object |
| @@ -276,7 +272,7 @@ static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs) · 47 unmodified lines | |||
| 276 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); | 272 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); |
| 277 | struct the_nilfs *alloc_nilfs(struct super_block *sb); | 273 | struct the_nilfs *alloc_nilfs(struct super_block *sb); |
| 278 | void destroy_nilfs(struct the_nilfs *nilfs); | 274 | void destroy_nilfs(struct the_nilfs *nilfs); |
| 279 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data); | 275 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb); |
| 280 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb); | 276 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb); |
| 281 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs); | 277 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs); |
| 282 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs); | 278 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs); |
| @@ -2283,8 +2283,6 @@ unlock: · 2282 unmodified lines | |||
| 2283 | ocfs2_inode_unlock(inode, 1); | 2283 | ocfs2_inode_unlock(inode, 1); |
| 2284 | brelse(di_bh); | 2284 | brelse(di_bh); |
| 2285 | out: | 2285 | out: |
| 2286 | if (ret < 0) | ||
| 2287 | ret = -EIO; | ||
| 2288 | return ret; | 2286 | return ret; |
| 2289 | } | 2287 | } |
| 2290 | 2288 | ||
| @@ -1274,7 +1274,7 @@ static int dlm_query_nodeinfo_handler(struct o2net_msg *msg, u32 len, · 1273 unmodified lines | |||
| 1274 | { | 1274 | { |
| 1275 | struct dlm_query_nodeinfo *qn; | 1275 | struct dlm_query_nodeinfo *qn; |
| 1276 | struct dlm_ctxt *dlm = NULL; | 1276 | struct dlm_ctxt *dlm = NULL; |
| 1277 | int locked = 0, status = -EINVAL; | 1277 | int status = -EINVAL; |
| 1278 | 1278 | ||
| 1279 | qn = (struct dlm_query_nodeinfo *) msg->buf; | 1279 | qn = (struct dlm_query_nodeinfo *) msg->buf; |
| 1280 | 1280 | ||
| @@ -1290,12 +1290,11 @@ static int dlm_query_nodeinfo_handler(struct o2net_msg *msg, u32 len, · 9 unmodified lines | |||
| 1290 | } | 1290 | } |
| 1291 | 1291 | ||
| 1292 | spin_lock(&dlm->spinlock); | 1292 | spin_lock(&dlm->spinlock); |
| 1293 | locked = 1; | ||
| 1294 | if (dlm->joining_node != qn->qn_nodenum) { | 1293 | if (dlm->joining_node != qn->qn_nodenum) { |
| 1295 | mlog(ML_ERROR, "Node %d queried nodes on domain %s but " | 1294 | mlog(ML_ERROR, "Node %d queried nodes on domain %s but " |
| 1296 | "joining node is %d\n", qn->qn_nodenum, qn->qn_domain, | 1295 | "joining node is %d\n", qn->qn_nodenum, qn->qn_domain, |
| 1297 | dlm->joining_node); | 1296 | dlm->joining_node); |
| 1298 | goto bail; | 1297 | goto unlock; |
| 1299 | } | 1298 | } |
| 1300 | 1299 | ||
| 1301 | /* Support for node query was added in 1.1 */ | 1300 | /* Support for node query was added in 1.1 */ |
| @@ -1305,14 +1304,14 @@ static int dlm_query_nodeinfo_handler(struct o2net_msg *msg, u32 len, · 3 unmodified lines | |||
| 1305 | "but active dlm protocol is %d.%d\n", qn->qn_nodenum, | 1304 | "but active dlm protocol is %d.%d\n", qn->qn_nodenum, |
| 1306 | qn->qn_domain, dlm->dlm_locking_proto.pv_major, | 1305 | qn->qn_domain, dlm->dlm_locking_proto.pv_major, |
| 1307 | dlm->dlm_locking_proto.pv_minor); | 1306 | dlm->dlm_locking_proto.pv_minor); |
| 1308 | goto bail; | 1307 | goto unlock; |
| 1309 | } | 1308 | } |
| 1310 | 1309 | ||
| 1311 | status = dlm_match_nodes(dlm, qn); | 1310 | status = dlm_match_nodes(dlm, qn); |
| 1312 | 1311 | ||
| 1312 | unlock: | ||
| 1313 | spin_unlock(&dlm->spinlock); | ||
| 1313 | bail: | 1314 | bail: |
| 1314 | if (locked) | ||
| 1315 | spin_unlock(&dlm->spinlock); | ||
| 1316 | spin_unlock(&dlm_domain_lock); | 1315 | spin_unlock(&dlm_domain_lock); |
| 1317 | 1316 | ||
| 1318 | return status; | 1317 | return status; |
| @@ -1528,7 +1527,6 @@ static void dlm_send_join_asserts(struct dlm_ctxt *dlm, · 209 unmodified lines | |||
| 1528 | { | 1527 | { |
| 1529 | int status, node, live; | 1528 | int status, node, live; |
| 1530 | 1529 | ||
| 1531 | status = 0; | ||
| 1532 | node = -1; | 1530 | node = -1; |
| 1533 | while ((node = find_next_bit(node_map, O2NM_MAX_NODES, | 1531 | while ((node = find_next_bit(node_map, O2NM_MAX_NODES, |
| 1534 | node + 1)) < O2NM_MAX_NODES) { | 1532 | node + 1)) < O2NM_MAX_NODES) { |
| @@ -255,9 +255,9 @@ static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb, · 254 unmodified lines | |||
| 255 | if (fh_len < 3 || fh_type > 2) | 255 | if (fh_len < 3 || fh_type > 2) |
| 256 | return NULL; | 256 | return NULL; |
| 257 | 257 | ||
| 258 | handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32; | 258 | handle.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[0]) << 32; |
| 259 | handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]); | 259 | handle.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[1]); |
| 260 | handle.ih_generation = le32_to_cpu(fid->raw[2]); | 260 | handle.ih_generation = le32_to_cpu((__force __le32)fid->raw[2]); |
| 261 | return ocfs2_get_dentry(sb, &handle); | 261 | return ocfs2_get_dentry(sb, &handle); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| @@ -269,9 +269,9 @@ static struct dentry *ocfs2_fh_to_parent(struct super_block *sb, · 5 unmodified lines | |||
| 269 | if (fh_type != 2 || fh_len < 6) | 269 | if (fh_type != 2 || fh_len < 6) |
| 270 | return NULL; | 270 | return NULL; |
| 271 | 271 | ||
| 272 | parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32; | 272 | parent.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[3]) << 32; |
| 273 | parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]); | 273 | parent.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[4]); |
| 274 | parent.ih_generation = le32_to_cpu(fid->raw[5]); | 274 | parent.ih_generation = le32_to_cpu((__force __le32)fid->raw[5]); |
| 275 | return ocfs2_get_dentry(sb, &parent); | 275 | return ocfs2_get_dentry(sb, &parent); |
| 276 | } | 276 | } |
| 277 | 277 | ||
| @@ -1936,6 +1936,8 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 1935 unmodified lines | |||
| 1936 | 1936 | ||
| 1937 | inode_lock(inode); | 1937 | inode_lock(inode); |
| 1938 | 1938 | ||
| 1939 | /* Wait all existing dio workers, newcomers will block on i_rwsem */ | ||
| 1940 | inode_dio_wait(inode); | ||
| 1939 | /* | 1941 | /* |
| 1940 | * This prevents concurrent writes on other nodes | 1942 | * This prevents concurrent writes on other nodes |
| 1941 | */ | 1943 | */ |
| @@ -1621,6 +1621,7 @@ static struct super_block *ocfs2_inode_cache_get_super(struct ocfs2_caching_info · 1620 unmodified lines | |||
| 1621 | } | 1621 | } |
| 1622 | 1622 | ||
| 1623 | static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci) | 1623 | static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci) |
| 1624 | __acquires(&oi->ip_lock) | ||
| 1624 | { | 1625 | { |
| 1625 | struct ocfs2_inode_info *oi = cache_info_to_inode(ci); | 1626 | struct ocfs2_inode_info *oi = cache_info_to_inode(ci); |
| 1626 | 1627 | ||
| @@ -1628,6 +1629,7 @@ static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci) · 1 unmodified line | |||
| 1628 | } | 1629 | } |
| 1629 | 1630 | ||
| 1630 | static void ocfs2_inode_cache_unlock(struct ocfs2_caching_info *ci) | 1631 | static void ocfs2_inode_cache_unlock(struct ocfs2_caching_info *ci) |
| 1632 | __releases(&oi->ip_lock) | ||
| 1631 | { | 1633 | { |
| 1632 | struct ocfs2_inode_info *oi = cache_info_to_inode(ci); | 1634 | struct ocfs2_inode_info *oi = cache_info_to_inode(ci); |
| 1633 | 1635 | ||
| @@ -125,6 +125,7 @@ int ocfs2_fileattr_set(struct mnt_idmap *idmap, · 124 unmodified lines | |||
| 125 | 125 | ||
| 126 | ocfs2_inode->ip_attr = flags; | 126 | ocfs2_inode->ip_attr = flags; |
| 127 | ocfs2_set_inode_flags(inode); | 127 | ocfs2_set_inode_flags(inode); |
| 128 | inode_set_ctime_current(inode); | ||
| 128 | 129 | ||
| 129 | status = ocfs2_mark_inode_dirty(handle, inode, bh); | 130 | status = ocfs2_mark_inode_dirty(handle, inode, bh); |
| 130 | if (status < 0) | 131 | if (status < 0) |
| @@ -212,14 +212,15 @@ static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb) · 211 unmodified lines | |||
| 212 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, | 212 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, |
| 213 | unsigned int num_clusters) | 213 | unsigned int num_clusters) |
| 214 | { | 214 | { |
| 215 | spin_lock(&osb->osb_lock); | 215 | if (num_clusters >= osb->local_alloc_default_bits) { |
| 216 | if (osb->local_alloc_state == OCFS2_LA_DISABLED || | 216 | spin_lock(&osb->osb_lock); |
| 217 | osb->local_alloc_state == OCFS2_LA_THROTTLED) | 217 | if (osb->local_alloc_state == OCFS2_LA_DISABLED || |
| 218 | if (num_clusters >= osb->local_alloc_default_bits) { | 218 | osb->local_alloc_state == OCFS2_LA_THROTTLED) { |
| 219 | cancel_delayed_work(&osb->la_enable_wq); | 219 | cancel_delayed_work(&osb->la_enable_wq); |
| 220 | osb->local_alloc_state = OCFS2_LA_ENABLED; | 220 | osb->local_alloc_state = OCFS2_LA_ENABLED; |
| 221 | } | 221 | } |
| 222 | spin_unlock(&osb->osb_lock); | 222 | spin_unlock(&osb->osb_lock); |
| 223 | } | ||
| 223 | } | 224 | } |
| 224 | 225 | ||
| 225 | void ocfs2_la_enable_worker(struct work_struct *work) | 226 | void ocfs2_la_enable_worker(struct work_struct *work) |
| @@ -335,7 +336,7 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) · 109 unmodified lines | |||
| 335 | "found = %u, set = %u, taken = %u, off = %u\n", | 336 | "found = %u, set = %u, taken = %u, off = %u\n", |
| 336 | num_used, le32_to_cpu(alloc->id1.bitmap1.i_used), | 337 | num_used, le32_to_cpu(alloc->id1.bitmap1.i_used), |
| 337 | le32_to_cpu(alloc->id1.bitmap1.i_total), | 338 | le32_to_cpu(alloc->id1.bitmap1.i_total), |
| 338 | OCFS2_LOCAL_ALLOC(alloc)->la_bm_off); | 339 | le32_to_cpu(OCFS2_LOCAL_ALLOC(alloc)->la_bm_off)); |
| 339 | 340 | ||
| 340 | status = -EINVAL; | 341 | status = -EINVAL; |
| 341 | goto bail; | 342 | goto bail; |
| @@ -863,14 +864,8 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, · 521 unmodified lines | |||
| 863 | 864 | ||
| 864 | numfound = bitoff = startoff = 0; | 865 | numfound = bitoff = startoff = 0; |
| 865 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); | 866 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); |
| 866 | while ((bitoff = ocfs2_find_next_zero_bit(bitmap, left, startoff)) != -1) { | 867 | while ((bitoff = ocfs2_find_next_zero_bit(bitmap, left, startoff)) < |
| 867 | if (bitoff == left) { | 868 | left) { |
| 868 | /* mlog(0, "bitoff (%d) == left", bitoff); */ | ||
| 869 | break; | ||
| 870 | } | ||
| 871 | /* mlog(0, "Found a zero: bitoff = %d, startoff = %d, " | ||
| 872 | "numfound = %d\n", bitoff, startoff, numfound);*/ | ||
| 873 | |||
| 874 | /* Ok, we found a zero bit... is it contig. or do we | 869 | /* Ok, we found a zero bit... is it contig. or do we |
| 875 | * start over?*/ | 870 | * start over?*/ |
| 876 | if (bitoff == startoff) { | 871 | if (bitoff == startoff) { |
| @@ -976,9 +971,9 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, · 99 unmodified lines | |||
| 976 | start = count = 0; | 971 | start = count = 0; |
| 977 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); | 972 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); |
| 978 | 973 | ||
| 979 | while ((bit_off = ocfs2_find_next_zero_bit(bitmap, left, start)) | 974 | while ((bit_off = ocfs2_find_next_zero_bit(bitmap, left, start)) < |
| 980 | != -1) { | 975 | left) { |
| 981 | if ((bit_off < left) && (bit_off == start)) { | 976 | if (bit_off == start) { |
| 982 | count++; | 977 | count++; |
| 983 | start++; | 978 | start++; |
| 984 | continue; | 979 | continue; |
| @@ -1002,8 +997,7 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, · 17 unmodified lines | |||
| 1002 | goto bail; | 997 | goto bail; |
| 1003 | } | 998 | } |
| 1004 | } | 999 | } |
| 1005 | if (bit_off >= left) | 1000 | |
| 1006 | break; | ||
| 1007 | count = 1; | 1001 | count = 1; |
| 1008 | start = bit_off + 1; | 1002 | start = bit_off + 1; |
| 1009 | } | 1003 | } |
| @@ -1220,7 +1214,7 @@ retry_enospc: · 210 unmodified lines | |||
| 1220 | OCFS2_LOCAL_ALLOC(alloc)->la_bitmap); | 1214 | OCFS2_LOCAL_ALLOC(alloc)->la_bitmap); |
| 1221 | 1215 | ||
| 1222 | trace_ocfs2_local_alloc_new_window_result( | 1216 | trace_ocfs2_local_alloc_new_window_result( |
| 1223 | OCFS2_LOCAL_ALLOC(alloc)->la_bm_off, | 1217 | le32_to_cpu(OCFS2_LOCAL_ALLOC(alloc)->la_bm_off), |
| 1224 | le32_to_cpu(alloc->id1.bitmap1.i_total)); | 1218 | le32_to_cpu(alloc->id1.bitmap1.i_total)); |
| 1225 | 1219 | ||
| 1226 | bail: | 1220 | bail: |
| @@ -685,7 +685,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context, · 684 unmodified lines | |||
| 685 | } | 685 | } |
| 686 | 686 | ||
| 687 | ret = ocfs2_block_group_set_bits(handle, gb_inode, gd, gd_bh, | 687 | ret = ocfs2_block_group_set_bits(handle, gb_inode, gd, gd_bh, |
| 688 | goal_bit, len); | 688 | goal_bit, len, 0, 0); |
| 689 | if (ret) { | 689 | if (ret) { |
| 690 | ocfs2_rollback_alloc_dinode_counts(gb_inode, gb_bh, len, | 690 | ocfs2_rollback_alloc_dinode_counts(gb_inode, gb_bh, len, |
| 691 | le16_to_cpu(gd->bg_chain)); | 691 | le16_to_cpu(gd->bg_chain)); |
| @@ -566,7 +566,7 @@ static int __ocfs2_mknod_locked(struct inode *dir, · 565 unmodified lines | |||
| 566 | fe->i_last_eb_blk = 0; | 566 | fe->i_last_eb_blk = 0; |
| 567 | strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE); | 567 | strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE); |
| 568 | fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL); | 568 | fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL); |
| 569 | ktime_get_real_ts64(&ts); | 569 | ktime_get_coarse_real_ts64(&ts); |
| 570 | fe->i_atime = fe->i_ctime = fe->i_mtime = | 570 | fe->i_atime = fe->i_ctime = fe->i_mtime = |
| 571 | cpu_to_le64(ts.tv_sec); | 571 | cpu_to_le64(ts.tv_sec); |
| 572 | fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec = | 572 | fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec = |
| @@ -797,6 +797,7 @@ static int ocfs2_link(struct dentry *old_dentry, · 224 unmodified lines | |||
| 797 | ocfs2_set_links_count(fe, inode->i_nlink); | 797 | ocfs2_set_links_count(fe, inode->i_nlink); |
| 798 | fe->i_ctime = cpu_to_le64(inode_get_ctime_sec(inode)); | 798 | fe->i_ctime = cpu_to_le64(inode_get_ctime_sec(inode)); |
| 799 | fe->i_ctime_nsec = cpu_to_le32(inode_get_ctime_nsec(inode)); | 799 | fe->i_ctime_nsec = cpu_to_le32(inode_get_ctime_nsec(inode)); |
| 800 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 800 | ocfs2_journal_dirty(handle, fe_bh); | 801 | ocfs2_journal_dirty(handle, fe_bh); |
| 801 | 802 | ||
| 802 | err = ocfs2_add_entry(handle, dentry, inode, | 803 | err = ocfs2_add_entry(handle, dentry, inode, |
| @@ -993,6 +994,7 @@ static int ocfs2_unlink(struct inode *dir, · 190 unmodified lines | |||
| 993 | drop_nlink(inode); | 994 | drop_nlink(inode); |
| 994 | drop_nlink(inode); | 995 | drop_nlink(inode); |
| 995 | ocfs2_set_links_count(fe, inode->i_nlink); | 996 | ocfs2_set_links_count(fe, inode->i_nlink); |
| 997 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 996 | ocfs2_journal_dirty(handle, fe_bh); | 998 | ocfs2_journal_dirty(handle, fe_bh); |
| 997 | 999 | ||
| 998 | inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); | 1000 | inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); |
| @@ -883,7 +883,8 @@ struct ocfs2_group_desc · 882 unmodified lines | |||
| 883 | __le16 bg_free_bits_count; /* Free bits count */ | 883 | __le16 bg_free_bits_count; /* Free bits count */ |
| 884 | __le16 bg_chain; /* What chain I am in. */ | 884 | __le16 bg_chain; /* What chain I am in. */ |
| 885 | /*10*/ __le32 bg_generation; | 885 | /*10*/ __le32 bg_generation; |
| 886 | __le32 bg_reserved1; | 886 | __le16 bg_contig_free_bits; /* max contig free bits length */ |
| 887 | __le16 bg_reserved1; | ||
| 887 | __le64 bg_next_group; /* Next group in my list, in | 888 | __le64 bg_next_group; /* Next group in my list, in |
| 888 | blocks */ | 889 | blocks */ |
| 889 | /*20*/ __le64 bg_parent_dinode; /* dinode which owns me, in | 890 | /*20*/ __le64 bg_parent_dinode; /* dinode which owns me, in |
| @@ -630,7 +630,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode, · 629 unmodified lines | |||
| 630 | rb->rf_records.rl_count = | 630 | rb->rf_records.rl_count = |
| 631 | cpu_to_le16(ocfs2_refcount_recs_per_rb(osb->sb)); | 631 | cpu_to_le16(ocfs2_refcount_recs_per_rb(osb->sb)); |
| 632 | spin_lock(&osb->osb_lock); | 632 | spin_lock(&osb->osb_lock); |
| 633 | rb->rf_generation = osb->s_next_generation++; | 633 | rb->rf_generation = cpu_to_le32(osb->s_next_generation++); |
| 634 | spin_unlock(&osb->osb_lock); | 634 | spin_unlock(&osb->osb_lock); |
| 635 | 635 | ||
| 636 | ocfs2_journal_dirty(handle, new_bh); | 636 | ocfs2_journal_dirty(handle, new_bh); |
| @@ -414,7 +414,7 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap, · 413 unmodified lines | |||
| 414 | 414 | ||
| 415 | start = search_start; | 415 | start = search_start; |
| 416 | while ((offset = ocfs2_find_next_zero_bit(bitmap, resmap->m_bitmap_len, | 416 | while ((offset = ocfs2_find_next_zero_bit(bitmap, resmap->m_bitmap_len, |
| 417 | start)) != -1) { | 417 | start)) < resmap->m_bitmap_len) { |
| 418 | /* Search reached end of the region */ | 418 | /* Search reached end of the region */ |
| 419 | if (offset >= (search_start + search_len)) | 419 | if (offset >= (search_start + search_len)) |
| 420 | break; | 420 | break; |
| @@ -91,6 +91,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, · 90 unmodified lines | |||
| 91 | u16 cl_bpc = le16_to_cpu(cl->cl_bpc); | 91 | u16 cl_bpc = le16_to_cpu(cl->cl_bpc); |
| 92 | u16 cl_cpg = le16_to_cpu(cl->cl_cpg); | 92 | u16 cl_cpg = le16_to_cpu(cl->cl_cpg); |
| 93 | u16 old_bg_clusters; | 93 | u16 old_bg_clusters; |
| 94 | u16 contig_bits; | ||
| 95 | __le16 old_bg_contig_free_bits; | ||
| 94 | 96 | ||
| 95 | trace_ocfs2_update_last_group_and_inode(new_clusters, | 97 | trace_ocfs2_update_last_group_and_inode(new_clusters, |
| 96 | first_new_cluster); | 98 | first_new_cluster); |
| @@ -122,6 +124,11 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, · 25 unmodified lines | |||
| 122 | le16_add_cpu(&group->bg_free_bits_count, -1 * backups); | 124 | le16_add_cpu(&group->bg_free_bits_count, -1 * backups); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 127 | contig_bits = ocfs2_find_max_contig_free_bits(group->bg_bitmap, | ||
| 128 | le16_to_cpu(group->bg_bits), 0); | ||
| 129 | old_bg_contig_free_bits = group->bg_contig_free_bits; | ||
| 130 | group->bg_contig_free_bits = cpu_to_le16(contig_bits); | ||
| 131 | |||
| 125 | ocfs2_journal_dirty(handle, group_bh); | 132 | ocfs2_journal_dirty(handle, group_bh); |
| 126 | 133 | ||
| 127 | /* update the inode accordingly. */ | 134 | /* update the inode accordingly. */ |
| @@ -160,6 +167,7 @@ out_rollback: · 32 unmodified lines | |||
| 160 | le16_add_cpu(&group->bg_free_bits_count, backups); | 167 | le16_add_cpu(&group->bg_free_bits_count, backups); |
| 161 | le16_add_cpu(&group->bg_bits, -1 * num_bits); | 168 | le16_add_cpu(&group->bg_bits, -1 * num_bits); |
| 162 | le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits); | 169 | le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits); |
| 170 | group->bg_contig_free_bits = old_bg_contig_free_bits; | ||
| 163 | } | 171 | } |
| 164 | out: | 172 | out: |
| 165 | if (ret) | 173 | if (ret) |
| @@ -50,6 +50,10 @@ struct ocfs2_suballoc_result { · 49 unmodified lines | |||
| 50 | u64 sr_blkno; /* The first allocated block */ | 50 | u64 sr_blkno; /* The first allocated block */ |
| 51 | unsigned int sr_bit_offset; /* The bit in the bg */ | 51 | unsigned int sr_bit_offset; /* The bit in the bg */ |
| 52 | unsigned int sr_bits; /* How many bits we claimed */ | 52 | unsigned int sr_bits; /* How many bits we claimed */ |
| 53 | unsigned int sr_max_contig_bits; /* The length for contiguous | ||
| 54 | * free bits, only available | ||
| 55 | * for cluster group | ||
| 56 | */ | ||
| 53 | }; | 57 | }; |
| 54 | 58 | ||
| 55 | static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res) | 59 | static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res) |
| @@ -1272,6 +1276,26 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, · 1216 unmodified lines | |||
| 1272 | return ret; | 1276 | return ret; |
| 1273 | } | 1277 | } |
| 1274 | 1278 | ||
| 1279 | u16 ocfs2_find_max_contig_free_bits(void *bitmap, | ||
| 1280 | u16 total_bits, u16 start) | ||
| 1281 | { | ||
| 1282 | u16 offset, free_bits; | ||
| 1283 | u16 contig_bits = 0; | ||
| 1284 | |||
| 1285 | while (start < total_bits) { | ||
| 1286 | offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start); | ||
| 1287 | if (offset == total_bits) | ||
| 1288 | break; | ||
| 1289 | |||
| 1290 | start = ocfs2_find_next_bit(bitmap, total_bits, offset); | ||
| 1291 | free_bits = start - offset; | ||
| 1292 | if (contig_bits < free_bits) | ||
| 1293 | contig_bits = free_bits; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | return contig_bits; | ||
| 1297 | } | ||
| 1298 | |||
| 1275 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | 1299 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, |
| 1276 | struct buffer_head *bg_bh, | 1300 | struct buffer_head *bg_bh, |
| 1277 | unsigned int bits_wanted, | 1301 | unsigned int bits_wanted, |
| @@ -1280,6 +1304,7 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, · 2 unmodified lines | |||
| 1280 | { | 1304 | { |
| 1281 | void *bitmap; | 1305 | void *bitmap; |
| 1282 | u16 best_offset, best_size; | 1306 | u16 best_offset, best_size; |
| 1307 | u16 prev_best_size = 0; | ||
| 1283 | int offset, start, found, status = 0; | 1308 | int offset, start, found, status = 0; |
| 1284 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 1309 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
| 1285 | 1310 | ||
| @@ -1290,10 +1315,8 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, · 4 unmodified lines | |||
| 1290 | found = start = best_offset = best_size = 0; | 1315 | found = start = best_offset = best_size = 0; |
| 1291 | bitmap = bg->bg_bitmap; | 1316 | bitmap = bg->bg_bitmap; |
| 1292 | 1317 | ||
| 1293 | while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) { | 1318 | while ((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) < |
| 1294 | if (offset == total_bits) | 1319 | total_bits) { |
| 1295 | break; | ||
| 1296 | |||
| 1297 | if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { | 1320 | if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { |
| 1298 | /* We found a zero, but we can't use it as it | 1321 | /* We found a zero, but we can't use it as it |
| 1299 | * hasn't been put to disk yet! */ | 1322 | * hasn't been put to disk yet! */ |
| @@ -1308,6 +1331,7 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, · 8 unmodified lines | |||
| 1308 | /* got a zero after some ones */ | 1331 | /* got a zero after some ones */ |
| 1309 | found = 1; | 1332 | found = 1; |
| 1310 | start = offset + 1; | 1333 | start = offset + 1; |
| 1334 | prev_best_size = best_size; | ||
| 1311 | } | 1335 | } |
| 1312 | if (found > best_size) { | 1336 | if (found > best_size) { |
| 1313 | best_size = found; | 1337 | best_size = found; |
| @@ -1320,6 +1344,8 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, · 6 unmodified lines | |||
| 1320 | } | 1344 | } |
| 1321 | } | 1345 | } |
| 1322 | 1346 | ||
| 1347 | /* best_size will be allocated, we save prev_best_size */ | ||
| 1348 | res->sr_max_contig_bits = prev_best_size; | ||
| 1323 | if (best_size) { | 1349 | if (best_size) { |
| 1324 | res->sr_bit_offset = best_offset; | 1350 | res->sr_bit_offset = best_offset; |
| 1325 | res->sr_bits = best_size; | 1351 | res->sr_bits = best_size; |
| @@ -1337,11 +1363,16 @@ int ocfs2_block_group_set_bits(handle_t *handle, · 11 unmodified lines | |||
| 1337 | struct ocfs2_group_desc *bg, | 1363 | struct ocfs2_group_desc *bg, |
| 1338 | struct buffer_head *group_bh, | 1364 | struct buffer_head *group_bh, |
| 1339 | unsigned int bit_off, | 1365 | unsigned int bit_off, |
| 1340 | unsigned int num_bits) | 1366 | unsigned int num_bits, |
| 1367 | unsigned int max_contig_bits, | ||
| 1368 | int fastpath) | ||
| 1341 | { | 1369 | { |
| 1342 | int status; | 1370 | int status; |
| 1343 | void *bitmap = bg->bg_bitmap; | 1371 | void *bitmap = bg->bg_bitmap; |
| 1344 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; | 1372 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; |
| 1373 | unsigned int start = bit_off + num_bits; | ||
| 1374 | u16 contig_bits; | ||
| 1375 | struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb); | ||
| 1345 | 1376 | ||
| 1346 | /* All callers get the descriptor via | 1377 | /* All callers get the descriptor via |
| 1347 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ | 1378 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ |
| @@ -1373,6 +1404,29 @@ int ocfs2_block_group_set_bits(handle_t *handle, · 25 unmodified lines | |||
| 1373 | while(num_bits--) | 1404 | while(num_bits--) |
| 1374 | ocfs2_set_bit(bit_off++, bitmap); | 1405 | ocfs2_set_bit(bit_off++, bitmap); |
| 1375 | 1406 | ||
| 1407 | /* | ||
| 1408 | * this is optimize path, caller set old contig value | ||
| 1409 | * in max_contig_bits to bypass finding action. | ||
| 1410 | */ | ||
| 1411 | if (fastpath) { | ||
| 1412 | bg->bg_contig_free_bits = cpu_to_le16(max_contig_bits); | ||
| 1413 | } else if (ocfs2_is_cluster_bitmap(alloc_inode)) { | ||
| 1414 | /* | ||
| 1415 | * Usually, the block group bitmap allocates only 1 bit | ||
| 1416 | * at a time, while the cluster group allocates n bits | ||
| 1417 | * each time. Therefore, we only save the contig bits for | ||
| 1418 | * the cluster group. | ||
| 1419 | */ | ||
| 1420 | contig_bits = ocfs2_find_max_contig_free_bits(bitmap, | ||
| 1421 | le16_to_cpu(bg->bg_bits), start); | ||
| 1422 | if (contig_bits > max_contig_bits) | ||
| 1423 | max_contig_bits = contig_bits; | ||
| 1424 | bg->bg_contig_free_bits = cpu_to_le16(max_contig_bits); | ||
| 1425 | ocfs2_local_alloc_seen_free_bits(osb, max_contig_bits); | ||
| 1426 | } else { | ||
| 1427 | bg->bg_contig_free_bits = 0; | ||
| 1428 | } | ||
| 1429 | |||
| 1376 | ocfs2_journal_dirty(handle, group_bh); | 1430 | ocfs2_journal_dirty(handle, group_bh); |
| 1377 | 1431 | ||
| 1378 | bail: | 1432 | bail: |
| @@ -1486,7 +1540,12 @@ static int ocfs2_cluster_group_search(struct inode *inode, · 107 unmodified lines | |||
| 1486 | 1540 | ||
| 1487 | BUG_ON(!ocfs2_is_cluster_bitmap(inode)); | 1541 | BUG_ON(!ocfs2_is_cluster_bitmap(inode)); |
| 1488 | 1542 | ||
| 1489 | if (gd->bg_free_bits_count) { | 1543 | if (le16_to_cpu(gd->bg_contig_free_bits) && |
| 1544 | le16_to_cpu(gd->bg_contig_free_bits) < bits_wanted) | ||
| 1545 | return -ENOSPC; | ||
| 1546 | |||
| 1547 | /* ->bg_contig_free_bits may un-initialized, so compare again */ | ||
| 1548 | if (le16_to_cpu(gd->bg_free_bits_count) >= bits_wanted) { | ||
| 1490 | max_bits = le16_to_cpu(gd->bg_bits); | 1549 | max_bits = le16_to_cpu(gd->bg_bits); |
| 1491 | 1550 | ||
| 1492 | /* Tail groups in cluster bitmaps which aren't cpg | 1551 | /* Tail groups in cluster bitmaps which aren't cpg |
| @@ -1530,13 +1589,6 @@ static int ocfs2_cluster_group_search(struct inode *inode, · 37 unmodified lines | |||
| 1530 | * of bits. */ | 1589 | * of bits. */ |
| 1531 | if (min_bits <= res->sr_bits) | 1590 | if (min_bits <= res->sr_bits) |
| 1532 | search = 0; /* success */ | 1591 | search = 0; /* success */ |
| 1533 | else if (res->sr_bits) { | ||
| 1534 | /* | ||
| 1535 | * Don't show bits which we'll be returning | ||
| 1536 | * for allocation to the local alloc bitmap. | ||
| 1537 | */ | ||
| 1538 | ocfs2_local_alloc_seen_free_bits(osb, res->sr_bits); | ||
| 1539 | } | ||
| 1540 | } | 1592 | } |
| 1541 | 1593 | ||
| 1542 | return search; | 1594 | return search; |
| @@ -1555,7 +1607,7 @@ static int ocfs2_block_group_search(struct inode *inode, · 12 unmodified lines | |||
| 1555 | BUG_ON(min_bits != 1); | 1607 | BUG_ON(min_bits != 1); |
| 1556 | BUG_ON(ocfs2_is_cluster_bitmap(inode)); | 1608 | BUG_ON(ocfs2_is_cluster_bitmap(inode)); |
| 1557 | 1609 | ||
| 1558 | if (bg->bg_free_bits_count) { | 1610 | if (le16_to_cpu(bg->bg_free_bits_count) >= bits_wanted) { |
| 1559 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), | 1611 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), |
| 1560 | group_bh, bits_wanted, | 1612 | group_bh, bits_wanted, |
| 1561 | le16_to_cpu(bg->bg_bits), | 1613 | le16_to_cpu(bg->bg_bits), |
| @@ -1715,7 +1767,8 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, · 153 unmodified lines | |||
| 1715 | } | 1767 | } |
| 1716 | 1768 | ||
| 1717 | ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh, | 1769 | ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh, |
| 1718 | res->sr_bit_offset, res->sr_bits); | 1770 | res->sr_bit_offset, res->sr_bits, |
| 1771 | res->sr_max_contig_bits, 0); | ||
| 1719 | if (ret < 0) { | 1772 | if (ret < 0) { |
| 1720 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, ac->ac_bh, | 1773 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, ac->ac_bh, |
| 1721 | res->sr_bits, | 1774 | res->sr_bits, |
| @@ -1849,7 +1902,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, · 127 unmodified lines | |||
| 1849 | bg, | 1902 | bg, |
| 1850 | group_bh, | 1903 | group_bh, |
| 1851 | res->sr_bit_offset, | 1904 | res->sr_bit_offset, |
| 1852 | res->sr_bits); | 1905 | res->sr_bits, |
| 1906 | res->sr_max_contig_bits, | ||
| 1907 | 0); | ||
| 1853 | if (status < 0) { | 1908 | if (status < 0) { |
| 1854 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, | 1909 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, |
| 1855 | ac->ac_bh, res->sr_bits, chain); | 1910 | ac->ac_bh, res->sr_bits, chain); |
| @@ -1951,7 +2006,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, · 95 unmodified lines | |||
| 1951 | for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i ++) { | 2006 | for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i ++) { |
| 1952 | if (i == victim) | 2007 | if (i == victim) |
| 1953 | continue; | 2008 | continue; |
| 1954 | if (!cl->cl_recs[i].c_free) | 2009 | if (le32_to_cpu(cl->cl_recs[i].c_free) < bits_wanted) |
| 1955 | continue; | 2010 | continue; |
| 1956 | 2011 | ||
| 1957 | ac->ac_chain = i; | 2012 | ac->ac_chain = i; |
| @@ -2163,7 +2218,9 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle, · 205 unmodified lines | |||
| 2163 | bg, | 2218 | bg, |
| 2164 | bg_bh, | 2219 | bg_bh, |
| 2165 | res->sr_bit_offset, | 2220 | res->sr_bit_offset, |
| 2166 | res->sr_bits); | 2221 | res->sr_bits, |
| 2222 | res->sr_max_contig_bits, | ||
| 2223 | 0); | ||
| 2167 | if (ret < 0) { | 2224 | if (ret < 0) { |
| 2168 | ocfs2_rollback_alloc_dinode_counts(ac->ac_inode, | 2225 | ocfs2_rollback_alloc_dinode_counts(ac->ac_inode, |
| 2169 | ac->ac_bh, res->sr_bits, chain); | 2226 | ac->ac_bh, res->sr_bits, chain); |
| @@ -2382,11 +2439,13 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, · 212 unmodified lines | |||
| 2382 | struct buffer_head *group_bh, | 2439 | struct buffer_head *group_bh, |
| 2383 | unsigned int bit_off, | 2440 | unsigned int bit_off, |
| 2384 | unsigned int num_bits, | 2441 | unsigned int num_bits, |
| 2442 | unsigned int max_contig_bits, | ||
| 2385 | void (*undo_fn)(unsigned int bit, | 2443 | void (*undo_fn)(unsigned int bit, |
| 2386 | unsigned long *bmap)) | 2444 | unsigned long *bmap)) |
| 2387 | { | 2445 | { |
| 2388 | int status; | 2446 | int status; |
| 2389 | unsigned int tmp; | 2447 | unsigned int tmp; |
| 2448 | u16 contig_bits; | ||
| 2390 | struct ocfs2_group_desc *undo_bg = NULL; | 2449 | struct ocfs2_group_desc *undo_bg = NULL; |
| 2391 | struct journal_head *jh; | 2450 | struct journal_head *jh; |
| 2392 | 2451 | ||
| @@ -2433,6 +2492,20 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, · 40 unmodified lines | |||
| 2433 | num_bits); | 2492 | num_bits); |
| 2434 | } | 2493 | } |
| 2435 | 2494 | ||
| 2495 | /* | ||
| 2496 | * TODO: even 'num_bits == 1' (the worst case, release 1 cluster), | ||
| 2497 | * we still need to rescan whole bitmap. | ||
| 2498 | */ | ||
| 2499 | if (ocfs2_is_cluster_bitmap(alloc_inode)) { | ||
| 2500 | contig_bits = ocfs2_find_max_contig_free_bits(bg->bg_bitmap, | ||
| 2501 | le16_to_cpu(bg->bg_bits), 0); | ||
| 2502 | if (contig_bits > max_contig_bits) | ||
| 2503 | max_contig_bits = contig_bits; | ||
| 2504 | bg->bg_contig_free_bits = cpu_to_le16(max_contig_bits); | ||
| 2505 | } else { | ||
| 2506 | bg->bg_contig_free_bits = 0; | ||
| 2507 | } | ||
| 2508 | |||
| 2436 | if (undo_fn) | 2509 | if (undo_fn) |
| 2437 | spin_unlock(&jh->b_state_lock); | 2510 | spin_unlock(&jh->b_state_lock); |
| 2438 | 2511 | ||
| @@ -2459,6 +2532,7 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, · 20 unmodified lines | |||
| 2459 | struct ocfs2_chain_list *cl = &fe->id2.i_chain; | 2532 | struct ocfs2_chain_list *cl = &fe->id2.i_chain; |
| 2460 | struct buffer_head *group_bh = NULL; | 2533 | struct buffer_head *group_bh = NULL; |
| 2461 | struct ocfs2_group_desc *group; | 2534 | struct ocfs2_group_desc *group; |
| 2535 | __le16 old_bg_contig_free_bits = 0; | ||
| 2462 | 2536 | ||
| 2463 | /* The alloc_bh comes from ocfs2_free_dinode() or | 2537 | /* The alloc_bh comes from ocfs2_free_dinode() or |
| 2464 | * ocfs2_free_clusters(). The callers have all locked the | 2538 | * ocfs2_free_clusters(). The callers have all locked the |
| @@ -2483,9 +2557,11 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, · 18 unmodified lines | |||
| 2483 | 2557 | ||
| 2484 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); | 2558 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); |
| 2485 | 2559 | ||
| 2560 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | ||
| 2561 | old_bg_contig_free_bits = group->bg_contig_free_bits; | ||
| 2486 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 2562 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |
| 2487 | group, group_bh, | 2563 | group, group_bh, |
| 2488 | start_bit, count, undo_fn); | 2564 | start_bit, count, 0, undo_fn); |
| 2489 | if (status < 0) { | 2565 | if (status < 0) { |
| 2490 | mlog_errno(status); | 2566 | mlog_errno(status); |
| 2491 | goto bail; | 2567 | goto bail; |
| @@ -2496,7 +2572,8 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, · 4 unmodified lines | |||
| 2496 | if (status < 0) { | 2572 | if (status < 0) { |
| 2497 | mlog_errno(status); | 2573 | mlog_errno(status); |
| 2498 | ocfs2_block_group_set_bits(handle, alloc_inode, group, group_bh, | 2574 | ocfs2_block_group_set_bits(handle, alloc_inode, group, group_bh, |
| 2499 | start_bit, count); | 2575 | start_bit, count, |
| 2576 | le16_to_cpu(old_bg_contig_free_bits), 1); | ||
| 2500 | goto bail; | 2577 | goto bail; |
| 2501 | } | 2578 | } |
| 2502 | 2579 | ||
| @@ -79,12 +79,16 @@ void ocfs2_rollback_alloc_dinode_counts(struct inode *inode, · 78 unmodified lines | |||
| 79 | struct buffer_head *di_bh, | 79 | struct buffer_head *di_bh, |
| 80 | u32 num_bits, | 80 | u32 num_bits, |
| 81 | u16 chain); | 81 | u16 chain); |
| 82 | u16 ocfs2_find_max_contig_free_bits(void *bitmap, | ||
| 83 | u16 total_bits, u16 start); | ||
| 82 | int ocfs2_block_group_set_bits(handle_t *handle, | 84 | int ocfs2_block_group_set_bits(handle_t *handle, |
| 83 | struct inode *alloc_inode, | 85 | struct inode *alloc_inode, |
| 84 | struct ocfs2_group_desc *bg, | 86 | struct ocfs2_group_desc *bg, |
| 85 | struct buffer_head *group_bh, | 87 | struct buffer_head *group_bh, |
| 86 | unsigned int bit_off, | 88 | unsigned int bit_off, |
| 87 | unsigned int num_bits); | 89 | unsigned int num_bits, |
| 90 | unsigned int max_contig_bits, | ||
| 91 | int fastpath); | ||
| 88 | 92 | ||
| 89 | int ocfs2_claim_metadata(handle_t *handle, | 93 | int ocfs2_claim_metadata(handle_t *handle, |
| 90 | struct ocfs2_alloc_context *ac, | 94 | struct ocfs2_alloc_context *ac, |
| @@ -383,6 +383,8 @@ static ssize_t __read_vmcore(struct iov_iter *iter, loff_t *fpos) · 382 unmodified lines | |||
| 383 | /* leave now if filled buffer already */ | 383 | /* leave now if filled buffer already */ |
| 384 | if (!iov_iter_count(iter)) | 384 | if (!iov_iter_count(iter)) |
| 385 | return acc; | 385 | return acc; |
| 386 | |||
| 387 | cond_resched(); | ||
| 386 | } | 388 | } |
| 387 | 389 | ||
| 388 | list_for_each_entry(m, &vmcore_list, list) { | 390 | list_for_each_entry(m, &vmcore_list, list) { |
| @@ -1370,9 +1372,8 @@ static void vmcoredd_write_header(void *buf, struct vmcoredd_data *data, · 981 unmodified lines | |||
| 1370 | vdd_hdr->n_descsz = size + sizeof(vdd_hdr->dump_name); | 1372 | vdd_hdr->n_descsz = size + sizeof(vdd_hdr->dump_name); |
| 1371 | vdd_hdr->n_type = NT_VMCOREDD; | 1373 | vdd_hdr->n_type = NT_VMCOREDD; |
| 1372 | 1374 | ||
| 1373 | strncpy((char *)vdd_hdr->name, VMCOREDD_NOTE_NAME, | 1375 | strscpy_pad(vdd_hdr->name, VMCOREDD_NOTE_NAME); |
| 1374 | sizeof(vdd_hdr->name)); | 1376 | strscpy_pad(vdd_hdr->dump_name, data->dump_name); |
| 1375 | memcpy(vdd_hdr->dump_name, data->dump_name, sizeof(vdd_hdr->dump_name)); | ||
| 1376 | } | 1377 | } |
| 1377 | 1378 | ||
| 1378 | /** | 1379 | /** |
| @@ -375,8 +375,6 @@ void squashfs_fill_page(struct page *page, struct squashfs_cache_entry *buffer, · 374 unmodified lines | |||
| 375 | flush_dcache_page(page); | 375 | flush_dcache_page(page); |
| 376 | if (copied == avail) | 376 | if (copied == avail) |
| 377 | SetPageUptodate(page); | 377 | SetPageUptodate(page); |
| 378 | else | ||
| 379 | SetPageError(page); | ||
| 380 | } | 378 | } |
| 381 | 379 | ||
| 382 | /* Copy data into page cache */ | 380 | /* Copy data into page cache */ |
| @@ -471,7 +469,7 @@ static int squashfs_read_folio(struct file *file, struct folio *folio) · 88 unmodified lines | |||
| 471 | 469 | ||
| 472 | res = read_blocklist(inode, index, &block); | 470 | res = read_blocklist(inode, index, &block); |
| 473 | if (res < 0) | 471 | if (res < 0) |
| 474 | goto error_out; | 472 | goto out; |
| 475 | 473 | ||
| 476 | if (res == 0) | 474 | if (res == 0) |
| 477 | res = squashfs_readpage_sparse(page, expected); | 475 | res = squashfs_readpage_sparse(page, expected); |
| @@ -483,8 +481,6 @@ static int squashfs_read_folio(struct file *file, struct folio *folio) · 5 unmodified lines | |||
| 483 | if (!res) | 481 | if (!res) |
| 484 | return 0; | 482 | return 0; |
| 485 | 483 | ||
| 486 | error_out: | ||
| 487 | SetPageError(page); | ||
| 488 | out: | 484 | out: |
| 489 | pageaddr = kmap_atomic(page); | 485 | pageaddr = kmap_atomic(page); |
| 490 | memset(pageaddr, 0, PAGE_SIZE); | 486 | memset(pageaddr, 0, PAGE_SIZE); |
| @@ -106,14 +106,13 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize, · 105 unmodified lines | |||
| 106 | return 0; | 106 | return 0; |
| 107 | 107 | ||
| 108 | mark_errored: | 108 | mark_errored: |
| 109 | /* Decompression failed, mark pages as errored. Target_page is | 109 | /* Decompression failed. Target_page is |
| 110 | * dealt with by the caller | 110 | * dealt with by the caller |
| 111 | */ | 111 | */ |
| 112 | for (i = 0; i < pages; i++) { | 112 | for (i = 0; i < pages; i++) { |
| 113 | if (page[i] == NULL || page[i] == target_page) | 113 | if (page[i] == NULL || page[i] == target_page) |
| 114 | continue; | 114 | continue; |
| 115 | flush_dcache_page(page[i]); | 115 | flush_dcache_page(page[i]); |
| 116 | SetPageError(page[i]); | ||
| 117 | unlock_page(page[i]); | 116 | unlock_page(page[i]); |
| 118 | put_page(page[i]); | 117 | put_page(page[i]); |
| 119 | } | 118 | } |
| @@ -62,27 +62,21 @@ · 61 unmodified lines | |||
| 62 | */ | 62 | */ |
| 63 | static int get_dir_index_using_name(struct super_block *sb, | 63 | static int get_dir_index_using_name(struct super_block *sb, |
| 64 | u64 *next_block, int *next_offset, u64 index_start, | 64 | u64 *next_block, int *next_offset, u64 index_start, |
| 65 | int index_offset, int i_count, const char *name, | 65 | int index_offset, int i_count, const char *name) |
| 66 | int len) | ||
| 67 | { | 66 | { |
| 68 | struct squashfs_sb_info *msblk = sb->s_fs_info; | 67 | struct squashfs_sb_info *msblk = sb->s_fs_info; |
| 69 | int i, length = 0, err; | 68 | int i, length = 0, err; |
| 70 | unsigned int size; | 69 | unsigned int size; |
| 71 | struct squashfs_dir_index *index; | 70 | struct squashfs_dir_index *index; |
| 72 | char *str; | ||
| 73 | 71 | ||
| 74 | TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); | 72 | TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); |
| 75 | 73 | ||
| 76 | index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN * 2 + 2, GFP_KERNEL); | 74 | index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); |
| 77 | if (index == NULL) { | 75 | if (index == NULL) { |
| 78 | ERROR("Failed to allocate squashfs_dir_index\n"); | 76 | ERROR("Failed to allocate squashfs_dir_index\n"); |
| 79 | goto out; | 77 | goto out; |
| 80 | } | 78 | } |
| 81 | 79 | ||
| 82 | str = &index->name[SQUASHFS_NAME_LEN + 1]; | ||
| 83 | strncpy(str, name, len); | ||
| 84 | str[len] = '\0'; | ||
| 85 | |||
| 86 | for (i = 0; i < i_count; i++) { | 80 | for (i = 0; i < i_count; i++) { |
| 87 | err = squashfs_read_metadata(sb, index, &index_start, | 81 | err = squashfs_read_metadata(sb, index, &index_start, |
| 88 | &index_offset, sizeof(*index)); | 82 | &index_offset, sizeof(*index)); |
| @@ -101,7 +95,7 @@ static int get_dir_index_using_name(struct super_block *sb, · 12 unmodified lines | |||
| 101 | 95 | ||
| 102 | index->name[size] = '\0'; | 96 | index->name[size] = '\0'; |
| 103 | 97 | ||
| 104 | if (strcmp(index->name, str) > 0) | 98 | if (strcmp(index->name, name) > 0) |
| 105 | break; | 99 | break; |
| 106 | 100 | ||
| 107 | length = le32_to_cpu(index->index); | 101 | length = le32_to_cpu(index->index); |
| @@ -153,7 +147,7 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, · 45 unmodified lines | |||
| 153 | length = get_dir_index_using_name(dir->i_sb, &block, &offset, | 147 | length = get_dir_index_using_name(dir->i_sb, &block, &offset, |
| 154 | squashfs_i(dir)->dir_idx_start, | 148 | squashfs_i(dir)->dir_idx_start, |
| 155 | squashfs_i(dir)->dir_idx_offset, | 149 | squashfs_i(dir)->dir_idx_offset, |
| 156 | squashfs_i(dir)->dir_idx_cnt, name, len); | 150 | squashfs_i(dir)->dir_idx_cnt, name); |
| 157 | 151 | ||
| 158 | while (length < i_size_read(dir)) { | 152 | while (length < i_size_read(dir)) { |
| 159 | /* | 153 | /* |
| @@ -32,20 +32,19 @@ · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) | 33 | static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) |
| 34 | { | 34 | { |
| 35 | struct page *page = &folio->page; | 35 | struct inode *inode = folio->mapping->host; |
| 36 | struct inode *inode = page->mapping->host; | ||
| 37 | struct super_block *sb = inode->i_sb; | 36 | struct super_block *sb = inode->i_sb; |
| 38 | struct squashfs_sb_info *msblk = sb->s_fs_info; | 37 | struct squashfs_sb_info *msblk = sb->s_fs_info; |
| 39 | int index = page->index << PAGE_SHIFT; | 38 | int index = folio_pos(folio); |
| 40 | u64 block = squashfs_i(inode)->start; | 39 | u64 block = squashfs_i(inode)->start; |
| 41 | int offset = squashfs_i(inode)->offset; | 40 | int offset = squashfs_i(inode)->offset; |
| 42 | int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE); | 41 | int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE); |
| 43 | int bytes, copied; | 42 | int bytes, copied, error; |
| 44 | void *pageaddr; | 43 | void *pageaddr; |
| 45 | struct squashfs_cache_entry *entry; | 44 | struct squashfs_cache_entry *entry; |
| 46 | 45 | ||
| 47 | TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " | 46 | TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " |
| 48 | "%llx, offset %x\n", page->index, block, offset); | 47 | "%llx, offset %x\n", folio->index, block, offset); |
| 49 | 48 | ||
| 50 | /* | 49 | /* |
| 51 | * Skip index bytes into symlink metadata. | 50 | * Skip index bytes into symlink metadata. |
| @@ -57,14 +56,15 @@ static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) · 5 unmodified lines | |||
| 57 | ERROR("Unable to read symlink [%llx:%x]\n", | 56 | ERROR("Unable to read symlink [%llx:%x]\n", |
| 58 | squashfs_i(inode)->start, | 57 | squashfs_i(inode)->start, |
| 59 | squashfs_i(inode)->offset); | 58 | squashfs_i(inode)->offset); |
| 60 | goto error_out; | 59 | error = bytes; |
| 60 | goto out; | ||
| 61 | } | 61 | } |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /* | 64 | /* |
| 65 | * Read length bytes from symlink metadata. Squashfs_read_metadata | 65 | * Read length bytes from symlink metadata. Squashfs_read_metadata |
| 66 | * is not used here because it can sleep and we want to use | 66 | * is not used here because it can sleep and we want to use |
| 67 | * kmap_atomic to map the page. Instead call the underlying | 67 | * kmap_local to map the folio. Instead call the underlying |
| 68 | * squashfs_cache_get routine. As length bytes may overlap metadata | 68 | * squashfs_cache_get routine. As length bytes may overlap metadata |
| 69 | * blocks, we may need to call squashfs_cache_get multiple times. | 69 | * blocks, we may need to call squashfs_cache_get multiple times. |
| 70 | */ | 70 | */ |
| @@ -75,29 +75,26 @@ static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) · 4 unmodified lines | |||
| 75 | squashfs_i(inode)->start, | 75 | squashfs_i(inode)->start, |
| 76 | squashfs_i(inode)->offset); | 76 | squashfs_i(inode)->offset); |
| 77 | squashfs_cache_put(entry); | 77 | squashfs_cache_put(entry); |
| 78 | goto error_out; | 78 | error = entry->error; |
| 79 | goto out; | ||
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | pageaddr = kmap_atomic(page); | 82 | pageaddr = kmap_local_folio(folio, 0); |
| 82 | copied = squashfs_copy_data(pageaddr + bytes, entry, offset, | 83 | copied = squashfs_copy_data(pageaddr + bytes, entry, offset, |
| 83 | length - bytes); | 84 | length - bytes); |
| 84 | if (copied == length - bytes) | 85 | if (copied == length - bytes) |
| 85 | memset(pageaddr + length, 0, PAGE_SIZE - length); | 86 | memset(pageaddr + length, 0, PAGE_SIZE - length); |
| 86 | else | 87 | else |
| 87 | block = entry->next_index; | 88 | block = entry->next_index; |
| 88 | kunmap_atomic(pageaddr); | 89 | kunmap_local(pageaddr); |
| 89 | squashfs_cache_put(entry); | 90 | squashfs_cache_put(entry); |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 92 | flush_dcache_page(page); | 93 | flush_dcache_folio(folio); |
| 93 | SetPageUptodate(page); | 94 | error = 0; |
| 94 | unlock_page(page); | 95 | out: |
| 95 | return 0; | 96 | folio_end_read(folio, error == 0); |
| 96 | 97 | return error; | |
| 97 | error_out: | ||
| 98 | SetPageError(page); | ||
| 99 | unlock_page(page); | ||
| 100 | return 0; | ||
| 101 | } | 98 | } |
| 102 | 99 | ||
| 103 | 100 | ||
| @@ -1057,11 +1057,6 @@ void init_cpu_present(const struct cpumask *src); · 1056 unmodified lines | |||
| 1057 | void init_cpu_possible(const struct cpumask *src); | 1057 | void init_cpu_possible(const struct cpumask *src); |
| 1058 | void init_cpu_online(const struct cpumask *src); | 1058 | void init_cpu_online(const struct cpumask *src); |
| 1059 | 1059 | ||
| 1060 | static inline void reset_cpu_possible_mask(void) | ||
| 1061 | { | ||
| 1062 | bitmap_zero(cpumask_bits(&__cpu_possible_mask), NR_CPUS); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | static inline void | 1060 | static inline void |
| 1066 | set_cpu_possible(unsigned int cpu, bool possible) | 1061 | set_cpu_possible(unsigned int cpu, bool possible) |
| 1067 | { | 1062 | { |
| @@ -147,6 +147,41 @@ instrument_copy_from_user_after(const void *to, const void __user *from, · 146 unmodified lines | |||
| 147 | kmsan_unpoison_memory(to, n - left); | 147 | kmsan_unpoison_memory(to, n - left); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | /** | ||
| 151 | * instrument_memcpy_before - add instrumentation before non-instrumented memcpy | ||
| 152 | * @to: destination address | ||
| 153 | * @from: source address | ||
| 154 | * @n: number of bytes to copy | ||
| 155 | * | ||
| 156 | * Instrument memory accesses that happen in custom memcpy implementations. The | ||
| 157 | * instrumentation should be inserted before the memcpy call. | ||
| 158 | */ | ||
| 159 | static __always_inline void instrument_memcpy_before(void *to, const void *from, | ||
| 160 | unsigned long n) | ||
| 161 | { | ||
| 162 | kasan_check_write(to, n); | ||
| 163 | kasan_check_read(from, n); | ||
| 164 | kcsan_check_write(to, n); | ||
| 165 | kcsan_check_read(from, n); | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * instrument_memcpy_after - add instrumentation after non-instrumented memcpy | ||
| 170 | * @to: destination address | ||
| 171 | * @from: source address | ||
| 172 | * @n: number of bytes to copy | ||
| 173 | * @left: number of bytes not copied (if known) | ||
| 174 | * | ||
| 175 | * Instrument memory accesses that happen in custom memcpy implementations. The | ||
| 176 | * instrumentation should be inserted after the memcpy call. | ||
| 177 | */ | ||
| 178 | static __always_inline void instrument_memcpy_after(void *to, const void *from, | ||
| 179 | unsigned long n, | ||
| 180 | unsigned long left) | ||
| 181 | { | ||
| 182 | kmsan_memmove(to, from, n - left); | ||
| 183 | } | ||
| 184 | |||
| 150 | /** | 185 | /** |
| 151 | * instrument_get_user() - add instrumentation to get_user()-like macros | 186 | * instrument_get_user() - add instrumentation to get_user()-like macros |
| 152 | * @to: destination variable, may not be address-taken | 187 | * @to: destination variable, may not be address-taken |
| @@ -464,10 +464,8 @@ static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { · 463 unmodified lines | |||
| 464 | 464 | ||
| 465 | extern bool kexec_file_dbg_print; | 465 | extern bool kexec_file_dbg_print; |
| 466 | 466 | ||
| 467 | #define kexec_dprintk(fmt, ...) \ | 467 | #define kexec_dprintk(fmt, arg...) \ |
| 468 | printk("%s" fmt, \ | 468 | do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) |
| 469 | kexec_file_dbg_print ? KERN_INFO : KERN_DEBUG, \ | ||
| 470 | ##__VA_ARGS__) | ||
| 471 | 469 | ||
| 472 | #else /* !CONFIG_KEXEC_CORE */ | 470 | #else /* !CONFIG_KEXEC_CORE */ |
| 473 | struct pt_regs; | 471 | struct pt_regs; |
| @@ -36,10 +36,15 @@ · 35 unmodified lines | |||
| 36 | * to lock the reader. | 36 | * to lock the reader. |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | #include <linux/kernel.h> | 39 | #include <linux/array_size.h> |
| 40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
| 41 | #include <linux/stddef.h> | 41 | #include <linux/stddef.h> |
| 42 | #include <linux/scatterlist.h> | 42 | #include <linux/types.h> |
| 43 | |||
| 44 | #include <asm/barrier.h> | ||
| 45 | #include <asm/errno.h> | ||
| 46 | |||
| 47 | struct scatterlist; | ||
| 43 | 48 | ||
| 44 | struct __kfifo { | 49 | struct __kfifo { |
| 45 | unsigned int in; | 50 | unsigned int in; |
| @@ -61,6 +61,17 @@ void kmsan_check_memory(const void *address, size_t size); · 60 unmodified lines | |||
| 61 | void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy, | 61 | void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy, |
| 62 | size_t left); | 62 | size_t left); |
| 63 | 63 | ||
| 64 | /** | ||
| 65 | * kmsan_memmove() - Notify KMSAN about a data copy within kernel. | ||
| 66 | * @to: destination address in the kernel. | ||
| 67 | * @from: source address in the kernel. | ||
| 68 | * @size: number of bytes to copy. | ||
| 69 | * | ||
| 70 | * Invoked after non-instrumented version (e.g. implemented using assembly | ||
| 71 | * code) of memmove()/memcpy() is called, in order to copy KMSAN's metadata. | ||
| 72 | */ | ||
| 73 | void kmsan_memmove(void *to, const void *from, size_t to_copy); | ||
| 74 | |||
| 64 | #else | 75 | #else |
| 65 | 76 | ||
| 66 | static inline void kmsan_poison_memory(const void *address, size_t size, | 77 | static inline void kmsan_poison_memory(const void *address, size_t size, |
| @@ -78,6 +89,10 @@ static inline void kmsan_copy_to_user(void __user *to, const void *from, · 11 unmodified lines | |||
| 78 | { | 89 | { |
| 79 | } | 90 | } |
| 80 | 91 | ||
| 92 | static inline void kmsan_memmove(void *to, const void *from, size_t to_copy) | ||
| 93 | { | ||
| 94 | } | ||
| 95 | |||
| 81 | #endif | 96 | #endif |
| 82 | 97 | ||
| 83 | #endif /* _LINUX_KMSAN_CHECKS_H */ | 98 | #endif /* _LINUX_KMSAN_CHECKS_H */ |
| @@ -105,10 +105,12 @@ void watchdog_hardlockup_check(unsigned int cpu, struct pt_regs *regs); · 104 unmodified lines | |||
| 105 | extern void hardlockup_detector_perf_stop(void); | 105 | extern void hardlockup_detector_perf_stop(void); |
| 106 | extern void hardlockup_detector_perf_restart(void); | 106 | extern void hardlockup_detector_perf_restart(void); |
| 107 | extern void hardlockup_detector_perf_cleanup(void); | 107 | extern void hardlockup_detector_perf_cleanup(void); |
| 108 | extern void hardlockup_config_perf_event(const char *str); | ||
| 108 | #else | 109 | #else |
| 109 | static inline void hardlockup_detector_perf_stop(void) { } | 110 | static inline void hardlockup_detector_perf_stop(void) { } |
| 110 | static inline void hardlockup_detector_perf_restart(void) { } | 111 | static inline void hardlockup_detector_perf_restart(void) { } |
| 111 | static inline void hardlockup_detector_perf_cleanup(void) { } | 112 | static inline void hardlockup_detector_perf_cleanup(void) { } |
| 113 | static inline void hardlockup_config_perf_event(const char *str) { } | ||
| 112 | #endif | 114 | #endif |
| 113 | 115 | ||
| 114 | void watchdog_hardlockup_stop(void); | 116 | void watchdog_hardlockup_stop(void); |
| @@ -200,7 +200,11 @@ TRACE_EVENT(nilfs2_mdt_submit_block, · 199 unmodified lines | |||
| 200 | __field(struct inode *, inode) | 200 | __field(struct inode *, inode) |
| 201 | __field(unsigned long, ino) | 201 | __field(unsigned long, ino) |
| 202 | __field(unsigned long, blkoff) | 202 | __field(unsigned long, blkoff) |
| 203 | __field(enum req_op, mode) | 203 | /* |
| 204 | * Use field_struct() to avoid is_signed_type() on the | ||
| 205 | * bitwise type enum req_op. | ||
| 206 | */ | ||
| 207 | __field_struct(enum req_op, mode) | ||
| 204 | ), | 208 | ), |
| 205 | 209 | ||
| 206 | TP_fast_assign( | 210 | TP_fast_assign( |
| @@ -29,7 +29,6 @@ static struct ctl_table kern_do_mounts_initrd_table[] = { · 28 unmodified lines | |||
| 29 | .mode = 0644, | 29 | .mode = 0644, |
| 30 | .proc_handler = proc_dointvec, | 30 | .proc_handler = proc_dointvec, |
| 31 | }, | 31 | }, |
| 32 | { } | ||
| 33 | }; | 32 | }; |
| 34 | 33 | ||
| 35 | static __init int kernel_do_mounts_initrd_sysctls_init(void) | 34 | static __init int kernel_do_mounts_initrd_sysctls_init(void) |
| @@ -345,6 +345,11 @@ static int __init xbc_snprint_cmdline(char *buf, size_t size, · 344 unmodified lines | |||
| 345 | continue; | 345 | continue; |
| 346 | } | 346 | } |
| 347 | xbc_array_for_each_value(vnode, val) { | 347 | xbc_array_for_each_value(vnode, val) { |
| 348 | /* | ||
| 349 | * For prettier and more readable /proc/cmdline, only | ||
| 350 | * quote the value when necessary, i.e. when it contains | ||
| 351 | * whitespace. | ||
| 352 | */ | ||
| 348 | q = strpbrk(val, " \t\r\n") ? "\"" : ""; | 353 | q = strpbrk(val, " \t\r\n") ? "\"" : ""; |
| 349 | ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ", | 354 | ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ", |
| 350 | xbc_namebuf, q, val, q); | 355 | xbc_namebuf, q, val, q); |
| @@ -881,6 +886,19 @@ static void __init print_unknown_bootoptions(void) · 530 unmodified lines | |||
| 881 | memblock_free(unknown_options, len); | 886 | memblock_free(unknown_options, len); |
| 882 | } | 887 | } |
| 883 | 888 | ||
| 889 | static void __init early_numa_node_init(void) | ||
| 890 | { | ||
| 891 | #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID | ||
| 892 | #ifndef cpu_to_node | ||
| 893 | int cpu; | ||
| 894 | |||
| 895 | /* The early_cpu_to_node() should be ready here. */ | ||
| 896 | for_each_possible_cpu(cpu) | ||
| 897 | set_cpu_numa_node(cpu, early_cpu_to_node(cpu)); | ||
| 898 | #endif | ||
| 899 | #endif | ||
| 900 | } | ||
| 901 | |||
| 884 | asmlinkage __visible __init __no_sanitize_address __noreturn __no_stack_protector | 902 | asmlinkage __visible __init __no_sanitize_address __noreturn __no_stack_protector |
| 885 | void start_kernel(void) | 903 | void start_kernel(void) |
| 886 | { | 904 | { |
| @@ -911,6 +929,7 @@ void start_kernel(void) · 24 unmodified lines | |||
| 911 | setup_nr_cpu_ids(); | 929 | setup_nr_cpu_ids(); |
| 912 | setup_per_cpu_areas(); | 930 | setup_per_cpu_areas(); |
| 913 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ | 931 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ |
| 932 | early_numa_node_init(); | ||
| 914 | boot_cpu_hotplug_init(); | 933 | boot_cpu_hotplug_init(); |
| 915 | 934 | ||
| 916 | pr_notice("Kernel command line: %s\n", saved_command_line); | 935 | pr_notice("Kernel command line: %s\n", saved_command_line); |
| @@ -178,7 +178,6 @@ static struct ctl_table ipc_sysctls[] = { · 177 unmodified lines | |||
| 178 | .extra2 = SYSCTL_INT_MAX, | 178 | .extra2 = SYSCTL_INT_MAX, |
| 179 | }, | 179 | }, |
| 180 | #endif | 180 | #endif |
| 181 | {} | ||
| 182 | }; | 181 | }; |
| 183 | 182 | ||
| 184 | static struct ctl_table_set *set_lookup(struct ctl_table_root *root) | 183 | static struct ctl_table_set *set_lookup(struct ctl_table_root *root) |
| @@ -64,7 +64,6 @@ static struct ctl_table mq_sysctls[] = { · 63 unmodified lines | |||
| 64 | .extra1 = &msg_maxsize_limit_min, | 64 | .extra1 = &msg_maxsize_limit_min, |
| 65 | .extra2 = &msg_maxsize_limit_max, | 65 | .extra2 = &msg_maxsize_limit_max, |
| 66 | }, | 66 | }, |
| 67 | {} | ||
| 68 | }; | 67 | }; |
| 69 | 68 | ||
| 70 | static struct ctl_table_set *set_lookup(struct ctl_table_root *root) | 69 | static struct ctl_table_set *set_lookup(struct ctl_table_root *root) |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> | 4 | * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 8 | |||
| 7 | #include <linux/buildid.h> | 9 | #include <linux/buildid.h> |
| 8 | #include <linux/init.h> | 10 | #include <linux/init.h> |
| 9 | #include <linux/utsname.h> | 11 | #include <linux/utsname.h> |
| @@ -109,7 +109,7 @@ static int __init parse_crashkernel_mem(char *cmdline, · 108 unmodified lines | |||
| 109 | 109 | ||
| 110 | size = memparse(cur, &tmp); | 110 | size = memparse(cur, &tmp); |
| 111 | if (cur == tmp) { | 111 | if (cur == tmp) { |
| 112 | pr_warn("Memory value expected\n"); | 112 | pr_warn("crashkernel: Memory value expected\n"); |
| 113 | return -EINVAL; | 113 | return -EINVAL; |
| 114 | } | 114 | } |
| 115 | cur = tmp; | 115 | cur = tmp; |
| @@ -132,7 +132,7 @@ static int __init parse_crashkernel_mem(char *cmdline, · 16 unmodified lines | |||
| 132 | cur++; | 132 | cur++; |
| 133 | *crash_base = memparse(cur, &tmp); | 133 | *crash_base = memparse(cur, &tmp); |
| 134 | if (cur == tmp) { | 134 | if (cur == tmp) { |
| 135 | pr_warn("Memory value expected after '@'\n"); | 135 | pr_warn("crahskernel: Memory value expected after '@'\n"); |
| 136 | return -EINVAL; | 136 | return -EINVAL; |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| @@ -627,7 +627,8 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, · 626 unmodified lines | |||
| 627 | mode = kcov_get_mode(remote_arg->trace_mode); | 627 | mode = kcov_get_mode(remote_arg->trace_mode); |
| 628 | if (mode < 0) | 628 | if (mode < 0) |
| 629 | return mode; | 629 | return mode; |
| 630 | if (remote_arg->area_size > LONG_MAX / sizeof(unsigned long)) | 630 | if ((unsigned long)remote_arg->area_size > |
| 631 | LONG_MAX / sizeof(unsigned long)) | ||
| 631 | return -EINVAL; | 632 | return -EINVAL; |
| 632 | kcov->mode = mode; | 633 | kcov->mode = mode; |
| 633 | t->kcov = kcov; | 634 | t->kcov = kcov; |
| @@ -16,14 +16,14 @@ static int __regset_get(struct task_struct *target, · 15 unmodified lines | |||
| 16 | if (size > regset->n * regset->size) | 16 | if (size > regset->n * regset->size) |
| 17 | size = regset->n * regset->size; | 17 | size = regset->n * regset->size; |
| 18 | if (!p) { | 18 | if (!p) { |
| 19 | to_free = p = kzalloc(size, GFP_KERNEL); | 19 | to_free = p = kvzalloc(size, GFP_KERNEL); |
| 20 | if (!p) | 20 | if (!p) |
| 21 | return -ENOMEM; | 21 | return -ENOMEM; |
| 22 | } | 22 | } |
| 23 | res = regset->regset_get(target, regset, | 23 | res = regset->regset_get(target, regset, |
| 24 | (struct membuf){.p = p, .left = size}); | 24 | (struct membuf){.p = p, .left = size}); |
| 25 | if (res < 0) { | 25 | if (res < 0) { |
| 26 | kfree(to_free); | 26 | kvfree(to_free); |
| 27 | return res; | 27 | return res; |
| 28 | } | 28 | } |
| 29 | *data = p; | 29 | *data = p; |
| @@ -71,6 +71,6 @@ int copy_regset_to_user(struct task_struct *target, · 41 unmodified lines | |||
| 71 | ret = regset_get_alloc(target, regset, size, &buf); | 71 | ret = regset_get_alloc(target, regset, size, &buf); |
| 72 | if (ret > 0) | 72 | if (ret > 0) |
| 73 | ret = copy_to_user(data, buf, ret) ? -EFAULT : 0; | 73 | ret = copy_to_user(data, buf, ret) ? -EFAULT : 0; |
| 74 | kfree(buf); | 74 | kvfree(buf); |
| 75 | return ret; | 75 | return ret; |
| 76 | } | 76 | } |
| @@ -524,8 +524,7 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, · 523 unmodified lines | |||
| 524 | if (!buts->buf_size || !buts->buf_nr) | 524 | if (!buts->buf_size || !buts->buf_nr) |
| 525 | return -EINVAL; | 525 | return -EINVAL; |
| 526 | 526 | ||
| 527 | strncpy(buts->name, name, BLKTRACE_BDEV_SIZE); | 527 | strscpy_pad(buts->name, name, BLKTRACE_BDEV_SIZE); |
| 528 | buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0'; | ||
| 529 | 528 | ||
| 530 | /* | 529 | /* |
| 531 | * some device names have larger paths - convert the slashes | 530 | * some device names have larger paths - convert the slashes |
| @@ -78,6 +78,7 @@ void __init hardlockup_detector_disable(void) · 77 unmodified lines | |||
| 78 | 78 | ||
| 79 | static int __init hardlockup_panic_setup(char *str) | 79 | static int __init hardlockup_panic_setup(char *str) |
| 80 | { | 80 | { |
| 81 | next: | ||
| 81 | if (!strncmp(str, "panic", 5)) | 82 | if (!strncmp(str, "panic", 5)) |
| 82 | hardlockup_panic = 1; | 83 | hardlockup_panic = 1; |
| 83 | else if (!strncmp(str, "nopanic", 7)) | 84 | else if (!strncmp(str, "nopanic", 7)) |
| @@ -86,6 +87,14 @@ static int __init hardlockup_panic_setup(char *str) · 2 unmodified lines | |||
| 86 | watchdog_hardlockup_user_enabled = 0; | 87 | watchdog_hardlockup_user_enabled = 0; |
| 87 | else if (!strncmp(str, "1", 1)) | 88 | else if (!strncmp(str, "1", 1)) |
| 88 | watchdog_hardlockup_user_enabled = 1; | 89 | watchdog_hardlockup_user_enabled = 1; |
| 90 | else if (!strncmp(str, "r", 1)) | ||
| 91 | hardlockup_config_perf_event(str + 1); | ||
| 92 | while (*(str++)) { | ||
| 93 | if (*str == ',') { | ||
| 94 | str++; | ||
| 95 | goto next; | ||
| 96 | } | ||
| 97 | } | ||
| 89 | return 1; | 98 | return 1; |
| 90 | } | 99 | } |
| 91 | __setup("nmi_watchdog=", hardlockup_panic_setup); | 100 | __setup("nmi_watchdog=", hardlockup_panic_setup); |
| @@ -90,6 +90,14 @@ static struct perf_event_attr wd_hw_attr = { · 89 unmodified lines | |||
| 90 | .disabled = 1, | 90 | .disabled = 1, |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static struct perf_event_attr fallback_wd_hw_attr = { | ||
| 94 | .type = PERF_TYPE_HARDWARE, | ||
| 95 | .config = PERF_COUNT_HW_CPU_CYCLES, | ||
| 96 | .size = sizeof(struct perf_event_attr), | ||
| 97 | .pinned = 1, | ||
| 98 | .disabled = 1, | ||
| 99 | }; | ||
| 100 | |||
| 93 | /* Callback function for perf event subsystem */ | 101 | /* Callback function for perf event subsystem */ |
| 94 | static void watchdog_overflow_callback(struct perf_event *event, | 102 | static void watchdog_overflow_callback(struct perf_event *event, |
| 95 | struct perf_sample_data *data, | 103 | struct perf_sample_data *data, |
| @@ -122,6 +130,13 @@ static int hardlockup_detector_event_create(void) · 26 unmodified lines | |||
| 122 | /* Try to register using hardware perf events */ | 130 | /* Try to register using hardware perf events */ |
| 123 | evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, | 131 | evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, |
| 124 | watchdog_overflow_callback, NULL); | 132 | watchdog_overflow_callback, NULL); |
| 133 | if (IS_ERR(evt)) { | ||
| 134 | wd_attr = &fallback_wd_hw_attr; | ||
| 135 | wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); | ||
| 136 | evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, | ||
| 137 | watchdog_overflow_callback, NULL); | ||
| 138 | } | ||
| 139 | |||
| 125 | if (IS_ERR(evt)) { | 140 | if (IS_ERR(evt)) { |
| 126 | pr_debug("Perf event create on CPU %d failed with %ld\n", cpu, | 141 | pr_debug("Perf event create on CPU %d failed with %ld\n", cpu, |
| 127 | PTR_ERR(evt)); | 142 | PTR_ERR(evt)); |
| @@ -133,7 +148,6 @@ static int hardlockup_detector_event_create(void) · 5 unmodified lines | |||
| 133 | 148 | ||
| 134 | /** | 149 | /** |
| 135 | * watchdog_hardlockup_enable - Enable the local event | 150 | * watchdog_hardlockup_enable - Enable the local event |
| 136 | * | ||
| 137 | * @cpu: The CPU to enable hard lockup on. | 151 | * @cpu: The CPU to enable hard lockup on. |
| 138 | */ | 152 | */ |
| 139 | void watchdog_hardlockup_enable(unsigned int cpu) | 153 | void watchdog_hardlockup_enable(unsigned int cpu) |
| @@ -152,7 +166,6 @@ void watchdog_hardlockup_enable(unsigned int cpu) · 12 unmodified lines | |||
| 152 | 166 | ||
| 153 | /** | 167 | /** |
| 154 | * watchdog_hardlockup_disable - Disable the local event | 168 | * watchdog_hardlockup_disable - Disable the local event |
| 155 | * | ||
| 156 | * @cpu: The CPU to enable hard lockup on. | 169 | * @cpu: The CPU to enable hard lockup on. |
| 157 | */ | 170 | */ |
| 158 | void watchdog_hardlockup_disable(unsigned int cpu) | 171 | void watchdog_hardlockup_disable(unsigned int cpu) |
| @@ -259,3 +272,33 @@ int __init watchdog_hardlockup_probe(void) · 100 unmodified lines | |||
| 259 | } | 272 | } |
| 260 | return ret; | 273 | return ret; |
| 261 | } | 274 | } |
| 275 | |||
| 276 | /** | ||
| 277 | * hardlockup_config_perf_event - Overwrite config of wd_hw_attr. | ||
| 278 | * @str: number which identifies the raw perf event to use | ||
| 279 | */ | ||
| 280 | void __init hardlockup_config_perf_event(const char *str) | ||
| 281 | { | ||
| 282 | u64 config; | ||
| 283 | char buf[24]; | ||
| 284 | char *comma = strchr(str, ','); | ||
| 285 | |||
| 286 | if (!comma) { | ||
| 287 | if (kstrtoull(str, 16, &config)) | ||
| 288 | return; | ||
| 289 | } else { | ||
| 290 | unsigned int len = comma - str; | ||
| 291 | |||
| 292 | if (len >= sizeof(buf)) | ||
| 293 | return; | ||
| 294 | |||
| 295 | if (strscpy(buf, str, sizeof(buf)) < 0) | ||
| 296 | return; | ||
| 297 | buf[len] = 0; | ||
| 298 | if (kstrtoull(buf, 16, &config)) | ||
| 299 | return; | ||
| 300 | } | ||
| 301 | |||
| 302 | wd_hw_attr.type = PERF_TYPE_RAW; | ||
| 303 | wd_hw_attr.config = config; | ||
| 304 | } | ||
| @@ -122,6 +122,7 @@ config KDB_DEFAULT_ENABLE · 121 unmodified lines | |||
| 122 | config KDB_KEYBOARD | 122 | config KDB_KEYBOARD |
| 123 | bool "KGDB_KDB: keyboard as input device" | 123 | bool "KGDB_KDB: keyboard as input device" |
| 124 | depends on VT && KGDB_KDB && !PARISC | 124 | depends on VT && KGDB_KDB && !PARISC |
| 125 | depends on HAS_IOPORT | ||
| 125 | default n | 126 | default n |
| 126 | help | 127 | help |
| 127 | KDB can use a PS/2 type keyboard for an input device | 128 | KDB can use a PS/2 type keyboard for an input device |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | # | 8 | # |
| 9 | 9 | ||
| 10 | use strict; | 10 | use strict; |
| 11 | use Cwd qw(abs_path); | ||
| 11 | 12 | ||
| 12 | my @names = (); | 13 | my @names = (); |
| 13 | my @oids = (); | 14 | my @oids = (); |
| @@ -17,6 +18,8 @@ if ($#ARGV != 1) { · 3 unmodified lines | |||
| 17 | exit(2); | 18 | exit(2); |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 21 | my $abs_srctree = abs_path($ENV{'srctree'}); | ||
| 22 | |||
| 20 | # | 23 | # |
| 21 | # Open the file to read from | 24 | # Open the file to read from |
| 22 | # | 25 | # |
| @@ -35,7 +38,7 @@ close IN_FILE || die; · 12 unmodified lines | |||
| 35 | # | 38 | # |
| 36 | open C_FILE, ">$ARGV[1]" or die; | 39 | open C_FILE, ">$ARGV[1]" or die; |
| 37 | print C_FILE "/*\n"; | 40 | print C_FILE "/*\n"; |
| 38 | print C_FILE " * Automatically generated by ", $0, ". Do not edit\n"; | 41 | print C_FILE " * Automatically generated by ", $0 =~ s#^\Q$abs_srctree/\E##r, ". Do not edit\n"; |
| 39 | print C_FILE " */\n"; | 42 | print C_FILE " */\n"; |
| 40 | 43 | ||
| 41 | # | 44 | # |
| @@ -1,10 +1,13 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/bug.h> | ||
| 2 | #include <linux/device.h> | 3 | #include <linux/device.h> |
| 3 | #include <linux/err.h> | 4 | #include <linux/errno.h> |
| 4 | #include <linux/io.h> | ||
| 5 | #include <linux/gfp.h> | ||
| 6 | #include <linux/export.h> | 5 | #include <linux/export.h> |
| 6 | #include <linux/gfp_types.h> | ||
| 7 | #include <linux/io.h> | ||
| 8 | #include <linux/ioport.h> | ||
| 7 | #include <linux/of_address.h> | 9 | #include <linux/of_address.h> |
| 10 | #include <linux/types.h> | ||
| 8 | 11 | ||
| 9 | enum devm_ioremap_type { | 12 | enum devm_ioremap_type { |
| 10 | DEVM_IOREMAP = 0, | 13 | DEVM_IOREMAP = 0, |
| @@ -125,12 +128,13 @@ __devm_ioremap_resource(struct device *dev, const struct resource *res, · 114 unmodified lines | |||
| 125 | resource_size_t size; | 128 | resource_size_t size; |
| 126 | void __iomem *dest_ptr; | 129 | void __iomem *dest_ptr; |
| 127 | char *pretty_name; | 130 | char *pretty_name; |
| 131 | int ret; | ||
| 128 | 132 | ||
| 129 | BUG_ON(!dev); | 133 | BUG_ON(!dev); |
| 130 | 134 | ||
| 131 | if (!res || resource_type(res) != IORESOURCE_MEM) { | 135 | if (!res || resource_type(res) != IORESOURCE_MEM) { |
| 132 | dev_err(dev, "invalid resource %pR\n", res); | 136 | ret = dev_err_probe(dev, -EINVAL, "invalid resource %pR\n", res); |
| 133 | return IOMEM_ERR_PTR(-EINVAL); | 137 | return IOMEM_ERR_PTR(ret); |
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | if (type == DEVM_IOREMAP && res->flags & IORESOURCE_MEM_NONPOSTED) | 140 | if (type == DEVM_IOREMAP && res->flags & IORESOURCE_MEM_NONPOSTED) |
| @@ -144,20 +148,20 @@ __devm_ioremap_resource(struct device *dev, const struct resource *res, · 7 unmodified lines | |||
| 144 | else | 148 | else |
| 145 | pretty_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); | 149 | pretty_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); |
| 146 | if (!pretty_name) { | 150 | if (!pretty_name) { |
| 147 | dev_err(dev, "can't generate pretty name for resource %pR\n", res); | 151 | ret = dev_err_probe(dev, -ENOMEM, "can't generate pretty name for resource %pR\n", res); |
| 148 | return IOMEM_ERR_PTR(-ENOMEM); | 152 | return IOMEM_ERR_PTR(ret); |
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | if (!devm_request_mem_region(dev, res->start, size, pretty_name)) { | 155 | if (!devm_request_mem_region(dev, res->start, size, pretty_name)) { |
| 152 | dev_err(dev, "can't request region for resource %pR\n", res); | 156 | ret = dev_err_probe(dev, -EBUSY, "can't request region for resource %pR\n", res); |
| 153 | return IOMEM_ERR_PTR(-EBUSY); | 157 | return IOMEM_ERR_PTR(ret); |
| 154 | } | 158 | } |
| 155 | 159 | ||
| 156 | dest_ptr = __devm_ioremap(dev, res->start, size, type); | 160 | dest_ptr = __devm_ioremap(dev, res->start, size, type); |
| 157 | if (!dest_ptr) { | 161 | if (!dest_ptr) { |
| 158 | dev_err(dev, "ioremap failed for resource %pR\n", res); | ||
| 159 | devm_release_mem_region(dev, res->start, size); | 162 | devm_release_mem_region(dev, res->start, size); |
| 160 | dest_ptr = IOMEM_ERR_PTR(-ENOMEM); | 163 | ret = dev_err_probe(dev, -ENOMEM, "ioremap failed for resource %pR\n", res); |
| 164 | return IOMEM_ERR_PTR(ret); | ||
| 161 | } | 165 | } |
| 162 | 166 | ||
| 163 | return dest_ptr; | 167 | return dest_ptr; |
| @@ -5,13 +5,13 @@ · 4 unmodified lines | |||
| 5 | * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> | 5 | * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/export.h> | ||
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/err.h> | 8 | #include <linux/err.h> |
| 9 | #include <linux/export.h> | ||
| 10 | #include <linux/kfifo.h> | ||
| 12 | #include <linux/log2.h> | 11 | #include <linux/log2.h> |
| 12 | #include <linux/scatterlist.h> | ||
| 13 | #include <linux/slab.h> | ||
| 13 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
| 14 | #include <linux/kfifo.h> | ||
| 15 | 15 | ||
| 16 | /* | 16 | /* |
| 17 | * internal helper to calculate the unused elements in a fifo | 17 | * internal helper to calculate the unused elements in a fifo |
| @@ -113,7 +113,7 @@ static void __init test_hexdump_prepare_test(size_t len, int rowsize, · 112 unmodified lines | |||
| 113 | *p++ = ' '; | 113 | *p++ = ' '; |
| 114 | } while (p < test + rs * 2 + rs / gs + 1); | 114 | } while (p < test + rs * 2 + rs / gs + 1); |
| 115 | 115 | ||
| 116 | strncpy(p, data_a, l); | 116 | memcpy(p, data_a, l); |
| 117 | p += l; | 117 | p += l; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| @@ -285,6 +285,17 @@ void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy, · 284 unmodified lines | |||
| 285 | } | 285 | } |
| 286 | EXPORT_SYMBOL(kmsan_copy_to_user); | 286 | EXPORT_SYMBOL(kmsan_copy_to_user); |
| 287 | 287 | ||
| 288 | void kmsan_memmove(void *to, const void *from, size_t size) | ||
| 289 | { | ||
| 290 | if (!kmsan_enabled || kmsan_in_runtime()) | ||
| 291 | return; | ||
| 292 | |||
| 293 | kmsan_enter_runtime(); | ||
| 294 | kmsan_internal_memmove_metadata(to, (void *)from, size); | ||
| 295 | kmsan_leave_runtime(); | ||
| 296 | } | ||
| 297 | EXPORT_SYMBOL(kmsan_memmove); | ||
| 298 | |||
| 288 | /* Helper function to check an URB. */ | 299 | /* Helper function to check an URB. */ |
| 289 | void kmsan_handle_urb(const struct urb *urb, bool is_out) | 300 | void kmsan_handle_urb(const struct urb *urb, bool is_out) |
| 290 | { | 301 | { |
| @@ -6,8 +6,9 @@ · 5 unmodified lines | |||
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/kfifo.h> | 9 | #include <linux/kfifo.h> |
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/scatterlist.h> | ||
| 11 | 12 | ||
| 12 | /* | 13 | /* |
| 13 | * This module shows how to handle fifo dma operations. | 14 | * This module shows how to handle fifo dma operations. |
| @@ -6040,6 +6040,12 @@ sub process { · 6039 unmodified lines | |||
| 6040 | CHK("MACRO_ARG_PRECEDENCE", | 6040 | CHK("MACRO_ARG_PRECEDENCE", |
| 6041 | "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); | 6041 | "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); |
| 6042 | } | 6042 | } |
| 6043 | |||
| 6044 | # check if this is an unused argument | ||
| 6045 | if ($define_stmt !~ /\b$arg\b/) { | ||
| 6046 | WARN("MACRO_ARG_UNUSED", | ||
| 6047 | "Argument '$arg' is not used in function-like macro\n" . "$herectx"); | ||
| 6048 | } | ||
| 6043 | } | 6049 | } |
| 6044 | 6050 | ||
| 6045 | # check for macros with flow control, but without ## concatenation | 6051 | # check for macros with flow control, but without ## concatenation |
| @@ -26,11 +26,7 @@ def get_current_cpu(): · 25 unmodified lines | |||
| 26 | if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: | 26 | if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: |
| 27 | return gdb.selected_thread().num - 1 | 27 | return gdb.selected_thread().num - 1 |
| 28 | elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: | 28 | elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: |
| 29 | tid = gdb.selected_thread().ptid[2] | 29 | return gdb.parse_and_eval("kgdb_active.counter") |
| 30 | if tid > (0x100000000 - MAX_CPUS - 2): | ||
| 31 | return 0x100000000 - tid - 2 | ||
| 32 | else: | ||
| 33 | return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu'] | ||
| 34 | else: | 30 | else: |
| 35 | raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " | 31 | raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " |
| 36 | "supported with this gdb server.") | 32 | "supported with this gdb server.") |
| @@ -152,9 +148,8 @@ Note that VAR has to be quoted as string.""" · 115 unmodified lines | |||
| 152 | def __init__(self): | 148 | def __init__(self): |
| 153 | super(PerCpu, self).__init__("lx_per_cpu") | 149 | super(PerCpu, self).__init__("lx_per_cpu") |
| 154 | 150 | ||
| 155 | def invoke(self, var_name, cpu=-1): | 151 | def invoke(self, var, cpu=-1): |
| 156 | var_ptr = gdb.parse_and_eval("&" + var_name.string()) | 152 | return per_cpu(var.address, cpu) |
| 157 | return per_cpu(var_ptr, cpu) | ||
| 158 | 153 | ||
| 159 | 154 | ||
| 160 | PerCpu() | 155 | PerCpu() |
| @@ -85,7 +85,7 @@ thread_info_type = utils.CachedType("struct thread_info") · 84 unmodified lines | |||
| 85 | 85 | ||
| 86 | def get_thread_info(task): | 86 | def get_thread_info(task): |
| 87 | thread_info_ptr_type = thread_info_type.get_type().pointer() | 87 | thread_info_ptr_type = thread_info_type.get_type().pointer() |
| 88 | if task.type.fields()[0].type == thread_info_type.get_type(): | 88 | if task_type.get_type().fields()[0].type == thread_info_type.get_type(): |
| 89 | return task['thread_info'] | 89 | return task['thread_info'] |
| 90 | thread_info = task['stack'].cast(thread_info_ptr_type) | 90 | thread_info = task['stack'].cast(thread_info_ptr_type) |
| 91 | return thread_info.dereference() | 91 | return thread_info.dereference() |
| @@ -196,7 +196,7 @@ def get_gdbserver_type(): · 195 unmodified lines | |||
| 196 | def probe_kgdb(): | 196 | def probe_kgdb(): |
| 197 | try: | 197 | try: |
| 198 | thread_info = gdb.execute("info thread 2", to_string=True) | 198 | thread_info = gdb.execute("info thread 2", to_string=True) |
| 199 | return "shadowCPU0" in thread_info | 199 | return "shadowCPU" in thread_info |
| 200 | except gdb.error: | 200 | except gdb.error: |
| 201 | return False | 201 | return False |
| 202 | 202 | ||
| @@ -158,13 +158,13 @@ RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ · 157 unmodified lines | |||
| 158 | 158 | ||
| 159 | static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) | 159 | static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) |
| 160 | { | 160 | { |
| 161 | rb->__rb_parent_color = rb_color(rb) | (unsigned long)p; | 161 | rb->__rb_parent_color = rb_color(rb) + (unsigned long)p; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static inline void rb_set_parent_color(struct rb_node *rb, | 164 | static inline void rb_set_parent_color(struct rb_node *rb, |
| 165 | struct rb_node *p, int color) | 165 | struct rb_node *p, int color) |
| 166 | { | 166 | { |
| 167 | rb->__rb_parent_color = (unsigned long)p | color; | 167 | rb->__rb_parent_color = (unsigned long)p + color; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static inline void | 170 | static inline void |
| @@ -58,7 +58,7 @@ · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | static inline void rb_set_black(struct rb_node *rb) | 59 | static inline void rb_set_black(struct rb_node *rb) |
| 60 | { | 60 | { |
| 61 | rb->__rb_parent_color |= RB_BLACK; | 61 | rb->__rb_parent_color += RB_BLACK; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static inline struct rb_node *rb_red_parent(struct rb_node *red) | 64 | static inline struct rb_node *rb_red_parent(struct rb_node *red) |
| @@ -91,7 +91,7 @@ int main(int argc, char **argv) · 90 unmodified lines | |||
| 91 | ksft_print_header(); | 91 | ksft_print_header(); |
| 92 | ksft_set_plan(3); | 92 | ksft_set_plan(3); |
| 93 | 93 | ||
| 94 | fd2 = open(kpath, O_RDWR, 0644); | 94 | fd2 = open(kpath, O_RDWR); |
| 95 | if (fd2 < 0) { | 95 | if (fd2 < 0) { |
| 96 | perror("Can't open file"); | 96 | perror("Can't open file"); |
| 97 | ksft_exit_fail(); | 97 | ksft_exit_fail(); |