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 | 137 | CONFIG_KEXEC_CORE=y |
| 138 | 138 | |
| 139 | − Subsequently, CRASH_CORE is selected by KEXEC_CORE:: | |
| 140 | − | |
| 141 | − CONFIG_CRASH_CORE=y | |
| 142 | − | |
| 143 | 139 | 2) Enable "sysfs file system support" in "Filesystem" -> "Pseudo |
| 144 | 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 | 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 | 171 | 2) Enable "/proc/vmcore support" under "Filesystems" -> "Pseudo filesystems":: |
| 172 | 172 | |
| 173 | 173 | CONFIG_PROC_VMCORE=y |
| @@ -3787,10 +3787,12 @@ · 3786 unmodified lines | ||
| 3787 | 3787 | Format: [state][,regs][,debounce][,die] |
| 3788 | 3788 | |
| 3789 | 3789 | nmi_watchdog= [KNL,BUGS=X86] Debugging features for SMP kernels |
| 3790 | − Format: [panic,][nopanic,][num] | |
| 3790 | + Format: [panic,][nopanic,][rNNN,][num] | |
| 3791 | 3791 | Valid num: 0 or 1 |
| 3792 | 3792 | 0 - turn hardlockup detector in nmi_watchdog off |
| 3793 | 3793 | 1 - turn hardlockup detector in nmi_watchdog on |
| 3794 | + rNNN - configure the watchdog with raw perf event 0xNNN | |
| 3795 | + | |
| 3794 | 3796 | When panic is specified, panic when an NMI watchdog |
| 3795 | 3797 | timeout occurs (or 'nopanic' to not panic on an NMI |
| 3796 | 3798 | watchdog, if CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is set) |
| @@ -7507,4 +7509,3 @@ · 3710 unmodified lines | ||
| 7507 | 7509 | memory, and other data can't be written using |
| 7508 | 7510 | xmon commands. |
| 7509 | 7511 | off xmon is disabled. |
| 7510 | − | |
| @@ -906,6 +906,20 @@ Macros, Attributes and Symbols · 905 unmodified lines | ||
| 906 | 906 | |
| 907 | 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 | 923 | **SINGLE_STATEMENT_DO_WHILE_MACRO** |
| 910 | 924 | For the multi-statement macros, it is necessary to use the do-while |
| 911 | 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 | 827 | do_this(b, c); \ |
| 828 | 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 | 853 | Things to avoid when using macros: |
| 831 | 854 | |
| 832 | 855 | 1) macros that affect control flow: |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/jump_label.h> |
| 5 | 5 | #include <linux/uaccess.h> |
| 6 | 6 | #include <linux/export.h> |
| 7 | +#include <linux/instrumented.h> | |
| 7 | 8 | #include <linux/string.h> |
| 8 | 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 | 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 | − return copy_mc_fragile(dst, src, len); | |
| 66 | − if (static_cpu_has(X86_FEATURE_ERMS)) | |
| 67 | − return copy_mc_enhanced_fast_string(dst, src, len); | |
| 65 | + unsigned long ret; | |
| 66 | + | |
| 67 | + if (copy_mc_fragile_enabled) { | |
| 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 | 79 | memcpy(dst, src, len); |
| 69 | 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 | 86 | unsigned long ret; |
| 76 | 87 | |
| 77 | 88 | if (copy_mc_fragile_enabled) { |
| 89 | + instrument_copy_to_user(dst, src, len); | |
| 78 | 90 | __uaccess_begin(); |
| 79 | 91 | ret = copy_mc_fragile((__force void *)dst, src, len); |
| 80 | 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 | 96 | if (static_cpu_has(X86_FEATURE_ERMS)) { |
| 97 | + instrument_copy_to_user(dst, src, len); | |
| 85 | 98 | __uaccess_begin(); |
| 86 | 99 | ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); |
| 87 | 100 | __uaccess_end(); |
| @@ -131,8 +131,7 @@ static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc) · 130 unmodified lines | ||
| 131 | 131 | ldm_crit ("Cannot find TOCBLOCK, database may be corrupt."); |
| 132 | 132 | return false; |
| 133 | 133 | } |
| 134 | − strncpy (toc->bitmap1_name, data + 0x24, sizeof (toc->bitmap1_name)); | |
| 135 | − toc->bitmap1_name[sizeof (toc->bitmap1_name) - 1] = 0; | |
| 134 | + strscpy_pad(toc->bitmap1_name, data + 0x24, sizeof(toc->bitmap1_name)); | |
| 136 | 135 | toc->bitmap1_start = get_unaligned_be64(data + 0x2E); |
| 137 | 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 | 141 | TOC_BITMAP1, toc->bitmap1_name); |
| 143 | 142 | return false; |
| 144 | 143 | } |
| 145 | − strncpy (toc->bitmap2_name, data + 0x46, sizeof (toc->bitmap2_name)); | |
| 146 | − toc->bitmap2_name[sizeof (toc->bitmap2_name) - 1] = 0; | |
| 144 | + strscpy_pad(toc->bitmap2_name, data + 0x46, sizeof(toc->bitmap2_name)); | |
| 147 | 145 | toc->bitmap2_start = get_unaligned_be64(data + 0x50); |
| 148 | 146 | toc->bitmap2_size = get_unaligned_be64(data + 0x58); |
| 149 | 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 | 871 | if (!th) |
| 872 | 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 | 875 | if (th->id < 0) { |
| 876 | 876 | err = th->id; |
| 877 | 877 | goto err_alloc; |
| @@ -931,7 +931,7 @@ err_chrdev: · 53 unmodified lines | ||
| 931 | 931 | "intel_th/output"); |
| 932 | 932 | |
| 933 | 933 | err_ida: |
| 934 | − ida_simple_remove(&intel_th_ida, th->id); | |
| 934 | + ida_free(&intel_th_ida, th->id); | |
| 935 | 935 | |
| 936 | 936 | err_alloc: |
| 937 | 937 | kfree(th); |
| @@ -964,7 +964,7 @@ void intel_th_free(struct intel_th *th) · 26 unmodified lines | ||
| 964 | 964 | __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, |
| 965 | 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 | 969 | kfree(th); |
| 970 | 970 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | */ |
| 7 | 7 | #include <linux/clk.h> |
| 8 | 8 | #include <linux/interrupt.h> |
| 9 | +#include <linux/io.h> | |
| 9 | 10 | #include <linux/kernel.h> |
| 10 | 11 | #include <linux/mfd/syscon.h> |
| 11 | 12 | #include <linux/module.h> |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/clk.h> |
| 9 | 9 | #include <linux/interrupt.h> |
| 10 | 10 | #include <linux/module.h> |
| 11 | +#include <linux/io.h> | |
| 11 | 12 | #include <linux/of.h> |
| 12 | 13 | #include <linux/platform_device.h> |
| 13 | 14 | #include <linux/reset.h> |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/module.h> |
| 19 | 19 | #include <linux/errno.h> |
| 20 | 20 | #include <linux/interrupt.h> |
| 21 | +#include <linux/io.h> | |
| 21 | 22 | #include <linux/kernel.h> |
| 22 | 23 | #include <linux/serial_reg.h> |
| 23 | 24 | #include <linux/types.h> |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/kernel.h> |
| 7 | 7 | #include <linux/clk.h> |
| 8 | 8 | #include <linux/interrupt.h> |
| 9 | +#include <linux/io.h> | |
| 9 | 10 | #include <linux/module.h> |
| 10 | 11 | #include <linux/of.h> |
| 11 | 12 | #include <linux/platform_device.h> |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #include <linux/clk.h> |
| 14 | 14 | #include <linux/interrupt.h> |
| 15 | +#include <linux/io.h> | |
| 15 | 16 | #include <linux/module.h> |
| 16 | 17 | #include <linux/of.h> |
| 17 | 18 | #include <linux/platform_device.h> |
| @@ -64,7 +64,7 @@ static void mux_chip_release(struct device *dev) · 63 unmodified lines | ||
| 64 | 64 | { |
| 65 | 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 | 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 | 111 | mux_chip->dev.of_node = dev->of_node; |
| 112 | 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 | 115 | if (mux_chip->id < 0) { |
| 116 | 116 | int err = mux_chip->id; |
| 117 | 117 | |
| @@ -148,7 +148,7 @@ static void parport_attach(struct parport *port) · 147 unmodified lines | ||
| 148 | 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 | 152 | memset(&pps_client_cb, 0, sizeof(pps_client_cb)); |
| 153 | 153 | pps_client_cb.private = device; |
| 154 | 154 | pps_client_cb.irq_func = parport_irq; |
| @@ -188,7 +188,7 @@ err_release_dev: · 33 unmodified lines | ||
| 188 | 188 | err_unregister_dev: |
| 189 | 189 | parport_unregister_device(device->pardev); |
| 190 | 190 | err_free: |
| 191 | − ida_simple_remove(&pps_client_index, index); | |
| 191 | + ida_free(&pps_client_index, index); | |
| 192 | 192 | kfree(device); |
| 193 | 193 | } |
| 194 | 194 | |
| @@ -208,7 +208,7 @@ static void parport_detach(struct parport *port) · 13 unmodified lines | ||
| 208 | 208 | pps_unregister_source(device->pps); |
| 209 | 209 | parport_release(pardev); |
| 210 | 210 | parport_unregister_device(pardev); |
| 211 | − ida_simple_remove(&pps_client_index, device->index); | |
| 211 | + ida_free(&pps_client_index, device->index); | |
| 212 | 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 | 1934 | threads = t->next; |
| 1935 | 1935 | WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus); |
| 1936 | 1936 | for (i = 1; i < info->thread_notes; ++i) |
| 1937 | − kfree(t->notes[i].data); | |
| 1937 | + kvfree(t->notes[i].data); | |
| 1938 | 1938 | kfree(t); |
| 1939 | 1939 | } |
| 1940 | 1940 | kfree(info->psinfo.data); |
| @@ -269,6 +269,18 @@ enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, }; · 268 unmodified lines | ||
| 269 | 269 | /** |
| 270 | 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 | 284 | * This function returns zero on success, negative value on error, or one of |
| 273 | 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 - | |
| 1861 | − * @bmap: | |
| 1862 | − * @key: | |
| 1863 | − * @ptr: | |
| 1864 | − * @keys: | |
| 1865 | − * @ptrs: | |
| 1866 | − * @n: | |
| 1860 | + * nilfs_btree_convert_and_insert - Convert and insert entries into a B-tree | |
| 1861 | + * @btree: NILFS B-tree structure | |
| 1862 | + * @key: Key of the new entry to be inserted | |
| 1863 | + * @ptr: Pointer (block number) associated with the key to be inserted | |
| 1864 | + * @keys: Array of keys to be inserted in addition to @key | |
| 1865 | + * @ptrs: Array of pointers associated with @keys | |
| 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 | 1877 | int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree, |
| 1869 | 1878 | __u64 key, __u64 ptr, |
| @@ -174,7 +174,6 @@ Eend: · 173 unmodified lines | ||
| 174 | 174 | dir->i_ino, (folio->index << PAGE_SHIFT) + offs, |
| 175 | 175 | (unsigned long)le64_to_cpu(p->inode)); |
| 176 | 176 | fail: |
| 177 | − folio_set_error(folio); | |
| 178 | 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 | 177 | * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes |
| 178 | + * @nilfs: NILFS filesystem instance | |
| 178 | 179 | */ |
| 179 | 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 | 336 | extern struct nilfs_super_block * |
| 337 | 337 | nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **); |
| 338 | −extern int nilfs_store_magic_and_option(struct super_block *, | |
| 339 | − struct nilfs_super_block *, char *); | |
| 338 | +extern int nilfs_store_magic(struct super_block *sb, | |
| 339 | + struct nilfs_super_block *sbp); | |
| 340 | 340 | extern int nilfs_check_feature_compatibility(struct super_block *, |
| 341 | 341 | struct nilfs_super_block *); |
| 342 | 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 | 563 | * checkpoint |
| 564 | 564 | * @nilfs: nilfs object |
| 565 | 565 | * @sb: super block instance |
| 566 | + * @root: NILFS root instance | |
| 566 | 567 | * @ri: pointer to a nilfs_recovery_info |
| 567 | 568 | */ |
| 568 | 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 | 699 | return; |
| 699 | 700 | |
| 700 | 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 | 705 | memset(bh->b_data, 0, bh->b_size); |
| 703 | 706 | set_buffer_dirty(bh); |
| 704 | 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 | 1725 | return; |
| 1726 | 1726 | } |
| 1727 | 1727 | |
| 1728 | − if (!err) { | |
| 1729 | − if (!nilfs_folio_buffers_clean(folio)) | |
| 1730 | − filemap_dirty_folio(folio->mapping, folio); | |
| 1731 | − folio_clear_error(folio); | |
| 1732 | − } else { | |
| 1728 | + if (err || !nilfs_folio_buffers_clean(folio)) | |
| 1733 | 1729 | filemap_dirty_folio(folio->mapping, folio); |
| 1734 | − folio_set_error(folio); | |
| 1735 | − } | |
| 1736 | 1730 | |
| 1737 | 1731 | folio_end_writeback(folio); |
| 1738 | 1732 | } |
| @@ -29,13 +29,13 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/slab.h> |
| 30 | 30 | #include <linux/init.h> |
| 31 | 31 | #include <linux/blkdev.h> |
| 32 | −#include <linux/parser.h> | |
| 33 | 32 | #include <linux/crc32.h> |
| 34 | 33 | #include <linux/vfs.h> |
| 35 | 34 | #include <linux/writeback.h> |
| 36 | 35 | #include <linux/seq_file.h> |
| 37 | 36 | #include <linux/mount.h> |
| 38 | 37 | #include <linux/fs_context.h> |
| 38 | +#include <linux/fs_parser.h> | |
| 39 | 39 | #include "nilfs.h" |
| 40 | 40 | #include "export.h" |
| 41 | 41 | #include "mdt.h" |
| @@ -61,7 +61,6 @@ struct kmem_cache *nilfs_segbuf_cachep; · 19 unmodified lines | ||
| 61 | 61 | struct kmem_cache *nilfs_btree_path_cache; |
| 62 | 62 | |
| 63 | 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 | 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 | 701 | .freeze_fs = nilfs_freeze, |
| 703 | 702 | .unfreeze_fs = nilfs_unfreeze, |
| 704 | 703 | .statfs = nilfs_statfs, |
| 705 | − .remount_fs = nilfs_remount, | |
| 706 | 704 | .show_options = nilfs_show_options |
| 707 | 705 | }; |
| 708 | 706 | |
| 709 | 707 | enum { |
| 710 | − Opt_err_cont, Opt_err_panic, Opt_err_ro, | |
| 711 | − Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, | |
| 712 | − Opt_discard, Opt_nodiscard, Opt_err, | |
| 708 | + Opt_err, Opt_barrier, Opt_snapshot, Opt_order, Opt_norecovery, | |
| 709 | + Opt_discard, | |
| 713 | 710 | }; |
| 714 | 711 | |
| 715 | −static match_table_t tokens = { | |
| 716 | − {Opt_err_cont, "errors=continue"}, | |
| 717 | − {Opt_err_panic, "errors=panic"}, | |
| 718 | − {Opt_err_ro, "errors=remount-ro"}, | |
| 719 | − {Opt_barrier, "barrier"}, | |
| 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} | |
| 712 | +static const struct constant_table nilfs_param_err[] = { | |
| 713 | + {"continue", NILFS_MOUNT_ERRORS_CONT}, | |
| 714 | + {"panic", NILFS_MOUNT_ERRORS_PANIC}, | |
| 715 | + {"remount-ro", NILFS_MOUNT_ERRORS_RO}, | |
| 716 | + {} | |
| 727 | 717 | }; |
| 728 | 718 | |
| 729 | −static int parse_options(char *options, struct super_block *sb, int is_remount) | |
| 730 | −{ | |
| 731 | − struct the_nilfs *nilfs = sb->s_fs_info; | |
| 732 | − char *p; | |
| 733 | − substring_t args[MAX_OPT_ARGS]; | |
| 734 | − | |
| 735 | − if (!options) | |
| 736 | − return 1; | |
| 737 | − | |
| 738 | − while ((p = strsep(&options, ",")) != NULL) { | |
| 739 | − int token; | |
| 719 | +static const struct fs_parameter_spec nilfs_param_spec[] = { | |
| 720 | + fsparam_enum ("errors", Opt_err, nilfs_param_err), | |
| 721 | + fsparam_flag_no ("barrier", Opt_barrier), | |
| 722 | + fsparam_u64 ("cp", Opt_snapshot), | |
| 723 | + fsparam_string ("order", Opt_order), | |
| 724 | + fsparam_flag ("norecovery", Opt_norecovery), | |
| 725 | + fsparam_flag_no ("discard", Opt_discard), | |
| 726 | + {} | |
| 727 | +}; | |
| 740 | 728 | |
| 741 | − if (!*p) | |
| 742 | − continue; | |
| 729 | +struct nilfs_fs_context { | |
| 730 | + unsigned long ns_mount_opt; | |
| 731 | + __u64 cno; | |
| 732 | +}; | |
| 743 | 733 | |
| 744 | − token = match_token(p, tokens, args); | |
| 745 | − switch (token) { | |
| 746 | − case Opt_barrier: | |
| 747 | − nilfs_set_opt(nilfs, BARRIER); | |
| 748 | − break; | |
| 749 | − case Opt_nobarrier: | |
| 734 | +static int nilfs_parse_param(struct fs_context *fc, struct fs_parameter *param) | |
| 735 | +{ | |
| 736 | + struct nilfs_fs_context *nilfs = fc->fs_private; | |
| 737 | + int is_remount = fc->purpose == FS_CONTEXT_FOR_RECONFIGURE; | |
| 738 | + struct fs_parse_result result; | |
| 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 | 748 | nilfs_clear_opt(nilfs, BARRIER); |
| 751 | − break; | |
| 752 | − case Opt_order: | |
| 753 | − if (strcmp(args[0].from, "relaxed") == 0) | |
| 754 | − /* Ordered data semantics */ | |
| 755 | − nilfs_clear_opt(nilfs, STRICT_ORDER); | |
| 756 | − else if (strcmp(args[0].from, "strict") == 0) | |
| 757 | − /* Strict in-order semantics */ | |
| 758 | − nilfs_set_opt(nilfs, STRICT_ORDER); | |
| 759 | − else | |
| 760 | − return 0; | |
| 761 | − break; | |
| 762 | − case Opt_err_panic: | |
| 763 | − nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_PANIC); | |
| 764 | − break; | |
| 765 | − case Opt_err_ro: | |
| 766 | − nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_RO); | |
| 767 | − break; | |
| 768 | − case Opt_err_cont: | |
| 769 | − nilfs_write_opt(nilfs, ERROR_MODE, ERRORS_CONT); | |
| 770 | − break; | |
| 771 | − case Opt_snapshot: | |
| 772 | − if (is_remount) { | |
| 773 | − nilfs_err(sb, | |
| 774 | − "\"%s\" option is invalid for remount", | |
| 775 | − p); | |
| 776 | − return 0; | |
| 777 | − } | |
| 778 | − break; | |
| 779 | − case Opt_norecovery: | |
| 780 | − nilfs_set_opt(nilfs, NORECOVERY); | |
| 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; | |
| 749 | + else | |
| 750 | + nilfs_set_opt(nilfs, BARRIER); | |
| 751 | + break; | |
| 752 | + case Opt_order: | |
| 753 | + if (strcmp(param->string, "relaxed") == 0) | |
| 754 | + /* Ordered data semantics */ | |
| 755 | + nilfs_clear_opt(nilfs, STRICT_ORDER); | |
| 756 | + else if (strcmp(param->string, "strict") == 0) | |
| 757 | + /* Strict in-order semantics */ | |
| 758 | + nilfs_set_opt(nilfs, STRICT_ORDER); | |
| 759 | + else | |
| 760 | + return -EINVAL; | |
| 761 | + break; | |
| 762 | + case Opt_err: | |
| 763 | + nilfs->ns_mount_opt &= ~NILFS_MOUNT_ERROR_MODE; | |
| 764 | + nilfs->ns_mount_opt |= result.uint_32; | |
| 765 | + break; | |
| 766 | + case Opt_snapshot: | |
| 767 | + if (is_remount) { | |
| 768 | + struct super_block *sb = fc->root->d_sb; | |
| 769 | + | |
| 770 | + nilfs_err(sb, | |
| 771 | + "\"%s\" option is invalid for remount", | |
| 772 | + param->key); | |
| 773 | + return -EINVAL; | |
| 774 | + } | |
| 775 | + if (result.uint_64 == 0) { | |
| 776 | + nilfs_err(NULL, | |
| 777 | + "invalid option \"cp=0\": invalid checkpoint number 0"); | |
| 778 | + return -EINVAL; | |
| 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 = | |
| 803 | − NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER; | |
| 795 | + return 0; | |
| 804 | 796 | } |
| 805 | 797 | |
| 806 | 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 | 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, | |
| 861 | − struct nilfs_super_block *sbp, | |
| 862 | − char *data) | |
| 852 | +int nilfs_store_magic(struct super_block *sb, | |
| 853 | + struct nilfs_super_block *sbp) | |
| 863 | 854 | { |
| 864 | 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 | 861 | sb->s_flags |= SB_NOATIME; |
| 871 | 862 | #endif |
| 872 | 863 | |
| 873 | − nilfs_set_default_options(sb, sbp); | |
| 874 | − | |
| 875 | 864 | nilfs->ns_resuid = le16_to_cpu(sbp->s_def_resuid); |
| 876 | 865 | nilfs->ns_resgid = le16_to_cpu(sbp->s_def_resgid); |
| 877 | 866 | nilfs->ns_interval = le32_to_cpu(sbp->s_c_interval); |
| 878 | 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 | 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 | 1025 | * nilfs_fill_super() - initialize a super block instance |
| 1037 | 1026 | * @sb: super_block |
| 1038 | − * @data: mount options | |
| 1039 | − * @silent: silent mode flag | |
| 1027 | + * @fc: filesystem context | |
| 1040 | 1028 | * |
| 1041 | 1029 | * This function is called exclusively by nilfs->ns_mount_mutex. |
| 1042 | 1030 | * So, the recovery process is protected from other simultaneous mounts. |
| 1043 | 1031 | */ |
| 1044 | 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 | 1035 | struct the_nilfs *nilfs; |
| 1048 | 1036 | struct nilfs_root *fsroot; |
| 1037 | + struct nilfs_fs_context *ctx = fc->fs_private; | |
| 1049 | 1038 | __u64 cno; |
| 1050 | 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 | 1045 | sb->s_fs_info = nilfs; |
| 1057 | 1046 | |
| 1058 | − err = init_nilfs(nilfs, sb, (char *)data); | |
| 1047 | + err = init_nilfs(nilfs, sb); | |
| 1059 | 1048 | if (err) |
| 1060 | 1049 | goto failed_nilfs; |
| 1061 | 1050 | |
| 1051 | + /* Copy in parsed mount options */ | |
| 1052 | + nilfs->ns_mount_opt = ctx->ns_mount_opt; | |
| 1053 | + | |
| 1062 | 1054 | sb->s_op = &nilfs_sops; |
| 1063 | 1055 | sb->s_export_op = &nilfs_export_ops; |
| 1064 | 1056 | sb->s_root = NULL; |
| @@ -1117,34 +1109,25 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) · 52 unmodified lines | ||
| 1117 | 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 | 1116 | struct the_nilfs *nilfs = sb->s_fs_info; |
| 1123 | − unsigned long old_sb_flags; | |
| 1124 | − unsigned long old_mount_opt; | |
| 1125 | 1117 | int err; |
| 1126 | 1118 | |
| 1127 | 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 | 1121 | err = -EINVAL; |
| 1138 | 1122 | |
| 1139 | 1123 | if (!nilfs_valid_fs(nilfs)) { |
| 1140 | 1124 | nilfs_warn(sb, |
| 1141 | 1125 | "couldn't remount because the filesystem is in an incomplete recovery state"); |
| 1142 | − goto restore_opts; | |
| 1126 | + goto ignore_opts; | |
| 1143 | 1127 | } |
| 1144 | − | |
| 1145 | − if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) | |
| 1128 | + if ((bool)(fc->sb_flags & SB_RDONLY) == sb_rdonly(sb)) | |
| 1146 | 1129 | goto out; |
| 1147 | − if (*flags & SB_RDONLY) { | |
| 1130 | + if (fc->sb_flags & SB_RDONLY) { | |
| 1148 | 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 | 1155 | "couldn't remount RDWR because of unsupported optional features (%llx)", |
| 1173 | 1156 | (unsigned long long)features); |
| 1174 | 1157 | err = -EROFS; |
| 1175 | − goto restore_opts; | |
| 1158 | + goto ignore_opts; | |
| 1176 | 1159 | } |
| 1177 | 1160 | |
| 1178 | 1161 | sb->s_flags &= ~SB_RDONLY; |
| 1179 | 1162 | |
| 1180 | 1163 | root = NILFS_I(d_inode(sb->s_root))->i_root; |
| 1181 | 1164 | err = nilfs_attach_log_writer(sb, root); |
| 1182 | − if (err) | |
| 1183 | − goto restore_opts; | |
| 1165 | + if (err) { | |
| 1166 | + sb->s_flags |= SB_RDONLY; | |
| 1167 | + goto ignore_opts; | |
| 1168 | + } | |
| 1184 | 1169 | |
| 1185 | 1170 | down_write(&nilfs->ns_sem); |
| 1186 | 1171 | nilfs_setup_super(sb, true); |
| 1187 | 1172 | up_write(&nilfs->ns_sem); |
| 1188 | 1173 | } |
| 1189 | 1174 | out: |
| 1190 | − return 0; | |
| 1191 | − | |
| 1192 | − restore_opts: | |
| 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 | −} | |
| 1175 | + sb->s_flags = (sb->s_flags & ~SB_POSIXACL); | |
| 1176 | + /* Copy over parsed remount options */ | |
| 1177 | + nilfs->ns_mount_opt = ctx->ns_mount_opt; | |
| 1262 | 1178 | |
| 1263 | −static int nilfs_set_bdev_super(struct super_block *s, void *data) | |
| 1264 | −{ | |
| 1265 | − s->s_dev = *(dev_t *)data; | |
| 1266 | 1179 | return 0; |
| 1267 | −} | |
| 1268 | 1180 | |
| 1269 | −static int nilfs_test_bdev_super(struct super_block *s, void *data) | |
| 1270 | −{ | |
| 1271 | − return !(s->s_iflags & SB_I_RETIRED) && s->s_dev == *(dev_t *)data; | |
| 1181 | + ignore_opts: | |
| 1182 | + return err; | |
| 1272 | 1183 | } |
| 1273 | 1184 | |
| 1274 | −static struct dentry * | |
| 1275 | −nilfs_mount(struct file_system_type *fs_type, int flags, | |
| 1276 | − const char *dev_name, void *data) | |
| 1185 | +static int | |
| 1186 | +nilfs_get_tree(struct fs_context *fc) | |
| 1277 | 1187 | { |
| 1278 | − struct nilfs_super_data sd = { .flags = flags }; | |
| 1188 | + struct nilfs_fs_context *ctx = fc->fs_private; | |
| 1279 | 1189 | struct super_block *s; |
| 1280 | 1190 | dev_t dev; |
| 1281 | 1191 | int err; |
| 1282 | 1192 | |
| 1283 | − if (nilfs_identify(data, &sd)) | |
| 1284 | − return ERR_PTR(-EINVAL); | |
| 1193 | + if (ctx->cno && !(fc->sb_flags & SB_RDONLY)) { | |
| 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 | 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, | |
| 1291 | − &dev); | |
| 1204 | + s = sget_dev(fc, dev); | |
| 1292 | 1205 | if (IS_ERR(s)) |
| 1293 | − return ERR_CAST(s); | |
| 1206 | + return PTR_ERR(s); | |
| 1294 | 1207 | |
| 1295 | 1208 | if (!s->s_root) { |
| 1296 | − err = setup_bdev_super(s, flags, NULL); | |
| 1209 | + err = setup_bdev_super(s, fc->sb_flags, fc); | |
| 1297 | 1210 | if (!err) |
| 1298 | − err = nilfs_fill_super(s, data, | |
| 1299 | − flags & SB_SILENT ? 1 : 0); | |
| 1211 | + err = nilfs_fill_super(s, fc); | |
| 1300 | 1212 | if (err) |
| 1301 | 1213 | goto failed_super; |
| 1302 | 1214 | |
| 1303 | 1215 | s->s_flags |= SB_ACTIVE; |
| 1304 | − } else if (!sd.cno) { | |
| 1216 | + } else if (!ctx->cno) { | |
| 1305 | 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 | 1219 | nilfs_err(s, |
| 1308 | 1220 | "the device already has a %s mount.", |
| 1309 | 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 | 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 | 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); | |
| 1319 | − if (err) | |
| 1233 | + fc->root = dget(s->s_root); | |
| 1234 | + err = nilfs_reconfigure(fc); | |
| 1235 | + if (err) { | |
| 1236 | + dput(fc->root); | |
| 1237 | + fc->root = NULL; /* prevent double release */ | |
| 1320 | 1238 | goto failed_super; |
| 1239 | + } | |
| 1240 | + return 0; | |
| 1321 | 1241 | } |
| 1322 | 1242 | } |
| 1323 | 1243 | |
| 1324 | − if (sd.cno) { | |
| 1244 | + if (ctx->cno) { | |
| 1325 | 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 | 1248 | if (err) |
| 1329 | 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 | 1257 | failed_super: |
| 1336 | 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 | 1289 | struct file_system_type nilfs_fs_type = { |
| 1341 | 1290 | .owner = THIS_MODULE, |
| 1342 | 1291 | .name = "nilfs2", |
| 1343 | − .mount = nilfs_mount, | |
| 1344 | 1292 | .kill_sb = kill_block_super, |
| 1345 | 1293 | .fs_flags = FS_REQUIRES_DEV, |
| 1294 | + .init_fs_context = nilfs_init_fs_context, | |
| 1295 | + .parameters = nilfs_param_spec, | |
| 1346 | 1296 | }; |
| 1347 | 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 | 592 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
| 593 | 593 | struct buffer_head **sbh = nilfs->ns_sbh; |
| 594 | 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 | 597 | if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) { |
| 598 | 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 | 648 | if (swp) |
| 649 | 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 | 667 | nilfs->ns_sbwcount = 0; |
| 652 | 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 | 670 | *sbpp = sbp[0]; |
| 655 | 671 | return 0; |
| 656 | 672 | } |
| @@ -659,7 +675,6 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, · 2 unmodified lines | ||
| 659 | 675 | * init_nilfs - initialize a NILFS instance. |
| 660 | 676 | * @nilfs: the_nilfs structure |
| 661 | 677 | * @sb: super block |
| 662 | − * @data: mount options | |
| 663 | 678 | * |
| 664 | 679 | * init_nilfs() performs common initialization per block device (e.g. |
| 665 | 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 | 683 | * Return Value: On success, 0 is returned. On error, a negative error |
| 669 | 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 | 688 | struct nilfs_super_block *sbp; |
| 674 | 689 | int blocksize; |
| @@ -686,7 +701,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) · 11 unmodified lines | ||
| 686 | 701 | if (err) |
| 687 | 702 | goto out; |
| 688 | 703 | |
| 689 | − err = nilfs_store_magic_and_option(sb, sbp, data); | |
| 704 | + err = nilfs_store_magic(sb, sbp); | |
| 690 | 705 | if (err) |
| 691 | 706 | goto failed_sbh; |
| 692 | 707 | |
| @@ -219,10 +219,6 @@ THE_NILFS_FNS(PURGING, purging) · 218 unmodified lines | ||
| 219 | 219 | #define nilfs_set_opt(nilfs, opt) \ |
| 220 | 220 | ((nilfs)->ns_mount_opt |= NILFS_MOUNT_##opt) |
| 221 | 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 | 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 | 272 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); |
| 277 | 273 | struct the_nilfs *alloc_nilfs(struct super_block *sb); |
| 278 | 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 | 276 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb); |
| 281 | 277 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs); |
| 282 | 278 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs); |
| @@ -2283,8 +2283,6 @@ unlock: · 2282 unmodified lines | ||
| 2283 | 2283 | ocfs2_inode_unlock(inode, 1); |
| 2284 | 2284 | brelse(di_bh); |
| 2285 | 2285 | out: |
| 2286 | − if (ret < 0) | |
| 2287 | − ret = -EIO; | |
| 2288 | 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 | 1275 | struct dlm_query_nodeinfo *qn; |
| 1276 | 1276 | struct dlm_ctxt *dlm = NULL; |
| 1277 | − int locked = 0, status = -EINVAL; | |
| 1277 | + int status = -EINVAL; | |
| 1278 | 1278 | |
| 1279 | 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 | 1292 | spin_lock(&dlm->spinlock); |
| 1293 | − locked = 1; | |
| 1294 | 1293 | if (dlm->joining_node != qn->qn_nodenum) { |
| 1295 | 1294 | mlog(ML_ERROR, "Node %d queried nodes on domain %s but " |
| 1296 | 1295 | "joining node is %d\n", qn->qn_nodenum, qn->qn_domain, |
| 1297 | 1296 | dlm->joining_node); |
| 1298 | − goto bail; | |
| 1297 | + goto unlock; | |
| 1299 | 1298 | } |
| 1300 | 1299 | |
| 1301 | 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 | 1304 | "but active dlm protocol is %d.%d\n", qn->qn_nodenum, |
| 1306 | 1305 | qn->qn_domain, dlm->dlm_locking_proto.pv_major, |
| 1307 | 1306 | dlm->dlm_locking_proto.pv_minor); |
| 1308 | − goto bail; | |
| 1307 | + goto unlock; | |
| 1309 | 1308 | } |
| 1310 | 1309 | |
| 1311 | 1310 | status = dlm_match_nodes(dlm, qn); |
| 1312 | 1311 | |
| 1312 | +unlock: | |
| 1313 | + spin_unlock(&dlm->spinlock); | |
| 1313 | 1314 | bail: |
| 1314 | − if (locked) | |
| 1315 | − spin_unlock(&dlm->spinlock); | |
| 1316 | 1315 | spin_unlock(&dlm_domain_lock); |
| 1317 | 1316 | |
| 1318 | 1317 | return status; |
| @@ -1528,7 +1527,6 @@ static void dlm_send_join_asserts(struct dlm_ctxt *dlm, · 209 unmodified lines | ||
| 1528 | 1527 | { |
| 1529 | 1528 | int status, node, live; |
| 1530 | 1529 | |
| 1531 | − status = 0; | |
| 1532 | 1530 | node = -1; |
| 1533 | 1531 | while ((node = find_next_bit(node_map, O2NM_MAX_NODES, |
| 1534 | 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 | 255 | if (fh_len < 3 || fh_type > 2) |
| 256 | 256 | return NULL; |
| 257 | 257 | |
| 258 | − handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32; | |
| 259 | − handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]); | |
| 260 | − handle.ih_generation = le32_to_cpu(fid->raw[2]); | |
| 258 | + handle.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[0]) << 32; | |
| 259 | + handle.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[1]); | |
| 260 | + handle.ih_generation = le32_to_cpu((__force __le32)fid->raw[2]); | |
| 261 | 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 | 269 | if (fh_type != 2 || fh_len < 6) |
| 270 | 270 | return NULL; |
| 271 | 271 | |
| 272 | − parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32; | |
| 273 | − parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]); | |
| 274 | − parent.ih_generation = le32_to_cpu(fid->raw[5]); | |
| 272 | + parent.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[3]) << 32; | |
| 273 | + parent.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[4]); | |
| 274 | + parent.ih_generation = le32_to_cpu((__force __le32)fid->raw[5]); | |
| 275 | 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 | 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 | 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 | 1623 | static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci) |
| 1624 | +__acquires(&oi->ip_lock) | |
| 1624 | 1625 | { |
| 1625 | 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 | 1631 | static void ocfs2_inode_cache_unlock(struct ocfs2_caching_info *ci) |
| 1632 | +__releases(&oi->ip_lock) | |
| 1631 | 1633 | { |
| 1632 | 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 | 126 | ocfs2_inode->ip_attr = flags; |
| 127 | 127 | ocfs2_set_inode_flags(inode); |
| 128 | + inode_set_ctime_current(inode); | |
| 128 | 129 | |
| 129 | 130 | status = ocfs2_mark_inode_dirty(handle, inode, bh); |
| 130 | 131 | if (status < 0) |
| @@ -212,14 +212,15 @@ static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb) · 211 unmodified lines | ||
| 212 | 212 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, |
| 213 | 213 | unsigned int num_clusters) |
| 214 | 214 | { |
| 215 | − spin_lock(&osb->osb_lock); | |
| 216 | − if (osb->local_alloc_state == OCFS2_LA_DISABLED || | |
| 217 | − osb->local_alloc_state == OCFS2_LA_THROTTLED) | |
| 218 | − if (num_clusters >= osb->local_alloc_default_bits) { | |
| 215 | + if (num_clusters >= osb->local_alloc_default_bits) { | |
| 216 | + spin_lock(&osb->osb_lock); | |
| 217 | + if (osb->local_alloc_state == OCFS2_LA_DISABLED || | |
| 218 | + osb->local_alloc_state == OCFS2_LA_THROTTLED) { | |
| 219 | 219 | cancel_delayed_work(&osb->la_enable_wq); |
| 220 | 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 | 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 | 336 | "found = %u, set = %u, taken = %u, off = %u\n", |
| 336 | 337 | num_used, le32_to_cpu(alloc->id1.bitmap1.i_used), |
| 337 | 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 | 341 | status = -EINVAL; |
| 341 | 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 | 865 | numfound = bitoff = startoff = 0; |
| 865 | 866 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); |
| 866 | − while ((bitoff = ocfs2_find_next_zero_bit(bitmap, left, startoff)) != -1) { | |
| 867 | − if (bitoff == 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 | − | |
| 867 | + while ((bitoff = ocfs2_find_next_zero_bit(bitmap, left, startoff)) < | |
| 868 | + left) { | |
| 874 | 869 | /* Ok, we found a zero bit... is it contig. or do we |
| 875 | 870 | * start over?*/ |
| 876 | 871 | if (bitoff == startoff) { |
| @@ -976,9 +971,9 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, · 99 unmodified lines | ||
| 976 | 971 | start = count = 0; |
| 977 | 972 | left = le32_to_cpu(alloc->id1.bitmap1.i_total); |
| 978 | 973 | |
| 979 | − while ((bit_off = ocfs2_find_next_zero_bit(bitmap, left, start)) | |
| 980 | − != -1) { | |
| 981 | − if ((bit_off < left) && (bit_off == start)) { | |
| 974 | + while ((bit_off = ocfs2_find_next_zero_bit(bitmap, left, start)) < | |
| 975 | + left) { | |
| 976 | + if (bit_off == start) { | |
| 982 | 977 | count++; |
| 983 | 978 | start++; |
| 984 | 979 | continue; |
| @@ -1002,8 +997,7 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, · 17 unmodified lines | ||
| 1002 | 997 | goto bail; |
| 1003 | 998 | } |
| 1004 | 999 | } |
| 1005 | − if (bit_off >= left) | |
| 1006 | − break; | |
| 1000 | + | |
| 1007 | 1001 | count = 1; |
| 1008 | 1002 | start = bit_off + 1; |
| 1009 | 1003 | } |
| @@ -1220,7 +1214,7 @@ retry_enospc: · 210 unmodified lines | ||
| 1220 | 1214 | OCFS2_LOCAL_ALLOC(alloc)->la_bitmap); |
| 1221 | 1215 | |
| 1222 | 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 | 1218 | le32_to_cpu(alloc->id1.bitmap1.i_total)); |
| 1225 | 1219 | |
| 1226 | 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 | 687 | ret = ocfs2_block_group_set_bits(handle, gb_inode, gd, gd_bh, |
| 688 | − goal_bit, len); | |
| 688 | + goal_bit, len, 0, 0); | |
| 689 | 689 | if (ret) { |
| 690 | 690 | ocfs2_rollback_alloc_dinode_counts(gb_inode, gb_bh, len, |
| 691 | 691 | le16_to_cpu(gd->bg_chain)); |
| @@ -566,7 +566,7 @@ static int __ocfs2_mknod_locked(struct inode *dir, · 565 unmodified lines | ||
| 566 | 566 | fe->i_last_eb_blk = 0; |
| 567 | 567 | strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE); |
| 568 | 568 | fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL); |
| 569 | − ktime_get_real_ts64(&ts); | |
| 569 | + ktime_get_coarse_real_ts64(&ts); | |
| 570 | 570 | fe->i_atime = fe->i_ctime = fe->i_mtime = |
| 571 | 571 | cpu_to_le64(ts.tv_sec); |
| 572 | 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 | 797 | ocfs2_set_links_count(fe, inode->i_nlink); |
| 798 | 798 | fe->i_ctime = cpu_to_le64(inode_get_ctime_sec(inode)); |
| 799 | 799 | fe->i_ctime_nsec = cpu_to_le32(inode_get_ctime_nsec(inode)); |
| 800 | + ocfs2_update_inode_fsync_trans(handle, inode, 0); | |
| 800 | 801 | ocfs2_journal_dirty(handle, fe_bh); |
| 801 | 802 | |
| 802 | 803 | err = ocfs2_add_entry(handle, dentry, inode, |
| @@ -993,6 +994,7 @@ static int ocfs2_unlink(struct inode *dir, · 190 unmodified lines | ||
| 993 | 994 | drop_nlink(inode); |
| 994 | 995 | drop_nlink(inode); |
| 995 | 996 | ocfs2_set_links_count(fe, inode->i_nlink); |
| 997 | + ocfs2_update_inode_fsync_trans(handle, inode, 0); | |
| 996 | 998 | ocfs2_journal_dirty(handle, fe_bh); |
| 997 | 999 | |
| 998 | 1000 | inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); |
| @@ -883,7 +883,8 @@ struct ocfs2_group_desc · 882 unmodified lines | ||
| 883 | 883 | __le16 bg_free_bits_count; /* Free bits count */ |
| 884 | 884 | __le16 bg_chain; /* What chain I am in. */ |
| 885 | 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 | 888 | __le64 bg_next_group; /* Next group in my list, in |
| 888 | 889 | blocks */ |
| 889 | 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 | 630 | rb->rf_records.rl_count = |
| 631 | 631 | cpu_to_le16(ocfs2_refcount_recs_per_rb(osb->sb)); |
| 632 | 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 | 634 | spin_unlock(&osb->osb_lock); |
| 635 | 635 | |
| 636 | 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 | 415 | start = search_start; |
| 416 | 416 | while ((offset = ocfs2_find_next_zero_bit(bitmap, resmap->m_bitmap_len, |
| 417 | − start)) != -1) { | |
| 417 | + start)) < resmap->m_bitmap_len) { | |
| 418 | 418 | /* Search reached end of the region */ |
| 419 | 419 | if (offset >= (search_start + search_len)) |
| 420 | 420 | break; |
| @@ -91,6 +91,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, · 90 unmodified lines | ||
| 91 | 91 | u16 cl_bpc = le16_to_cpu(cl->cl_bpc); |
| 92 | 92 | u16 cl_cpg = le16_to_cpu(cl->cl_cpg); |
| 93 | 93 | u16 old_bg_clusters; |
| 94 | + u16 contig_bits; | |
| 95 | + __le16 old_bg_contig_free_bits; | |
| 94 | 96 | |
| 95 | 97 | trace_ocfs2_update_last_group_and_inode(new_clusters, |
| 96 | 98 | first_new_cluster); |
| @@ -122,6 +124,11 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, · 25 unmodified lines | ||
| 122 | 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 | 132 | ocfs2_journal_dirty(handle, group_bh); |
| 126 | 133 | |
| 127 | 134 | /* update the inode accordingly. */ |
| @@ -160,6 +167,7 @@ out_rollback: · 32 unmodified lines | ||
| 160 | 167 | le16_add_cpu(&group->bg_free_bits_count, backups); |
| 161 | 168 | le16_add_cpu(&group->bg_bits, -1 * num_bits); |
| 162 | 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 | 172 | out: |
| 165 | 173 | if (ret) |
| @@ -50,6 +50,10 @@ struct ocfs2_suballoc_result { · 49 unmodified lines | ||
| 50 | 50 | u64 sr_blkno; /* The first allocated block */ |
| 51 | 51 | unsigned int sr_bit_offset; /* The bit in the bg */ |
| 52 | 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 | 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 | 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 | 1299 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, |
| 1276 | 1300 | struct buffer_head *bg_bh, |
| 1277 | 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 | 1305 | void *bitmap; |
| 1282 | 1306 | u16 best_offset, best_size; |
| 1307 | + u16 prev_best_size = 0; | |
| 1283 | 1308 | int offset, start, found, status = 0; |
| 1284 | 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 | 1315 | found = start = best_offset = best_size = 0; |
| 1291 | 1316 | bitmap = bg->bg_bitmap; |
| 1292 | 1317 | |
| 1293 | − while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) { | |
| 1294 | − if (offset == total_bits) | |
| 1295 | − break; | |
| 1296 | − | |
| 1318 | + while ((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) < | |
| 1319 | + total_bits) { | |
| 1297 | 1320 | if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { |
| 1298 | 1321 | /* We found a zero, but we can't use it as it |
| 1299 | 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 | 1331 | /* got a zero after some ones */ |
| 1309 | 1332 | found = 1; |
| 1310 | 1333 | start = offset + 1; |
| 1334 | + prev_best_size = best_size; | |
| 1311 | 1335 | } |
| 1312 | 1336 | if (found > best_size) { |
| 1313 | 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 | 1349 | if (best_size) { |
| 1324 | 1350 | res->sr_bit_offset = best_offset; |
| 1325 | 1351 | res->sr_bits = best_size; |
| @@ -1337,11 +1363,16 @@ int ocfs2_block_group_set_bits(handle_t *handle, · 11 unmodified lines | ||
| 1337 | 1363 | struct ocfs2_group_desc *bg, |
| 1338 | 1364 | struct buffer_head *group_bh, |
| 1339 | 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 | 1370 | int status; |
| 1343 | 1371 | void *bitmap = bg->bg_bitmap; |
| 1344 | 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 | 1377 | /* All callers get the descriptor via |
| 1347 | 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 | 1404 | while(num_bits--) |
| 1374 | 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 | 1430 | ocfs2_journal_dirty(handle, group_bh); |
| 1377 | 1431 | |
| 1378 | 1432 | bail: |
| @@ -1486,7 +1540,12 @@ static int ocfs2_cluster_group_search(struct inode *inode, · 107 unmodified lines | ||
| 1486 | 1540 | |
| 1487 | 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 | 1549 | max_bits = le16_to_cpu(gd->bg_bits); |
| 1491 | 1550 | |
| 1492 | 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 | 1589 | * of bits. */ |
| 1531 | 1590 | if (min_bits <= res->sr_bits) |
| 1532 | 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 | 1594 | return search; |
| @@ -1555,7 +1607,7 @@ static int ocfs2_block_group_search(struct inode *inode, · 12 unmodified lines | ||
| 1555 | 1607 | BUG_ON(min_bits != 1); |
| 1556 | 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 | 1611 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), |
| 1560 | 1612 | group_bh, bits_wanted, |
| 1561 | 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 | 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 | 1772 | if (ret < 0) { |
| 1720 | 1773 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, ac->ac_bh, |
| 1721 | 1774 | res->sr_bits, |
| @@ -1849,7 +1902,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, · 127 unmodified lines | ||
| 1849 | 1902 | bg, |
| 1850 | 1903 | group_bh, |
| 1851 | 1904 | res->sr_bit_offset, |
| 1852 | − res->sr_bits); | |
| 1905 | + res->sr_bits, | |
| 1906 | + res->sr_max_contig_bits, | |
| 1907 | + 0); | |
| 1853 | 1908 | if (status < 0) { |
| 1854 | 1909 | ocfs2_rollback_alloc_dinode_counts(alloc_inode, |
| 1855 | 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 | 2006 | for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i ++) { |
| 1952 | 2007 | if (i == victim) |
| 1953 | 2008 | continue; |
| 1954 | − if (!cl->cl_recs[i].c_free) | |
| 2009 | + if (le32_to_cpu(cl->cl_recs[i].c_free) < bits_wanted) | |
| 1955 | 2010 | continue; |
| 1956 | 2011 | |
| 1957 | 2012 | ac->ac_chain = i; |
| @@ -2163,7 +2218,9 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle, · 205 unmodified lines | ||
| 2163 | 2218 | bg, |
| 2164 | 2219 | bg_bh, |
| 2165 | 2220 | res->sr_bit_offset, |
| 2166 | − res->sr_bits); | |
| 2221 | + res->sr_bits, | |
| 2222 | + res->sr_max_contig_bits, | |
| 2223 | + 0); | |
| 2167 | 2224 | if (ret < 0) { |
| 2168 | 2225 | ocfs2_rollback_alloc_dinode_counts(ac->ac_inode, |
| 2169 | 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 | 2439 | struct buffer_head *group_bh, |
| 2383 | 2440 | unsigned int bit_off, |
| 2384 | 2441 | unsigned int num_bits, |
| 2442 | + unsigned int max_contig_bits, | |
| 2385 | 2443 | void (*undo_fn)(unsigned int bit, |
| 2386 | 2444 | unsigned long *bmap)) |
| 2387 | 2445 | { |
| 2388 | 2446 | int status; |
| 2389 | 2447 | unsigned int tmp; |
| 2448 | + u16 contig_bits; | |
| 2390 | 2449 | struct ocfs2_group_desc *undo_bg = NULL; |
| 2391 | 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 | 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 | 2509 | if (undo_fn) |
| 2437 | 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 | 2532 | struct ocfs2_chain_list *cl = &fe->id2.i_chain; |
| 2460 | 2533 | struct buffer_head *group_bh = NULL; |
| 2461 | 2534 | struct ocfs2_group_desc *group; |
| 2535 | + __le16 old_bg_contig_free_bits = 0; | |
| 2462 | 2536 | |
| 2463 | 2537 | /* The alloc_bh comes from ocfs2_free_dinode() or |
| 2464 | 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 | 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 | 2562 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |
| 2487 | 2563 | group, group_bh, |
| 2488 | − start_bit, count, undo_fn); | |
| 2564 | + start_bit, count, 0, undo_fn); | |
| 2489 | 2565 | if (status < 0) { |
| 2490 | 2566 | mlog_errno(status); |
| 2491 | 2567 | goto bail; |
| @@ -2496,7 +2572,8 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, · 4 unmodified lines | ||
| 2496 | 2572 | if (status < 0) { |
| 2497 | 2573 | mlog_errno(status); |
| 2498 | 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 | 2577 | goto bail; |
| 2501 | 2578 | } |
| 2502 | 2579 | |
| @@ -79,12 +79,16 @@ void ocfs2_rollback_alloc_dinode_counts(struct inode *inode, · 78 unmodified lines | ||
| 79 | 79 | struct buffer_head *di_bh, |
| 80 | 80 | u32 num_bits, |
| 81 | 81 | u16 chain); |
| 82 | +u16 ocfs2_find_max_contig_free_bits(void *bitmap, | |
| 83 | + u16 total_bits, u16 start); | |
| 82 | 84 | int ocfs2_block_group_set_bits(handle_t *handle, |
| 83 | 85 | struct inode *alloc_inode, |
| 84 | 86 | struct ocfs2_group_desc *bg, |
| 85 | 87 | struct buffer_head *group_bh, |
| 86 | 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 | 93 | int ocfs2_claim_metadata(handle_t *handle, |
| 90 | 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 | 383 | /* leave now if filled buffer already */ |
| 384 | 384 | if (!iov_iter_count(iter)) |
| 385 | 385 | return acc; |
| 386 | + | |
| 387 | + cond_resched(); | |
| 386 | 388 | } |
| 387 | 389 | |
| 388 | 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 | 1372 | vdd_hdr->n_descsz = size + sizeof(vdd_hdr->dump_name); |
| 1371 | 1373 | vdd_hdr->n_type = NT_VMCOREDD; |
| 1372 | 1374 | |
| 1373 | − strncpy((char *)vdd_hdr->name, VMCOREDD_NOTE_NAME, | |
| 1374 | − sizeof(vdd_hdr->name)); | |
| 1375 | − memcpy(vdd_hdr->dump_name, data->dump_name, sizeof(vdd_hdr->dump_name)); | |
| 1375 | + strscpy_pad(vdd_hdr->name, VMCOREDD_NOTE_NAME); | |
| 1376 | + strscpy_pad(vdd_hdr->dump_name, data->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 | 375 | flush_dcache_page(page); |
| 376 | 376 | if (copied == avail) |
| 377 | 377 | SetPageUptodate(page); |
| 378 | − else | |
| 379 | − SetPageError(page); | |
| 380 | 378 | } |
| 381 | 379 | |
| 382 | 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 | 470 | res = read_blocklist(inode, index, &block); |
| 473 | 471 | if (res < 0) |
| 474 | − goto error_out; | |
| 472 | + goto out; | |
| 475 | 473 | |
| 476 | 474 | if (res == 0) |
| 477 | 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 | 481 | if (!res) |
| 484 | 482 | return 0; |
| 485 | 483 | |
| 486 | −error_out: | |
| 487 | − SetPageError(page); | |
| 488 | 484 | out: |
| 489 | 485 | pageaddr = kmap_atomic(page); |
| 490 | 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 | 106 | return 0; |
| 107 | 107 | |
| 108 | 108 | mark_errored: |
| 109 | − /* Decompression failed, mark pages as errored. Target_page is | |
| 109 | + /* Decompression failed. Target_page is | |
| 110 | 110 | * dealt with by the caller |
| 111 | 111 | */ |
| 112 | 112 | for (i = 0; i < pages; i++) { |
| 113 | 113 | if (page[i] == NULL || page[i] == target_page) |
| 114 | 114 | continue; |
| 115 | 115 | flush_dcache_page(page[i]); |
| 116 | − SetPageError(page[i]); | |
| 117 | 116 | unlock_page(page[i]); |
| 118 | 117 | put_page(page[i]); |
| 119 | 118 | } |
| @@ -62,27 +62,21 @@ · 61 unmodified lines | ||
| 62 | 62 | */ |
| 63 | 63 | static int get_dir_index_using_name(struct super_block *sb, |
| 64 | 64 | u64 *next_block, int *next_offset, u64 index_start, |
| 65 | − int index_offset, int i_count, const char *name, | |
| 66 | − int len) | |
| 65 | + int index_offset, int i_count, const char *name) | |
| 67 | 66 | { |
| 68 | 67 | struct squashfs_sb_info *msblk = sb->s_fs_info; |
| 69 | 68 | int i, length = 0, err; |
| 70 | 69 | unsigned int size; |
| 71 | 70 | struct squashfs_dir_index *index; |
| 72 | − char *str; | |
| 73 | 71 | |
| 74 | 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 | 75 | if (index == NULL) { |
| 78 | 76 | ERROR("Failed to allocate squashfs_dir_index\n"); |
| 79 | 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 | 80 | for (i = 0; i < i_count; i++) { |
| 87 | 81 | err = squashfs_read_metadata(sb, index, &index_start, |
| 88 | 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 | 96 | index->name[size] = '\0'; |
| 103 | 97 | |
| 104 | − if (strcmp(index->name, str) > 0) | |
| 98 | + if (strcmp(index->name, name) > 0) | |
| 105 | 99 | break; |
| 106 | 100 | |
| 107 | 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 | 147 | length = get_dir_index_using_name(dir->i_sb, &block, &offset, |
| 154 | 148 | squashfs_i(dir)->dir_idx_start, |
| 155 | 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 | 152 | while (length < i_size_read(dir)) { |
| 159 | 153 | /* |
| @@ -32,20 +32,19 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) |
| 34 | 34 | { |
| 35 | − struct page *page = &folio->page; | |
| 36 | − struct inode *inode = page->mapping->host; | |
| 35 | + struct inode *inode = folio->mapping->host; | |
| 37 | 36 | struct super_block *sb = inode->i_sb; |
| 38 | 37 | struct squashfs_sb_info *msblk = sb->s_fs_info; |
| 39 | − int index = page->index << PAGE_SHIFT; | |
| 38 | + int index = folio_pos(folio); | |
| 40 | 39 | u64 block = squashfs_i(inode)->start; |
| 41 | 40 | int offset = squashfs_i(inode)->offset; |
| 42 | 41 | int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE); |
| 43 | − int bytes, copied; | |
| 42 | + int bytes, copied, error; | |
| 44 | 43 | void *pageaddr; |
| 45 | 44 | struct squashfs_cache_entry *entry; |
| 46 | 45 | |
| 47 | 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 | 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 | 56 | ERROR("Unable to read symlink [%llx:%x]\n", |
| 58 | 57 | squashfs_i(inode)->start, |
| 59 | 58 | squashfs_i(inode)->offset); |
| 60 | − goto error_out; | |
| 59 | + error = bytes; | |
| 60 | + goto out; | |
| 61 | 61 | } |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | /* |
| 65 | 65 | * Read length bytes from symlink metadata. Squashfs_read_metadata |
| 66 | 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 | 68 | * squashfs_cache_get routine. As length bytes may overlap metadata |
| 69 | 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 | 75 | squashfs_i(inode)->start, |
| 76 | 76 | squashfs_i(inode)->offset); |
| 77 | 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 | 83 | copied = squashfs_copy_data(pageaddr + bytes, entry, offset, |
| 83 | 84 | length - bytes); |
| 84 | 85 | if (copied == length - bytes) |
| 85 | 86 | memset(pageaddr + length, 0, PAGE_SIZE - length); |
| 86 | 87 | else |
| 87 | 88 | block = entry->next_index; |
| 88 | − kunmap_atomic(pageaddr); | |
| 89 | + kunmap_local(pageaddr); | |
| 89 | 90 | squashfs_cache_put(entry); |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | − flush_dcache_page(page); | |
| 93 | − SetPageUptodate(page); | |
| 94 | − unlock_page(page); | |
| 95 | − return 0; | |
| 96 | − | |
| 97 | −error_out: | |
| 98 | − SetPageError(page); | |
| 99 | − unlock_page(page); | |
| 100 | − return 0; | |
| 93 | + flush_dcache_folio(folio); | |
| 94 | + error = 0; | |
| 95 | +out: | |
| 96 | + folio_end_read(folio, error == 0); | |
| 97 | + return error; | |
| 101 | 98 | } |
| 102 | 99 | |
| 103 | 100 | |
| @@ -1057,11 +1057,6 @@ void init_cpu_present(const struct cpumask *src); · 1056 unmodified lines | ||
| 1057 | 1057 | void init_cpu_possible(const struct cpumask *src); |
| 1058 | 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 | 1060 | static inline void |
| 1066 | 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 | 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 | 186 | * instrument_get_user() - add instrumentation to get_user()-like macros |
| 152 | 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 | 465 | extern bool kexec_file_dbg_print; |
| 466 | 466 | |
| 467 | −#define kexec_dprintk(fmt, ...) \ | |
| 468 | − printk("%s" fmt, \ | |
| 469 | − kexec_file_dbg_print ? KERN_INFO : KERN_DEBUG, \ | |
| 470 | − ##__VA_ARGS__) | |
| 467 | +#define kexec_dprintk(fmt, arg...) \ | |
| 468 | + do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) | |
| 471 | 469 | |
| 472 | 470 | #else /* !CONFIG_KEXEC_CORE */ |
| 473 | 471 | struct pt_regs; |
| @@ -36,10 +36,15 @@ · 35 unmodified lines | ||
| 36 | 36 | * to lock the reader. |
| 37 | 37 | */ |
| 38 | 38 | |
| 39 | −#include <linux/kernel.h> | |
| 39 | +#include <linux/array_size.h> | |
| 40 | 40 | #include <linux/spinlock.h> |
| 41 | 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 | 49 | struct __kfifo { |
| 45 | 50 | unsigned int in; |
| @@ -61,6 +61,17 @@ void kmsan_check_memory(const void *address, size_t size); · 60 unmodified lines | ||
| 61 | 61 | void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy, |
| 62 | 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 | 75 | #else |
| 65 | 76 | |
| 66 | 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 | 96 | #endif |
| 82 | 97 | |
| 83 | 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 | 105 | extern void hardlockup_detector_perf_stop(void); |
| 106 | 106 | extern void hardlockup_detector_perf_restart(void); |
| 107 | 107 | extern void hardlockup_detector_perf_cleanup(void); |
| 108 | +extern void hardlockup_config_perf_event(const char *str); | |
| 108 | 109 | #else |
| 109 | 110 | static inline void hardlockup_detector_perf_stop(void) { } |
| 110 | 111 | static inline void hardlockup_detector_perf_restart(void) { } |
| 111 | 112 | static inline void hardlockup_detector_perf_cleanup(void) { } |
| 113 | +static inline void hardlockup_config_perf_event(const char *str) { } | |
| 112 | 114 | #endif |
| 113 | 115 | |
| 114 | 116 | void watchdog_hardlockup_stop(void); |
| @@ -200,7 +200,11 @@ TRACE_EVENT(nilfs2_mdt_submit_block, · 199 unmodified lines | ||
| 200 | 200 | __field(struct inode *, inode) |
| 201 | 201 | __field(unsigned long, ino) |
| 202 | 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 | 210 | TP_fast_assign( |
| @@ -29,7 +29,6 @@ static struct ctl_table kern_do_mounts_initrd_table[] = { · 28 unmodified lines | ||
| 29 | 29 | .mode = 0644, |
| 30 | 30 | .proc_handler = proc_dointvec, |
| 31 | 31 | }, |
| 32 | − { } | |
| 33 | 32 | }; |
| 34 | 33 | |
| 35 | 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 | 345 | continue; |
| 346 | 346 | } |
| 347 | 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 | 353 | q = strpbrk(val, " \t\r\n") ? "\"" : ""; |
| 349 | 354 | ret = snprintf(buf, rest(buf, end), "%s=%s%s%s ", |
| 350 | 355 | xbc_namebuf, q, val, q); |
| @@ -881,6 +886,19 @@ static void __init print_unknown_bootoptions(void) · 530 unmodified lines | ||
| 881 | 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 | 902 | asmlinkage __visible __init __no_sanitize_address __noreturn __no_stack_protector |
| 885 | 903 | void start_kernel(void) |
| 886 | 904 | { |
| @@ -911,6 +929,7 @@ void start_kernel(void) · 24 unmodified lines | ||
| 911 | 929 | setup_nr_cpu_ids(); |
| 912 | 930 | setup_per_cpu_areas(); |
| 913 | 931 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ |
| 932 | + early_numa_node_init(); | |
| 914 | 933 | boot_cpu_hotplug_init(); |
| 915 | 934 | |
| 916 | 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 | 178 | .extra2 = SYSCTL_INT_MAX, |
| 179 | 179 | }, |
| 180 | 180 | #endif |
| 181 | − {} | |
| 182 | 181 | }; |
| 183 | 182 | |
| 184 | 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 | 64 | .extra1 = &msg_maxsize_limit_min, |
| 65 | 65 | .extra2 = &msg_maxsize_limit_max, |
| 66 | 66 | }, |
| 67 | − {} | |
| 68 | 67 | }; |
| 69 | 68 | |
| 70 | 69 | static struct ctl_table_set *set_lookup(struct ctl_table_root *root) |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 8 | + | |
| 7 | 9 | #include <linux/buildid.h> |
| 8 | 10 | #include <linux/init.h> |
| 9 | 11 | #include <linux/utsname.h> |
| @@ -109,7 +109,7 @@ static int __init parse_crashkernel_mem(char *cmdline, · 108 unmodified lines | ||
| 109 | 109 | |
| 110 | 110 | size = memparse(cur, &tmp); |
| 111 | 111 | if (cur == tmp) { |
| 112 | − pr_warn("Memory value expected\n"); | |
| 112 | + pr_warn("crashkernel: Memory value expected\n"); | |
| 113 | 113 | return -EINVAL; |
| 114 | 114 | } |
| 115 | 115 | cur = tmp; |
| @@ -132,7 +132,7 @@ static int __init parse_crashkernel_mem(char *cmdline, · 16 unmodified lines | ||
| 132 | 132 | cur++; |
| 133 | 133 | *crash_base = memparse(cur, &tmp); |
| 134 | 134 | if (cur == tmp) { |
| 135 | − pr_warn("Memory value expected after '@'\n"); | |
| 135 | + pr_warn("crahskernel: Memory value expected after '@'\n"); | |
| 136 | 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 | 627 | mode = kcov_get_mode(remote_arg->trace_mode); |
| 628 | 628 | if (mode < 0) |
| 629 | 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 | 632 | return -EINVAL; |
| 632 | 633 | kcov->mode = mode; |
| 633 | 634 | t->kcov = kcov; |
| @@ -16,14 +16,14 @@ static int __regset_get(struct task_struct *target, · 15 unmodified lines | ||
| 16 | 16 | if (size > regset->n * regset->size) |
| 17 | 17 | size = regset->n * regset->size; |
| 18 | 18 | if (!p) { |
| 19 | − to_free = p = kzalloc(size, GFP_KERNEL); | |
| 19 | + to_free = p = kvzalloc(size, GFP_KERNEL); | |
| 20 | 20 | if (!p) |
| 21 | 21 | return -ENOMEM; |
| 22 | 22 | } |
| 23 | 23 | res = regset->regset_get(target, regset, |
| 24 | 24 | (struct membuf){.p = p, .left = size}); |
| 25 | 25 | if (res < 0) { |
| 26 | − kfree(to_free); | |
| 26 | + kvfree(to_free); | |
| 27 | 27 | return res; |
| 28 | 28 | } |
| 29 | 29 | *data = p; |
| @@ -71,6 +71,6 @@ int copy_regset_to_user(struct task_struct *target, · 41 unmodified lines | ||
| 71 | 71 | ret = regset_get_alloc(target, regset, size, &buf); |
| 72 | 72 | if (ret > 0) |
| 73 | 73 | ret = copy_to_user(data, buf, ret) ? -EFAULT : 0; |
| 74 | − kfree(buf); | |
| 74 | + kvfree(buf); | |
| 75 | 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 | 524 | if (!buts->buf_size || !buts->buf_nr) |
| 525 | 525 | return -EINVAL; |
| 526 | 526 | |
| 527 | − strncpy(buts->name, name, BLKTRACE_BDEV_SIZE); | |
| 528 | − buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0'; | |
| 527 | + strscpy_pad(buts->name, name, BLKTRACE_BDEV_SIZE); | |
| 529 | 528 | |
| 530 | 529 | /* |
| 531 | 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 | 79 | static int __init hardlockup_panic_setup(char *str) |
| 80 | 80 | { |
| 81 | +next: | |
| 81 | 82 | if (!strncmp(str, "panic", 5)) |
| 82 | 83 | hardlockup_panic = 1; |
| 83 | 84 | else if (!strncmp(str, "nopanic", 7)) |
| @@ -86,6 +87,14 @@ static int __init hardlockup_panic_setup(char *str) · 2 unmodified lines | ||
| 86 | 87 | watchdog_hardlockup_user_enabled = 0; |
| 87 | 88 | else if (!strncmp(str, "1", 1)) |
| 88 | 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 | 98 | return 1; |
| 90 | 99 | } |
| 91 | 100 | __setup("nmi_watchdog=", hardlockup_panic_setup); |
| @@ -90,6 +90,14 @@ static struct perf_event_attr wd_hw_attr = { · 89 unmodified lines | ||
| 90 | 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 | 101 | /* Callback function for perf event subsystem */ |
| 94 | 102 | static void watchdog_overflow_callback(struct perf_event *event, |
| 95 | 103 | struct perf_sample_data *data, |
| @@ -122,6 +130,13 @@ static int hardlockup_detector_event_create(void) · 26 unmodified lines | ||
| 122 | 130 | /* Try to register using hardware perf events */ |
| 123 | 131 | evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, |
| 124 | 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 | 140 | if (IS_ERR(evt)) { |
| 126 | 141 | pr_debug("Perf event create on CPU %d failed with %ld\n", cpu, |
| 127 | 142 | PTR_ERR(evt)); |
| @@ -133,7 +148,6 @@ static int hardlockup_detector_event_create(void) · 5 unmodified lines | ||
| 133 | 148 | |
| 134 | 149 | /** |
| 135 | 150 | * watchdog_hardlockup_enable - Enable the local event |
| 136 | − * | |
| 137 | 151 | * @cpu: The CPU to enable hard lockup on. |
| 138 | 152 | */ |
| 139 | 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 | 168 | * watchdog_hardlockup_disable - Disable the local event |
| 155 | − * | |
| 156 | 169 | * @cpu: The CPU to enable hard lockup on. |
| 157 | 170 | */ |
| 158 | 171 | void watchdog_hardlockup_disable(unsigned int cpu) |
| @@ -259,3 +272,33 @@ int __init watchdog_hardlockup_probe(void) · 100 unmodified lines | ||
| 259 | 272 | } |
| 260 | 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 | 122 | config KDB_KEYBOARD |
| 123 | 123 | bool "KGDB_KDB: keyboard as input device" |
| 124 | 124 | depends on VT && KGDB_KDB && !PARISC |
| 125 | + depends on HAS_IOPORT | |
| 125 | 126 | default n |
| 126 | 127 | help |
| 127 | 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 | 10 | use strict; |
| 11 | +use Cwd qw(abs_path); | |
| 11 | 12 | |
| 12 | 13 | my @names = (); |
| 13 | 14 | my @oids = (); |
| @@ -17,6 +18,8 @@ if ($#ARGV != 1) { · 3 unmodified lines | ||
| 17 | 18 | exit(2); |
| 18 | 19 | } |
| 19 | 20 | |
| 21 | +my $abs_srctree = abs_path($ENV{'srctree'}); | |
| 22 | + | |
| 20 | 23 | # |
| 21 | 24 | # Open the file to read from |
| 22 | 25 | # |
| @@ -35,7 +38,7 @@ close IN_FILE || die; · 12 unmodified lines | ||
| 35 | 38 | # |
| 36 | 39 | open C_FILE, ">$ARGV[1]" or die; |
| 37 | 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 | 42 | print C_FILE " */\n"; |
| 40 | 43 | |
| 41 | 44 | # |
| @@ -1,10 +1,13 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | +#include <linux/bug.h> | |
| 2 | 3 | #include <linux/device.h> |
| 3 | −#include <linux/err.h> | |
| 4 | −#include <linux/io.h> | |
| 5 | −#include <linux/gfp.h> | |
| 4 | +#include <linux/errno.h> | |
| 6 | 5 | #include <linux/export.h> |
| 6 | +#include <linux/gfp_types.h> | |
| 7 | +#include <linux/io.h> | |
| 8 | +#include <linux/ioport.h> | |
| 7 | 9 | #include <linux/of_address.h> |
| 10 | +#include <linux/types.h> | |
| 8 | 11 | |
| 9 | 12 | enum devm_ioremap_type { |
| 10 | 13 | DEVM_IOREMAP = 0, |
| @@ -125,12 +128,13 @@ __devm_ioremap_resource(struct device *dev, const struct resource *res, · 114 unmodified lines | ||
| 125 | 128 | resource_size_t size; |
| 126 | 129 | void __iomem *dest_ptr; |
| 127 | 130 | char *pretty_name; |
| 131 | + int ret; | |
| 128 | 132 | |
| 129 | 133 | BUG_ON(!dev); |
| 130 | 134 | |
| 131 | 135 | if (!res || resource_type(res) != IORESOURCE_MEM) { |
| 132 | − dev_err(dev, "invalid resource %pR\n", res); | |
| 133 | − return IOMEM_ERR_PTR(-EINVAL); | |
| 136 | + ret = dev_err_probe(dev, -EINVAL, "invalid resource %pR\n", res); | |
| 137 | + return IOMEM_ERR_PTR(ret); | |
| 134 | 138 | } |
| 135 | 139 | |
| 136 | 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 | 148 | else |
| 145 | 149 | pretty_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); |
| 146 | 150 | if (!pretty_name) { |
| 147 | − dev_err(dev, "can't generate pretty name for resource %pR\n", res); | |
| 148 | − return IOMEM_ERR_PTR(-ENOMEM); | |
| 151 | + ret = dev_err_probe(dev, -ENOMEM, "can't generate pretty name for resource %pR\n", res); | |
| 152 | + return IOMEM_ERR_PTR(ret); | |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | 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); | |
| 153 | − return IOMEM_ERR_PTR(-EBUSY); | |
| 156 | + ret = dev_err_probe(dev, -EBUSY, "can't request region for resource %pR\n", res); | |
| 157 | + return IOMEM_ERR_PTR(ret); | |
| 154 | 158 | } |
| 155 | 159 | |
| 156 | 160 | dest_ptr = __devm_ioremap(dev, res->start, size, type); |
| 157 | 161 | if (!dest_ptr) { |
| 158 | − dev_err(dev, "ioremap failed for resource %pR\n", res); | |
| 159 | 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 | 167 | return dest_ptr; |
| @@ -5,13 +5,13 @@ · 4 unmodified lines | ||
| 5 | 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 | 8 | #include <linux/err.h> |
| 9 | +#include <linux/export.h> | |
| 10 | +#include <linux/kfifo.h> | |
| 12 | 11 | #include <linux/log2.h> |
| 12 | +#include <linux/scatterlist.h> | |
| 13 | +#include <linux/slab.h> | |
| 13 | 14 | #include <linux/uaccess.h> |
| 14 | −#include <linux/kfifo.h> | |
| 15 | 15 | |
| 16 | 16 | /* |
| 17 | 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 | 113 | *p++ = ' '; |
| 114 | 114 | } while (p < test + rs * 2 + rs / gs + 1); |
| 115 | 115 | |
| 116 | − strncpy(p, data_a, l); | |
| 116 | + memcpy(p, data_a, l); | |
| 117 | 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 | 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 | 299 | /* Helper function to check an URB. */ |
| 289 | 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 | 8 | #include <linux/init.h> |
| 9 | −#include <linux/module.h> | |
| 10 | 9 | #include <linux/kfifo.h> |
| 10 | +#include <linux/module.h> | |
| 11 | +#include <linux/scatterlist.h> | |
| 11 | 12 | |
| 12 | 13 | /* |
| 13 | 14 | * This module shows how to handle fifo dma operations. |
| @@ -6040,6 +6040,12 @@ sub process { · 6039 unmodified lines | ||
| 6040 | 6040 | CHK("MACRO_ARG_PRECEDENCE", |
| 6041 | 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 | 6051 | # check for macros with flow control, but without ## concatenation |
| @@ -26,11 +26,7 @@ def get_current_cpu(): · 25 unmodified lines | ||
| 26 | 26 | if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: |
| 27 | 27 | return gdb.selected_thread().num - 1 |
| 28 | 28 | elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: |
| 29 | − tid = gdb.selected_thread().ptid[2] | |
| 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'] | |
| 29 | + return gdb.parse_and_eval("kgdb_active.counter") | |
| 34 | 30 | else: |
| 35 | 31 | raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " |
| 36 | 32 | "supported with this gdb server.") |
| @@ -152,9 +148,8 @@ Note that VAR has to be quoted as string.""" · 115 unmodified lines | ||
| 152 | 148 | def __init__(self): |
| 153 | 149 | super(PerCpu, self).__init__("lx_per_cpu") |
| 154 | 150 | |
| 155 | − def invoke(self, var_name, cpu=-1): | |
| 156 | − var_ptr = gdb.parse_and_eval("&" + var_name.string()) | |
| 157 | − return per_cpu(var_ptr, cpu) | |
| 151 | + def invoke(self, var, cpu=-1): | |
| 152 | + return per_cpu(var.address, cpu) | |
| 158 | 153 | |
| 159 | 154 | |
| 160 | 155 | PerCpu() |
| @@ -85,7 +85,7 @@ thread_info_type = utils.CachedType("struct thread_info") · 84 unmodified lines | ||
| 85 | 85 | |
| 86 | 86 | def get_thread_info(task): |
| 87 | 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 | 89 | return task['thread_info'] |
| 90 | 90 | thread_info = task['stack'].cast(thread_info_ptr_type) |
| 91 | 91 | return thread_info.dereference() |
| @@ -196,7 +196,7 @@ def get_gdbserver_type(): · 195 unmodified lines | ||
| 196 | 196 | def probe_kgdb(): |
| 197 | 197 | try: |
| 198 | 198 | thread_info = gdb.execute("info thread 2", to_string=True) |
| 199 | − return "shadowCPU0" in thread_info | |
| 199 | + return "shadowCPU" in thread_info | |
| 200 | 200 | except gdb.error: |
| 201 | 201 | return False |
| 202 | 202 | |
| @@ -158,13 +158,13 @@ RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 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 | 164 | static inline void rb_set_parent_color(struct rb_node *rb, |
| 165 | 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 | 170 | static inline void |
| @@ -58,7 +58,7 @@ · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 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 | 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 | 91 | ksft_print_header(); |
| 92 | 92 | ksft_set_plan(3); |
| 93 | 93 | |
| 94 | − fd2 = open(kpath, O_RDWR, 0644); | |
| 94 | + fd2 = open(kpath, O_RDWR); | |
| 95 | 95 | if (fd2 < 0) { |
| 96 | 96 | perror("Can't open file"); |
| 97 | 97 | ksft_exit_fail(); |