]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to f638850417 bcachefs: bch2_trans_log_msg()
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 30 Mar 2022 21:40:25 +0000 (17:40 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Wed, 30 Mar 2022 21:40:37 +0000 (17:40 -0400)
33 files changed:
.bcachefs_revision
ccan/darray/LICENSE [deleted file]
ccan/darray/_info [deleted file]
ccan/darray/darray.h [deleted file]
cmd_debug.c
cmd_format.c
cmd_fs.c
cmd_migrate.c
include/linux/slab.h
include/linux/types.h
include/linux/vmalloc.h
include/trace/events/bcachefs.h
libbcachefs.c
libbcachefs.h
libbcachefs/alloc_background.c
libbcachefs/alloc_foreground.c
libbcachefs/bcachefs.h
libbcachefs/btree_iter.c
libbcachefs/btree_types.h
libbcachefs/btree_update.h
libbcachefs/btree_update_interior.c
libbcachefs/btree_update_leaf.c
libbcachefs/darray.h [new file with mode: 0644]
libbcachefs/fs.c
libbcachefs/fs.h
libbcachefs/fsck.c
libbcachefs/move.c
libbcachefs/subvolume.c
libbcachefs/subvolume.h
libbcachefs/subvolume_types.h
qcow2.c
tools-util.c
tools-util.h

index 4a20b81775952554da0ed2d4c97c35b59e208406..09f07f6ab5c636f0fb6ea53424ab45bcd5baf6fa 100644 (file)
@@ -1 +1 @@
-7786034caa4ee7d10d25202284220513c0944ce2
+f638850417c9042dab40511e3c3ed0b1be355301
diff --git a/ccan/darray/LICENSE b/ccan/darray/LICENSE
deleted file mode 100644 (file)
index 89de354..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/ccan/darray/_info b/ccan/darray/_info
deleted file mode 100644 (file)
index b6d5e4b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-
-#include "ccan/darray/darray.h"
-
-/**
- * darray - Generic resizable arrays
- *
- * darray is a set of macros for managing dynamically-allocated arrays.
- * It removes the tedium of managing realloc'd arrays with pointer, size, and
- * allocated size.
- *
- * Example:
- * #include <ccan/darray/darray.h>
- * #include <stdio.h>
- * 
- * int main(void) {
- *     darray(int) numbers = darray_new();
- *     char buffer[32];
- *     
- *     for (;;) {
- *             int *i;
- *             darray_foreach(i, numbers)
- *                     printf("%d ", *i);
- *             if (darray_size(numbers) > 0)
- *                     puts("");
- *             
- *             printf("darray> ");
- *             fgets(buffer, sizeof(buffer), stdin);
- *             if (*buffer == '\0' || *buffer == '\n')
- *                     break;
- *             
- *             darray_append(numbers, atoi(buffer));
- *     }
- *     
- *     darray_free(numbers);
- *     
- *     return 0;
- * }
- *
- * Author: Joey Adams <joeyadams3.14159@gmail.com>
- * License: MIT
- * Version: 0.2
- */
-int main(int argc, char *argv[])
-{
-       if (argc != 2)
-               return 1;
-
-       if (strcmp(argv[1], "depends") == 0) {
-               /* Nothing. */
-               return 0;
-       }
-
-       return 1;
-}
diff --git a/ccan/darray/darray.h b/ccan/darray/darray.h
deleted file mode 100644 (file)
index 7511241..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2011 Joseph Adams <joeyadams3.14159@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef CCAN_DARRAY_H
-#define CCAN_DARRAY_H
-
-#include <stdlib.h>
-#include <string.h>
-#include "config.h"
-
-/*
- * SYNOPSIS
- *
- * Life cycle of a darray (dynamically-allocated array):
- *
- *     darray(int) a = darray_new();
- *     darray_free(a);
- *
- *     struct {darray(int) a;} foo;
- *     darray_init(foo.a);
- *     darray_free(foo.a);
- *
- * Typedefs for darrays of common types:
- *
- *     darray_char, darray_schar, darray_uchar
- *     darray_short, darray_int, darray_long
- *     darray_ushort, darray_uint, darray_ulong
- *
- * Access:
- *
- *     T      darray_item(darray(T) arr, size_t index);
- *     size_t darray_size(darray(T) arr);
- *     size_t darray_alloc(darray(T) arr);
- *     bool   darray_empty(darray(T) arr);
- *
- * Insertion (single item):
- *
- *     void   darray_append(darray(T) arr, T item);
- *     void   darray_prepend(darray(T) arr, T item);
- *     void   darray_push(darray(T) arr, T item); // same as darray_append
- *
- * Insertion (multiple items):
- *
- *     void   darray_append_items(darray(T) arr, T *items, size_t count);
- *     void   darray_prepend_items(darray(T) arr, T *items, size_t count);
- *
- *     void   darray_appends(darray(T) arr, [T item, [...]]);
- *     void   darray_prepends(darray(T) arr, [T item, [...]]);
- *
- *     // Same functionality as above, but does not require typeof.
- *     void   darray_appends_t(darray(T) arr, #T, [T item, [...]]);
- *     void   darray_prepends_t(darray(T) arr, #T, [T item, [...]]);
- *
- * Removal:
- *
- *     T      darray_pop(darray(T) arr | darray_size(arr) != 0);
- *     T*     darray_pop_check(darray(T*) arr);
- *     void   darray_remove(darray(T) arr, size_t index);
- *
- * Replacement:
- *
- *     void   darray_from_items(darray(T) arr, T *items, size_t count);
- *     void   darray_from_c(darray(T) arr, T c_array[N]);
- *
- * String buffer:
- *
- *     void   darray_append_string(darray(char) arr, const char *str);
- *     void   darray_append_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- *     void   darray_prepend_string(darray(char) arr, const char *str);
- *     void   darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- *     void   darray_from_string(darray(T) arr, const char *str);
- *     void   darray_from_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- * Size management:
- *
- *     void   darray_resize(darray(T) arr, size_t newSize);
- *     void   darray_resize0(darray(T) arr, size_t newSize);
- *
- *     void   darray_realloc(darray(T) arr, size_t newAlloc);
- *     void   darray_growalloc(darray(T) arr, size_t newAlloc);
- *
- *     void   darray_make_room(darray(T) arr, size_t room);
- *
- * Traversal:
- *
- *     darray_foreach(T *&i, darray(T) arr) {...}
- *     darray_foreach_reverse(T *&i, darray(T) arr) {...}
- *
- * Except for darray_foreach, darray_foreach_reverse, and darray_remove,
- * all macros evaluate their non-darray arguments only once.
- */
-
-/*** Life cycle ***/
-
-#define darray(type) struct {type *item; size_t size; size_t alloc;}
-
-#define darray_new() {0,0,0}
-#define darray_init(arr) do {(arr).item=0; (arr).size=0; (arr).alloc=0;} while(0)
-#define darray_free(arr) do {free((arr).item);} while(0)
-
-
-/*
- * Typedefs for darrays of common types.  These are useful
- * when you want to pass a pointer to an darray(T) around.
- *
- * The following will produce an incompatible pointer warning:
- *
- *     void foo(darray(int) *arr);
- *     darray(int) arr = darray_new();
- *     foo(&arr);
- *
- * The workaround:
- *
- *     void foo(darray_int *arr);
- *     darray_int arr = darray_new();
- *     foo(&arr);
- */
-
-typedef darray(char)           darray_char;
-typedef darray(signed char)    darray_schar;
-typedef darray(unsigned char)  darray_uchar;
-
-typedef darray(short)          darray_short;
-typedef darray(int)            darray_int;
-typedef darray(long)           darray_long;
-
-typedef darray(unsigned short) darray_ushort;
-typedef darray(unsigned int)   darray_uint;
-typedef darray(unsigned long)  darray_ulong;
-
-
-/*** Access ***/
-
-#define darray_item(arr, i) ((arr).item[i])
-#define darray_size(arr)    ((arr).size)
-#define darray_alloc(arr)   ((arr).alloc)
-#define darray_empty(arr)   ((arr).size == 0)
-
-
-/*** Insertion (single item) ***/
-
-#define darray_append(arr, ...) do { \
-               darray_resize(arr, (arr).size+1); \
-               (arr).item[(arr).size-1] = (__VA_ARGS__); \
-       } while(0)
-#define darray_prepend(arr, ...) do { \
-               darray_resize(arr, (arr).size+1); \
-               memmove((arr).item+1, (arr).item, ((arr).size-1)*sizeof(*(arr).item)); \
-               (arr).item[0] = (__VA_ARGS__); \
-       } while(0)
-#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__)
-
-
-/*** Insertion (multiple items) ***/
-
-#define darray_append_items(arr, items, count) do { \
-               size_t __count = (count), __oldSize = (arr).size; \
-               darray_resize(arr, __oldSize + __count); \
-               memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
-       } while(0)
-
-#define darray_prepend_items(arr, items, count) do { \
-               size_t __count = (count), __oldSize = (arr).size; \
-               darray_resize(arr, __count + __oldSize); \
-               memmove((arr).item + __count, (arr).item, __oldSize * sizeof(*(arr).item)); \
-               memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
-       } while(0)
-
-#define darray_append_items_nullterminate(arr, items, count) do { \
-               size_t __count = (count), __oldSize = (arr).size; \
-               darray_resize(arr, __oldSize + __count + 1); \
-               memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
-               (arr).item[--(arr).size] = 0; \
-       } while(0)
-
-#define darray_prepend_items_nullterminate(arr, items, count) do { \
-               size_t __count = (count), __oldSize = (arr).size; \
-               darray_resize(arr, __count + __oldSize + 1); \
-               memmove((arr).item + __count, (arr).item, __oldSize * sizeof(*(arr).item)); \
-               memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
-               (arr).item[--(arr).size] = 0; \
-       } while(0)
-
-#if HAVE_TYPEOF
-#define darray_appends(arr, ...) darray_appends_t(arr, typeof((*(arr).item)), __VA_ARGS__)
-#define darray_prepends(arr, ...) darray_prepends_t(arr, typeof((*(arr).item)), __VA_ARGS__)
-#endif
-
-#define darray_appends_t(arr, type, ...) do { \
-               type __src[] = {__VA_ARGS__}; \
-               darray_append_items(arr, __src, sizeof(__src)/sizeof(*__src)); \
-       } while(0)
-#define darray_prepends_t(arr, type, ...) do { \
-               type __src[] = {__VA_ARGS__}; \
-               darray_prepend_items(arr, __src, sizeof(__src)/sizeof(*__src)); \
-       } while(0)
-
-
-/*** Removal ***/
-
-/* Warning: Do not call darray_pop on an empty darray. */
-#define darray_pop(arr) ((arr).item[--(arr).size])
-#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL)
-/* Warning, slow: Requires copying all elements after removed item. */
-#define darray_remove(arr, index) do { \
-       if (index < arr.size-1)    \
-               memmove(&(arr).item[index], &(arr).item[index+1], ((arr).size-1-i)*sizeof(*(arr).item)); \
-       (arr).size--;  \
-       } while(0)
-
-
-/*** Replacement ***/
-
-#define darray_from_items(arr, items, count) do {size_t __count = (count); darray_resize(arr, __count); memcpy((arr).item, items, __count*sizeof(*(arr).item));} while(0)
-#define darray_from_c(arr, c_array) darray_from_items(arr, c_array, sizeof(c_array)/sizeof(*(c_array)))
-
-
-/*** String buffer ***/
-
-#define darray_append_string(arr, str) do {const char *__str = (str); darray_append_items(arr, __str, strlen(__str)+1); (arr).size--;} while(0)
-#define darray_append_lit(arr, stringLiteral) do {darray_append_items(arr, stringLiteral, sizeof(stringLiteral)); (arr).size--;} while(0)
-
-#define darray_prepend_string(arr, str) do { \
-               const char *__str = (str); \
-               darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \
-       } while(0)
-#define darray_prepend_lit(arr, stringLiteral) \
-       darray_prepend_items_nullterminate(arr, stringLiteral, sizeof(stringLiteral) - 1)
-
-#define darray_from_string(arr, str) do {const char *__str = (str); darray_from_items(arr, __str, strlen(__str)+1); (arr).size--;} while(0)
-#define darray_from_lit(arr, stringLiteral) do {darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); (arr).size--;} while(0)
-
-
-/*** Size management ***/
-
-#define darray_resize(arr, newSize) darray_growalloc(arr, (arr).size = (newSize))
-#define darray_resize0(arr, newSize) do { \
-               size_t __oldSize = (arr).size, __newSize = (newSize); \
-               (arr).size = __newSize; \
-               if (__newSize > __oldSize) { \
-                       darray_growalloc(arr, __newSize); \
-                       memset(&(arr).item[__oldSize], 0, (__newSize - __oldSize) * sizeof(*(arr).item)); \
-               } \
-       } while(0)
-
-#define darray_realloc(arr, newAlloc) do { \
-               (arr).item = realloc((arr).item, ((arr).alloc = (newAlloc)) * sizeof(*(arr).item)); \
-       } while(0)
-#define darray_growalloc(arr, need) do { \
-               size_t __need = (need); \
-               if (__need > (arr).alloc) \
-                       darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \
-       } while(0)
-
-#if HAVE_STATEMENT_EXPR==1
-#define darray_make_room(arr, room) ({size_t newAlloc = (arr).size+(room); if ((arr).alloc<newAlloc) darray_realloc(arr, newAlloc); (arr).item+(arr).size; })
-#endif
-
-static inline size_t darray_next_alloc(size_t alloc, size_t need)
-{
-       if (alloc == 0)
-               alloc = 1;
-       while (alloc < need)
-               alloc *= 2;
-       return alloc;
-}
-
-
-/*** Traversal ***/
-
-/*
- * darray_foreach(T *&i, darray(T) arr) {...}
- *
- * Traverse a darray.  `i` must be declared in advance as a pointer to an item.
- */
-#define darray_foreach(i, arr) \
-       for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
-
-/*
- * darray_foreach_reverse(T *&i, darray(T) arr) {...}
- *
- * Like darray_foreach, but traverse in reverse order.
- */
-#define darray_foreach_reverse(i, arr) \
-       for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; )
-
-
-#endif /* CCAN_DARRAY_H */
-
-/*
-
-darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items;
-       if not, it increases the alloc to satisfy this requirement, allocating slack
-       space to avoid having to reallocate for every size increment.
-
-darray_from_string(arr, str) copies a string to an darray_char.
-
-darray_push(arr, item) pushes an item to the end of the darray.
-darray_pop(arr) pops it back out.  Be sure there is at least one item in the darray before calling.
-darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray.
-
-darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space.
-Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function.
-
-The following require HAVE_TYPEOF==1 :
-
-darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray.
-darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\
-
-
-Examples:
-
-       darray(int)  arr;
-       int        *i;
-       
-       darray_appends(arr, 0,1,2,3,4);
-       darray_appends(arr, -5,-4,-3,-2,-1);
-       darray_foreach(i, arr)
-               printf("%d ", *i);
-       printf("\n");
-       
-       darray_free(arr);
-       
-
-       typedef struct {int n,d;} Fraction;
-       darray(Fraction) fractions;
-       Fraction        *i;
-       
-       darray_appends(fractions, {3,4}, {3,5}, {2,1});
-       darray_foreach(i, fractions)
-               printf("%d/%d\n", i->n, i->d);
-       
-       darray_free(fractions);
-*/
index 04afea1387013ca1ee779365a328c0a7017aa947..159835b8b363beb13cc8aa8b1b94ed1e56b42afc 100644 (file)
@@ -38,12 +38,10 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd,
                            bool entire_journal)
 {
        struct bch_sb *sb = ca->disk_sb.sb;
-       ranges data;
+       ranges data = { 0 };
        unsigned i;
        int ret;
 
-       darray_init(data);
-
        /* Superblock: */
        range_add(&data, BCH_SB_LAYOUT_SECTOR << 9,
                  sizeof(struct bch_sb_layout));
@@ -110,7 +108,7 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd,
 
        qcow2_write_image(ca->disk_sb.bdev->bd_fd, fd, &data,
                          max_t(unsigned, btree_bytes(c) / 8, block_bytes(c)));
-       darray_free(data);
+       darray_exit(data);
 }
 
 int cmd_dump(int argc, char *argv[])
index d25163a7ecba0b7b76ff93805021d038038d83f2..c3debe0a95f15ea5638d78179f7117d5a92244e8 100644 (file)
 
 #include <uuid/uuid.h>
 
-#include "ccan/darray/darray.h"
-
 #include "cmds.h"
 #include "libbcachefs.h"
 #include "crypto.h"
+#include "libbcachefs/darray.h"
 #include "libbcachefs/opts.h"
 #include "libbcachefs/super-io.h"
 #include "libbcachefs/util.h"
@@ -114,17 +113,14 @@ u64 read_flag_list_or_die(char *opt, const char * const list[],
 
 int cmd_format(int argc, char *argv[])
 {
-       darray(struct dev_opts) devices;
-       darray(char *) device_paths;
+       DARRAY(struct dev_opts) devices = { 0 };
+       DARRAY(char *) device_paths = { 0 };
        struct format_opts opts = format_opts_default();
        struct dev_opts dev_opts = dev_opts_default(), *dev;
        bool force = false, no_passphrase = false, quiet = false, initialize = true, verbose = false;
        unsigned v;
        int opt;
 
-       darray_init(devices);
-       darray_init(device_paths);
-
        struct bch_opt_strs fs_opt_strs =
                bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
        struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);
@@ -201,9 +197,9 @@ int cmd_format(int argc, char *argv[])
                        initialize = false;
                        break;
                case O_no_opt:
-                       darray_append(device_paths, optarg);
+                       darray_push(device_paths, optarg);
                        dev_opts.path = optarg;
-                       darray_append(devices, dev_opts);
+                       darray_push(devices, dev_opts);
                        dev_opts.size = 0;
                        break;
                case O_quiet:
@@ -222,7 +218,7 @@ int cmd_format(int argc, char *argv[])
                        break;
                }
 
-       if (darray_empty(devices))
+       if (!devices.nr)
                die("Please supply a device");
 
        if (opts.encrypted && !no_passphrase) {
@@ -230,14 +226,14 @@ int cmd_format(int argc, char *argv[])
                initialize = false;
        }
 
-       darray_foreach(dev, devices)
+       darray_for_each(devices, dev)
                dev->fd = open_for_format(dev->path, force);
 
        struct bch_sb *sb =
                bch2_format(fs_opt_strs,
                            fs_opts,
                            opts,
-                           devices.item, darray_size(devices));
+                           devices.data, devices.nr);
        bch2_opt_strs_free(&fs_opt_strs);
 
        if (!quiet) {
@@ -257,7 +253,7 @@ int cmd_format(int argc, char *argv[])
                free(opts.passphrase);
        }
 
-       darray_free(devices);
+       darray_exit(devices);
 
        if (initialize) {
                struct bch_opts mount_opts = bch2_opts_empty();
@@ -269,17 +265,17 @@ int cmd_format(int argc, char *argv[])
                 * Start the filesystem once, to allocate the journal and create
                 * the root directory:
                 */
-               struct bch_fs *c = bch2_fs_open(device_paths.item,
-                                               darray_size(device_paths),
+               struct bch_fs *c = bch2_fs_open(device_paths.data,
+                                               device_paths.nr,
                                                mount_opts);
                if (IS_ERR(c))
-                       die("error opening %s: %s", device_paths.item[0],
+                       die("error opening %s: %s", device_paths.data[0],
                            strerror(-PTR_ERR(c)));
 
                bch2_fs_stop(c);
        }
 
-       darray_free(device_paths);
+       darray_exit(device_paths);
 
        return 0;
 }
index 6bf00c03f7b9c217a852d83fa3743499c5d94e13..3121e5b76d741f1ded6e30752eac13004ff3ad91 100644 (file)
--- a/cmd_fs.c
+++ b/cmd_fs.c
@@ -4,11 +4,10 @@
 
 #include <uuid/uuid.h>
 
-#include "ccan/darray/darray.h"
-
 #include "linux/sort.h"
 
 #include "libbcachefs/bcachefs_ioctl.h"
+#include "libbcachefs/darray.h"
 #include "libbcachefs/opts.h"
 
 #include "cmds.h"
@@ -115,7 +114,7 @@ static struct dev_name *dev_idx_to_name(dev_names *dev_names, unsigned idx)
 {
        struct dev_name *dev;
 
-       darray_foreach(dev, *dev_names)
+       darray_for_each(*dev_names, dev)
                if (dev->idx == idx)
                        return dev;
 
@@ -256,22 +255,22 @@ static void fs_usage_to_text(struct printbuf *out, const char *path)
 
        free(u);
 
-       sort(&darray_item(dev_names, 0), darray_size(dev_names),
-            sizeof(darray_item(dev_names, 0)), dev_by_label_cmp, NULL);
+       sort(dev_names.data, dev_names.nr,
+            sizeof(dev_names.data[0]), dev_by_label_cmp, NULL);
 
        out->tabstops[0] = 16;
        out->tabstops[1] = 36;
        out->tabstops[2] = 52;
        out->tabstops[3] = 68;
 
-       darray_foreach(dev, dev_names)
+       darray_for_each(dev_names, dev)
                dev_usage_to_text(out, fs, dev);
 
-       darray_foreach(dev, dev_names) {
+       darray_for_each(dev_names, dev) {
                free(dev->dev);
                free(dev->label);
        }
-       darray_free(dev_names);
+       darray_exit(dev_names);
 
        bcache_fs_close(fs);
 }
index 4da3ab1b58c6e0125f68c24e1771db4335d6b244..08ec7de28004df6eca81c97b7fd933c9b502a434 100644 (file)
@@ -530,7 +530,7 @@ static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
 
        struct fiemap_iter iter;
        struct fiemap_extent e;
-       ranges extents = { NULL };
+       ranges extents = { 0 };
 
        fiemap_for_each(fd, iter, e) {
                if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
@@ -603,7 +603,7 @@ static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
 
        update_inode(c, &root_inode);
 
-       darray_free(s.extents);
+       darray_exit(s.extents);
        genradix_free(&s.hardlinks);
 }
 
@@ -613,7 +613,7 @@ static void find_superblock_space(ranges extents,
 {
        struct range *i;
 
-       darray_foreach(i, extents) {
+       darray_for_each(extents, i) {
                u64 start = round_up(max(256ULL << 10, i->start),
                                     dev->bucket_size << 9);
                u64 end = round_down(i->end,
index 557c04113ae66fafdb11fca48bedf95c9f1b5530..17fe235eef1786c603cba131ebd9e83480db4b27 100644 (file)
@@ -7,10 +7,14 @@
 
 #include <linux/kernel.h>
 #include <linux/log2.h>
+#include <linux/overflow.h>
 #include <linux/page.h>
 #include <linux/shrinker.h>
 #include <linux/types.h>
 
+#include <stdlib.h>
+#include <sys/mman.h>
+
 #define ARCH_KMALLOC_MINALIGN          16
 #define KMALLOC_MAX_SIZE               SIZE_MAX
 
@@ -58,6 +62,16 @@ static inline void *krealloc(void *old, size_t size, gfp_t flags)
        return new;
 }
 
+static inline void *krealloc_array(void *p, size_t new_n, size_t new_size, gfp_t flags)
+{
+       size_t bytes;
+
+       if (unlikely(check_mul_overflow(new_n, new_size, &bytes)))
+               return NULL;
+
+       return krealloc(p, bytes, flags);
+}
+
 #define kzalloc(size, flags)           kmalloc(size, flags|__GFP_ZERO)
 #define kmalloc_array(n, size, flags)                                  \
        ((size) != 0 && (n) > SIZE_MAX / (size)                         \
@@ -174,4 +188,53 @@ static inline struct kmem_cache *kmem_cache_create(size_t obj_size)
 
 #define KMEM_CACHE(_struct, _flags)    kmem_cache_create(sizeof(struct _struct))
 
+#define PAGE_KERNEL            0
+#define PAGE_KERNEL_EXEC       1
+
+#define vfree(p)               free(p)
+
+static inline void *__vmalloc(unsigned long size, gfp_t gfp_mask)
+{
+       unsigned i = 0;
+       void *p;
+
+       size = round_up(size, PAGE_SIZE);
+
+       do {
+               run_shrinkers(gfp_mask, i != 0);
+
+               p = aligned_alloc(PAGE_SIZE, size);
+               if (p && gfp_mask & __GFP_ZERO)
+                       memset(p, 0, size);
+       } while (!p && i++ < 10);
+
+       return p;
+}
+
+static inline void *vmalloc_exec(unsigned long size, gfp_t gfp_mask)
+{
+       void *p;
+
+       p = __vmalloc(size, gfp_mask);
+       if (!p)
+               return NULL;
+
+       if (mprotect(p, size, PROT_READ|PROT_WRITE|PROT_EXEC)) {
+               vfree(p);
+               return NULL;
+       }
+
+       return p;
+}
+
+static inline void *vmalloc(unsigned long size)
+{
+       return __vmalloc(size, GFP_KERNEL);
+}
+
+static inline void *vzalloc(unsigned long size)
+{
+       return __vmalloc(size, GFP_KERNEL|__GFP_ZERO);
+}
+
 #endif /* __TOOLS_LINUX_SLAB_H */
index 77f967377757530f64238075483a4e6e6a3df365..7eb2222f8ce265f8cffc85072e80f20b25053606 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdint.h>
 
 #include <fcntl.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 
 #define __SANE_USERSPACE_TYPES__       /* For PPC64, to get LL64 types */
index 965e341d44d5406af20fe0cb8f796aaf6f453d46..55fffb5991e0e402a2665a6888018fb10f9bae0d 100644 (file)
@@ -1,59 +1,6 @@
 #ifndef __TOOLS_LINUX_VMALLOC_H
 #define __TOOLS_LINUX_VMALLOC_H
 
-#include <stdlib.h>
-#include <sys/mman.h>
-
 #include "linux/slab.h"
-#include "tools-util.h"
-
-#define PAGE_KERNEL            0
-#define PAGE_KERNEL_EXEC       1
-
-#define vfree(p)               free(p)
-
-static inline void *__vmalloc(unsigned long size, gfp_t gfp_mask)
-{
-       unsigned i = 0;
-       void *p;
-
-       size = round_up(size, PAGE_SIZE);
-
-       do {
-               run_shrinkers(gfp_mask, i != 0);
-
-               p = aligned_alloc(PAGE_SIZE, size);
-               if (p && gfp_mask & __GFP_ZERO)
-                       memset(p, 0, size);
-       } while (!p && i++ < 10);
-
-       return p;
-}
-
-static inline void *vmalloc_exec(unsigned long size, gfp_t gfp_mask)
-{
-       void *p;
-
-       p = __vmalloc(size, gfp_mask);
-       if (!p)
-               return NULL;
-
-       if (mprotect(p, size, PROT_READ|PROT_WRITE|PROT_EXEC)) {
-               vfree(p);
-               return NULL;
-       }
-
-       return p;
-}
-
-static inline void *vmalloc(unsigned long size)
-{
-       return __vmalloc(size, GFP_KERNEL);
-}
-
-static inline void *vzalloc(unsigned long size)
-{
-       return __vmalloc(size, GFP_KERNEL|__GFP_ZERO);
-}
 
 #endif /* __TOOLS_LINUX_VMALLOC_H */
index 08de7e617247fe6330db69f27278f84a4e462f31..ac2aecd47c5eb65858886c0aa5e68fe822e65743 100644 (file)
@@ -493,32 +493,49 @@ DEFINE_EVENT(bucket_alloc, bucket_alloc,
 
 TRACE_EVENT(bucket_alloc_fail,
        TP_PROTO(struct bch_dev *ca, const char *alloc_reserve,
-                u64 avail, u64 need_journal_commit,
-                bool nonblocking),
-       TP_ARGS(ca, alloc_reserve, avail, need_journal_commit, nonblocking),
+                u64 avail,
+                u64 seen,
+                u64 open,
+                u64 need_journal_commit,
+                u64 nouse,
+                bool nonblocking,
+                int ret),
+       TP_ARGS(ca, alloc_reserve, avail, seen, open, need_journal_commit, nouse, nonblocking, ret),
 
        TP_STRUCT__entry(
                __field(dev_t,                  dev                     )
                __array(char,   reserve,        16                      )
                __field(u64,                    avail                   )
+               __field(u64,                    seen                    )
+               __field(u64,                    open                    )
                __field(u64,                    need_journal_commit     )
+               __field(u64,                    nouse                   )
                __field(bool,                   nonblocking             )
+               __field(int,                    ret                     )
        ),
 
        TP_fast_assign(
                __entry->dev            = ca->dev;
                strlcpy(__entry->reserve, alloc_reserve, sizeof(__entry->reserve));
                __entry->avail          = avail;
+               __entry->seen           = seen;
+               __entry->open           = open;
                __entry->need_journal_commit = need_journal_commit;
+               __entry->nouse          = nouse;
                __entry->nonblocking    = nonblocking;
+               __entry->ret            = ret;
        ),
 
-       TP_printk("%d,%d reserve %s avail %llu need_journal_commit %llu nonblocking %u",
+       TP_printk("%d,%d reserve %s avail %llu seen %llu open %llu need_journal_commit %llu nouse %llu nonblocking %u ret %i",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
                  __entry->reserve,
                  __entry->avail,
+                 __entry->seen,
+                 __entry->open,
                  __entry->need_journal_commit,
-                 __entry->nonblocking)
+                 __entry->nouse,
+                 __entry->nonblocking,
+                 __entry->ret)
 );
 
 DEFINE_EVENT(bucket_alloc, open_bucket_alloc_fail,
index ceca4286dc69971b24cf24605b73a20a1c8d4922..8ba01947fa7e2842352dd6adab2afea8f35dec19 100644 (file)
@@ -713,7 +713,7 @@ dev_names bchu_fs_get_devices(struct bchfs_handle fs)
                n.label = read_file_str(fs.sysfs_fd, label_attr);
                free(label_attr);
 
-               darray_append(devs, n);
+               darray_push(devs, n);
        }
 
        closedir(dir);
index 3a83e16508330266ae78110b8c3341afaff07985..17e8eef3d9998d037c2787e2c431647e5e17e933 100644 (file)
@@ -237,7 +237,7 @@ struct dev_name {
        char            *label;
        uuid_le         uuid;
 };
-typedef darray(struct dev_name) dev_names;
+typedef DARRAY(struct dev_name) dev_names;
 
 dev_names bchu_fs_get_devices(struct bchfs_handle);
 
index 81cbfeb58cd1a9e40220a3e680e1ab229ec89bb4..07a76993318f4ae8c21f5f511948e4d7a5fdb3cd 100644 (file)
@@ -862,7 +862,9 @@ static void bch2_do_discards_work(struct work_struct *work)
                    bch2_bucket_is_open_safe(c, k.k->p.inode, k.k->p.offset))
                        continue;
 
-               ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+               ret = __bch2_trans_do(&trans, NULL, NULL,
+                                     BTREE_INSERT_USE_RESERVE|
+                                     BTREE_INSERT_NOFAIL,
                                bch2_clear_need_discard(&trans, k.k->p, ca, &discard_done));
                if (ret)
                        break;
@@ -954,6 +956,7 @@ static void bch2_do_invalidates_work(struct work_struct *work)
        for_each_member_device(ca, c, i)
                while (!ret && should_invalidate_buckets(ca))
                        ret = __bch2_trans_do(&trans, NULL, NULL,
+                                             BTREE_INSERT_USE_RESERVE|
                                              BTREE_INSERT_NOFAIL,
                                        invalidate_one_bucket(&trans, ca));
 
index 5b11493653896afad416af3d66c2c51ca9f4326a..538b597d845c845e5b5b1380183ec3f92af18aa6 100644 (file)
@@ -192,20 +192,26 @@ static inline unsigned open_buckets_reserved(enum alloc_reserve reserve)
 static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
                                              enum alloc_reserve reserve,
                                              struct bkey_alloc_unpacked a,
-                                             size_t *need_journal_commit,
+                                             u64 *skipped_open,
+                                             u64 *skipped_need_journal_commit,
+                                             u64 *skipped_nouse,
                                              struct closure *cl)
 {
        struct open_bucket *ob;
 
-       if (unlikely(ca->buckets_nouse && test_bit(a.bucket, ca->buckets_nouse)))
+       if (unlikely(ca->buckets_nouse && test_bit(a.bucket, ca->buckets_nouse))) {
+               (*skipped_nouse)++;
                return NULL;
+       }
 
-       if (bch2_bucket_is_open(c, ca->dev_idx, a.bucket))
+       if (bch2_bucket_is_open(c, ca->dev_idx, a.bucket)) {
+               (*skipped_open)++;
                return NULL;
+       }
 
        if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
                        c->journal.flushed_seq_ondisk, ca->dev_idx, a.bucket)) {
-               (*need_journal_commit)++;
+               (*skipped_need_journal_commit)++;
                return NULL;
        }
 
@@ -227,6 +233,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
        /* Recheck under lock: */
        if (bch2_bucket_is_open(c, ca->dev_idx, a.bucket)) {
                spin_unlock(&c->freelist_lock);
+               (*skipped_open)++;
                return NULL;
        }
 
@@ -267,7 +274,9 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
 
 static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bch_dev *ca,
                                            enum alloc_reserve reserve, u64 free_entry,
-                                           size_t *need_journal_commit,
+                                           u64 *skipped_open,
+                                           u64 *skipped_need_journal_commit,
+                                           u64 *skipped_nouse,
                                            struct closure *cl)
 {
        struct bch_fs *c = trans->c;
@@ -317,7 +326,11 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
                goto err;
        }
 
-       ob = __try_alloc_bucket(c, ca, reserve, a, need_journal_commit, cl);
+       ob = __try_alloc_bucket(c, ca, reserve, a,
+                               skipped_open,
+                               skipped_need_journal_commit,
+                               skipped_nouse,
+                               cl);
 err:
        bch2_trans_iter_exit(trans, &iter);
        printbuf_exit(&buf);
@@ -360,8 +373,11 @@ static noinline struct open_bucket *
 bch2_bucket_alloc_trans_early(struct btree_trans *trans,
                              struct bch_dev *ca,
                              enum alloc_reserve reserve,
-                             u64 *b,
-                             size_t *need_journal_commit,
+                             u64 *cur_bucket,
+                             u64 *buckets_seen,
+                             u64 *skipped_open,
+                             u64 *skipped_need_journal_commit,
+                             u64 *skipped_nouse,
                              struct closure *cl)
 {
        struct btree_iter iter;
@@ -369,10 +385,10 @@ bch2_bucket_alloc_trans_early(struct btree_trans *trans,
        struct open_bucket *ob = NULL;
        int ret;
 
-       *b = max_t(u64, *b, ca->mi.first_bucket);
-       *b = max_t(u64, *b, ca->new_fs_bucket_idx);
+       *cur_bucket = max_t(u64, *cur_bucket, ca->mi.first_bucket);
+       *cur_bucket = max_t(u64, *cur_bucket, ca->new_fs_bucket_idx);
 
-       for_each_btree_key(trans, iter, BTREE_ID_alloc, POS(ca->dev_idx, *b),
+       for_each_btree_key(trans, iter, BTREE_ID_alloc, POS(ca->dev_idx, *cur_bucket),
                           BTREE_ITER_SLOTS, k, ret) {
                struct bkey_alloc_unpacked a;
 
@@ -388,14 +404,19 @@ bch2_bucket_alloc_trans_early(struct btree_trans *trans,
                if (bucket_state(a) != BUCKET_free)
                        continue;
 
+               (*buckets_seen)++;
+
                ob = __try_alloc_bucket(trans->c, ca, reserve, a,
-                                       need_journal_commit, cl);
+                                       skipped_open,
+                                       skipped_need_journal_commit,
+                                       skipped_nouse,
+                                       cl);
                if (ob)
                        break;
        }
        bch2_trans_iter_exit(trans, &iter);
 
-       *b = iter.pos.offset;
+       *cur_bucket = iter.pos.offset;
 
        return ob ?: ERR_PTR(ret ?: -FREELIST_EMPTY);
 }
@@ -403,8 +424,11 @@ bch2_bucket_alloc_trans_early(struct btree_trans *trans,
 static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
                                                   struct bch_dev *ca,
                                                   enum alloc_reserve reserve,
-                                                  u64 *b,
-                                                  size_t *need_journal_commit,
+                                                  u64 *cur_bucket,
+                                                  u64 *buckets_seen,
+                                                  u64 *skipped_open,
+                                                  u64 *skipped_need_journal_commit,
+                                                  u64 *skipped_nouse,
                                                   struct closure *cl)
 {
        struct btree_iter iter;
@@ -413,26 +437,37 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
        int ret;
 
        if (unlikely(!ca->mi.freespace_initialized))
-               return bch2_bucket_alloc_trans_early(trans, ca, reserve, b,
-                                                    need_journal_commit, cl);
+               return bch2_bucket_alloc_trans_early(trans, ca, reserve,
+                                                    cur_bucket,
+                                                    buckets_seen,
+                                                    skipped_open,
+                                                    skipped_need_journal_commit,
+                                                    skipped_nouse,
+                                                    cl);
 
        BUG_ON(ca->new_fs_bucket_idx);
 
        for_each_btree_key(trans, iter, BTREE_ID_freespace,
-                          POS(ca->dev_idx, *b), 0, k, ret) {
+                          POS(ca->dev_idx, *cur_bucket), 0, k, ret) {
                if (k.k->p.inode != ca->dev_idx)
                        break;
 
-               for (*b = max(*b, bkey_start_offset(k.k));
-                    *b != k.k->p.offset && !ob;
-                    (*b)++) {
+               for (*cur_bucket = max(*cur_bucket, bkey_start_offset(k.k));
+                    *cur_bucket != k.k->p.offset && !ob;
+                    (*cur_bucket)++) {
                        if (btree_trans_too_many_iters(trans)) {
                                ob = ERR_PTR(-EINTR);
                                break;
                        }
 
-                       ob = try_alloc_bucket(trans, ca, reserve, *b,
-                                             need_journal_commit, cl);
+                       (*buckets_seen)++;
+
+                       ob = try_alloc_bucket(trans, ca, reserve,
+                                             *cur_bucket,
+                                             skipped_open,
+                                             skipped_need_journal_commit,
+                                             skipped_nouse,
+                                             cl);
                }
                if (ob)
                        break;
@@ -453,9 +488,12 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
                                      struct closure *cl)
 {
        struct open_bucket *ob = NULL;
-       size_t need_journal_commit = 0;
        u64 avail = dev_buckets_available(ca, reserve);
-       u64 b = 0;
+       u64 cur_bucket = 0;
+       u64 buckets_seen = 0;
+       u64 skipped_open = 0;
+       u64 skipped_need_journal_commit = 0;
+       u64 skipped_nouse = 0;
        int ret;
 
        if (may_alloc_partial) {
@@ -483,19 +521,27 @@ again:
        }
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-                       PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(&trans,
-                                                       ca, reserve, &b,
-                                                       &need_journal_commit, cl)));
-
-       if (need_journal_commit * 2 > avail)
+                       PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(&trans, ca, reserve,
+                                                       &cur_bucket,
+                                                       &buckets_seen,
+                                                       &skipped_open,
+                                                       &skipped_need_journal_commit,
+                                                       &skipped_nouse,
+                                                       cl)));
+
+       if (skipped_need_journal_commit * 2 > avail)
                bch2_journal_flush_async(&c->journal, NULL);
 err:
        if (!ob)
                ob = ERR_PTR(ret ?: -FREELIST_EMPTY);
 
-       if (ob == ERR_PTR(-FREELIST_EMPTY)) {
+       if (IS_ERR(ob)) {
                trace_bucket_alloc_fail(ca, bch2_alloc_reserves[reserve], avail,
-                                       need_journal_commit, cl == NULL);
+                                       buckets_seen,
+                                       skipped_open,
+                                       skipped_need_journal_commit,
+                                       skipped_nouse,
+                                       cl == NULL, PTR_ERR(ob));
                atomic_long_inc(&c->bucket_alloc_fail);
        }
 
index a4ef9aabf274a46016e0f43797a74639b4188602..9877037fc195d1a49fbe2a219cdc6d0345d503bd 100644 (file)
@@ -649,7 +649,7 @@ struct bch_fs {
        struct mutex            snapshot_table_lock;
        struct work_struct      snapshot_delete_work;
        struct work_struct      snapshot_wait_for_pagecache_and_delete_work;
-       struct snapshot_id_list snapshots_unlinked;
+       snapshot_id_list        snapshots_unlinked;
        struct mutex            snapshots_unlinked_lock;
 
        /* BTREE CACHE */
index 56c493c95d3a5158d79b445c47e0f8c8b0de017b..25d254ee9eaca15545a9456546d722e131ec68ea 100644 (file)
@@ -1686,6 +1686,7 @@ bch2_btree_path_make_mut(struct btree_trans *trans,
                btree_trans_verify_sorted(trans);
        }
 
+       path->should_be_locked = false;
        return path;
 }
 
@@ -1705,8 +1706,7 @@ bch2_btree_path_set_pos(struct btree_trans *trans,
 
        path = bch2_btree_path_make_mut(trans, path, intent, ip);
 
-       path->pos               = new_pos;
-       path->should_be_locked  = false;
+       path->pos = new_pos;
 
        bch2_btree_path_check_sort(trans, path, cmp);
 
@@ -1720,6 +1720,7 @@ bch2_btree_path_set_pos(struct btree_trans *trans,
        l = btree_path_up_until_good_node(trans, path, cmp);
 
        if (btree_path_node(path, l)) {
+               BUG_ON(!btree_node_locked(path, l));
                /*
                 * We might have to skip over many keys, or just a few: try
                 * advancing the node iterator, and if we have to skip over too
@@ -1923,6 +1924,7 @@ struct btree_path *bch2_path_get(struct btree_trans *trans,
 
        BUG_ON(trans->restarted);
        btree_trans_verify_sorted(trans);
+       bch2_trans_verify_locks(trans);
 
        trans_for_each_path_inorder(trans, path, i) {
                if (__btree_path_cmp(path,
@@ -2114,6 +2116,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
                btree_node_unlock(path, path->level);
                path->l[path->level].b = BTREE_ITER_NO_NODE_UP;
                path->level++;
+               btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
                return NULL;
        }
 
@@ -2121,6 +2124,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
                __bch2_btree_path_unlock(path);
                path->l[path->level].b = BTREE_ITER_NO_NODE_GET_LOCKS;
                path->l[path->level + 1].b = BTREE_ITER_NO_NODE_GET_LOCKS;
+               btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
                trace_trans_restart_relock_next_node(trans->fn, _THIS_IP_,
                                           path->btree_id, &path->pos);
                btree_trans_restart(trans);
@@ -3055,8 +3059,7 @@ void bch2_trans_begin(struct btree_trans *trans)
        trans->mem_top                  = 0;
 
        trans->hooks                    = NULL;
-       trans->extra_journal_entries    = NULL;
-       trans->extra_journal_entry_u64s = 0;
+       trans->extra_journal_entries.nr = 0;
 
        if (trans->fs_usage_deltas) {
                trans->fs_usage_deltas->used = 0;
@@ -3189,6 +3192,8 @@ void bch2_trans_exit(struct btree_trans *trans)
 
        bch2_journal_preres_put(&c->journal, &trans->journal_preres);
 
+       kfree(trans->extra_journal_entries.data);
+
        if (trans->fs_usage_deltas) {
                if (trans->fs_usage_deltas->size + sizeof(trans->fs_usage_deltas) ==
                    REPLICAS_DELTA_LIST_MAX)
index 993f04f52149481a4509b1d6743b725b4dae6fc4..b86a721f90acee8c6a1dc7043ec5e80788e34767 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "bkey_methods.h"
 #include "buckets_types.h"
+#include "darray.h"
 #include "journal_types.h"
 
 struct open_bucket;
@@ -417,8 +418,7 @@ struct btree_trans {
 
        /* update path: */
        struct btree_trans_commit_hook *hooks;
-       struct jset_entry       *extra_journal_entries;
-       unsigned                extra_journal_entry_u64s;
+       DARRAY(u64)             extra_journal_entries;
        struct journal_entry_pin *journal_pin;
 
        struct journal_res      journal_res;
index ca142f9551937388c8bed500a1975fd030b41f2c..ad13b0739a688d4678844e6e276e02098764f173 100644 (file)
@@ -80,6 +80,8 @@ void bch2_trans_commit_hook(struct btree_trans *,
                            struct btree_trans_commit_hook *);
 int __bch2_trans_commit(struct btree_trans *);
 
+int bch2_trans_log_msg(struct btree_trans *, const char *);
+
 /**
  * bch2_trans_commit - insert keys at given iterator positions
  *
index c2232f8185c52f4e8dcb852452ed4728859740df..42ae3b0c5839448c0a19c92b497b3c978f5b19be 100644 (file)
@@ -532,8 +532,15 @@ static int btree_update_nodes_written_trans(struct btree_trans *trans,
        struct bkey_i *k;
        int ret;
 
-       trans->extra_journal_entries = (void *) &as->journal_entries[0];
-       trans->extra_journal_entry_u64s = as->journal_u64s;
+       ret = darray_make_room(trans->extra_journal_entries, as->journal_u64s);
+       if (ret)
+               return ret;
+
+       memcpy(&darray_top(trans->extra_journal_entries),
+              as->journal_entries,
+              as->journal_u64s * sizeof(u64));
+       trans->extra_journal_entries.nr += as->journal_u64s;
+
        trans->journal_pin = &as->journal;
 
        for_each_keylist_key(&as->new_keys, k) {
@@ -1899,7 +1906,6 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct btree_iter iter2 = { NULL };
        struct btree *parent;
-       u64 journal_entries[BKEY_BTREE_PTR_U64s_MAX];
        int ret;
 
        if (!skip_triggers) {
@@ -1933,6 +1939,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
                btree_node_unlock(iter2.path, iter2.path->level);
                path_l(iter2.path)->b = BTREE_ITER_NO_NODE_UP;
                iter2.path->level++;
+               btree_path_set_dirty(iter2.path, BTREE_ITER_NEED_TRAVERSE);
 
                bch2_btree_path_check_sort(trans, iter2.path, 0);
 
@@ -1943,12 +1950,16 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
        } else {
                BUG_ON(btree_node_root(c, b) != b);
 
-               trans->extra_journal_entries = (void *) &journal_entries[0];
-               trans->extra_journal_entry_u64s =
-                       journal_entry_set((void *) &journal_entries[0],
-                                         BCH_JSET_ENTRY_btree_root,
-                                         b->c.btree_id, b->c.level,
-                                         new_key, new_key->k.u64s);
+               ret = darray_make_room(trans->extra_journal_entries,
+                                      jset_u64s(new_key->k.u64s));
+               if (ret)
+                       return ret;
+
+               journal_entry_set((void *) &darray_top(trans->extra_journal_entries),
+                                 BCH_JSET_ENTRY_btree_root,
+                                 b->c.btree_id, b->c.level,
+                                 new_key, new_key->k.u64s);
+               trans->extra_journal_entries.nr += jset_u64s(new_key->k.u64s);
        }
 
        ret = bch2_trans_commit(trans, NULL, NULL,
index 8d185c7c10efe10f800b64f14f9e21507f612e5e..6f4ee55ebffe0f5214a19a68d5b74de0e638052b 100644 (file)
@@ -700,13 +700,13 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
                trans->journal_res.seq = c->journal.replay_journal_seq;
        }
 
-       if (unlikely(trans->extra_journal_entry_u64s)) {
+       if (unlikely(trans->extra_journal_entries.nr)) {
                memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
-                                 trans->extra_journal_entries,
-                                 trans->extra_journal_entry_u64s);
+                                 trans->extra_journal_entries.data,
+                                 trans->extra_journal_entries.nr);
 
-               trans->journal_res.offset       += trans->extra_journal_entry_u64s;
-               trans->journal_res.u64s         -= trans->extra_journal_entry_u64s;
+               trans->journal_res.offset       += trans->extra_journal_entries.nr;
+               trans->journal_res.u64s         -= trans->extra_journal_entries.nr;
        }
 
        /*
@@ -1088,7 +1088,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
        int ret = 0;
 
        if (!trans->nr_updates &&
-           !trans->extra_journal_entry_u64s)
+           !trans->extra_journal_entries.nr)
                goto out_reset;
 
        if (trans->flags & BTREE_INSERT_GC_LOCK_HELD)
@@ -1112,7 +1112,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
 
        memset(&trans->journal_preres, 0, sizeof(trans->journal_preres));
 
-       trans->journal_u64s             = trans->extra_journal_entry_u64s;
+       trans->journal_u64s             = trans->extra_journal_entries.nr;
        trans->journal_preres_u64s      = 0;
 
        trans->journal_transaction_names = READ_ONCE(c->opts.journal_transaction_names);
@@ -1170,8 +1170,7 @@ out_reset:
        trans->extra_journal_res        = 0;
        trans->nr_updates               = 0;
        trans->hooks                    = NULL;
-       trans->extra_journal_entries    = NULL;
-       trans->extra_journal_entry_u64s = 0;
+       trans->extra_journal_entries.nr = 0;
 
        if (trans->fs_usage_deltas) {
                trans->fs_usage_deltas->used = 0;
@@ -1739,3 +1738,30 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
                             bch2_btree_delete_range_trans(&trans, id, start, end,
                                                           update_flags, journal_seq));
 }
+
+int bch2_trans_log_msg(struct btree_trans *trans, const char *msg)
+{
+       unsigned len = strlen(msg);
+       unsigned u64s = DIV_ROUND_UP(len, sizeof(u64));
+       struct jset_entry_log *l;
+       int ret;
+
+       ret = darray_make_room(trans->extra_journal_entries, jset_u64s(u64s));
+       if (ret)
+               return ret;
+
+       l = (void *) &darray_top(trans->extra_journal_entries);
+       l->entry.u64s           = cpu_to_le16(u64s);
+       l->entry.btree_id       = 0;
+       l->entry.level          = 1;
+       l->entry.type           = BCH_JSET_ENTRY_log;
+       l->entry.pad[0]         = 0;
+       l->entry.pad[1]         = 0;
+       l->entry.pad[2]         = 0;
+       memcpy(l->d, msg, len);
+       while (len & 7)
+               l->d[len++] = '\0';
+
+       trans->extra_journal_entries.nr += jset_u64s(u64s);
+       return 0;
+}
diff --git a/libbcachefs/darray.h b/libbcachefs/darray.h
new file mode 100644 (file)
index 0000000..745b1cd
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _BCACHEFS_DARRAY_H
+#define _BCACHEFS_DARRAY_H
+
+/*
+ * Dynamic arrays:
+ *
+ * Inspired by CCAN's darray
+ */
+
+#include "util.h"
+#include <linux/slab.h>
+
+#define DARRAY(type)                                                   \
+struct {                                                               \
+       size_t nr, size;                                                \
+       type *data;                                                     \
+}
+
+typedef DARRAY(void) darray_void;
+
+static inline int __darray_make_room(darray_void *d, size_t t_size, size_t more)
+{
+       if (d->nr + more > d->size) {
+               size_t new_size = roundup_pow_of_two(d->nr + more);
+               void *data = krealloc_array(d->data, new_size, t_size, GFP_KERNEL);
+
+               if (!data)
+                       return -ENOMEM;
+
+               d->data = data;
+               d->size = new_size;
+       }
+
+       return 0;
+}
+
+#define darray_make_room(_d, _more)                                    \
+       __darray_make_room((darray_void *) &(_d), sizeof((_d).data[0]), (_more))
+
+#define darray_top(_d)         ((_d).data[(_d).nr])
+
+#define darray_push(_d, _item)                                         \
+({                                                                     \
+       int _ret = darray_make_room((_d), 1);                           \
+                                                                       \
+       if (!_ret)                                                      \
+               (_d).data[(_d).nr++] = (_item);                         \
+       _ret;                                                           \
+})
+
+#define darray_insert_item(_d, _pos, _item)                            \
+({                                                                     \
+       int _ret = darray_make_room((_d), 1);                           \
+                                                                       \
+       if (!_ret)                                                      \
+               array_insert_item((_d).data, (_d).nr, (_pos), (_item)); \
+       _ret;                                                           \
+})
+
+#define darray_for_each(_d, _i)                                                \
+       for (_i = (_d).data; _i < (_d).data + (_d).nr; _i++)
+
+#define darray_init(_d)                                                        \
+do {                                                                   \
+       (_d).data = NULL;                                               \
+       (_d).nr = (_d).size = 0;                                        \
+} while (0)
+
+#define darray_exit(_d)                                                        \
+do {                                                                   \
+       kfree((_d).data);                                               \
+       darray_init(_d);                                                \
+} while (0)
+
+#endif /* _BCACHEFS_DARRAY_H */
index 9fc6c39eacdb6fb244efba8317dd2ceaec61abae..d462c06899d677e3c7a67ea73b865b2292f94cda 100644 (file)
@@ -1477,7 +1477,7 @@ static void bch2_evict_inode(struct inode *vinode)
 }
 
 void bch2_evict_subvolume_inodes(struct bch_fs *c,
-                                struct snapshot_id_list *s)
+                                snapshot_id_list *s)
 {
        struct super_block *sb = c->vfs_sb;
        struct inode *inode;
index b2211ec7f3028600a941014057440dc3dc056c7a..9f4b57e30e2a7d14e8c66598c2203cbf970d319e 100644 (file)
@@ -191,7 +191,7 @@ int bch2_setattr_nonsize(struct user_namespace *,
                         struct iattr *);
 int __bch2_unlink(struct inode *, struct dentry *, bool);
 
-void bch2_evict_subvolume_inodes(struct bch_fs *, struct snapshot_id_list *);
+void bch2_evict_subvolume_inodes(struct bch_fs *, snapshot_id_list *);
 
 void bch2_vfs_exit(void);
 int bch2_vfs_init(void);
@@ -199,7 +199,7 @@ int bch2_vfs_init(void);
 #else
 
 static inline void bch2_evict_subvolume_inodes(struct bch_fs *c,
-                                              struct snapshot_id_list *s) {}
+                                              snapshot_id_list *s) {}
 static inline void bch2_vfs_exit(void) {}
 static inline int bch2_vfs_init(void) { return 0; }
 
index 8783b950055e5c9adfc30ba8fe7229cb3ebb188a..2582ddf14803f7ba504e088dedc9180b4300bf9b 100644 (file)
@@ -3,6 +3,7 @@
 #include "bcachefs.h"
 #include "bkey_buf.h"
 #include "btree_update.h"
+#include "darray.h"
 #include "dirent.h"
 #include "error.h"
 #include "fs-common.h"
@@ -471,11 +472,11 @@ static int snapshots_seen_update(struct bch_fs *c, struct snapshots_seen *s, str
        pos.snapshot = snapshot_t(c, pos.snapshot)->equiv;
 
        if (bkey_cmp(s->pos, pos))
-               s->nr = 0;
+               s->ids.nr = 0;
        s->pos = pos;
 
        /* Might get called multiple times due to lock restarts */
-       if (s->nr && s->d[s->nr - 1] == pos.snapshot)
+       if (s->ids.nr && s->ids.data[s->ids.nr - 1] == pos.snapshot)
                return 0;
 
        return snapshots_seen_add(c, s, pos.snapshot);
@@ -498,7 +499,7 @@ static bool key_visible_in_snapshot(struct bch_fs *c, struct snapshots_seen *see
        ancestor        = snapshot_t(c, ancestor)->equiv;
 
        /* @ancestor should be the snapshot most recently added to @seen */
-       BUG_ON(!seen->nr || seen->d[seen->nr - 1] != ancestor);
+       BUG_ON(!seen->ids.nr || seen->ids.data[seen->ids.nr - 1] != ancestor);
        BUG_ON(seen->pos.snapshot != ancestor);
 
        if (id == ancestor)
@@ -507,11 +508,11 @@ static bool key_visible_in_snapshot(struct bch_fs *c, struct snapshots_seen *see
        if (!bch2_snapshot_is_ancestor(c, id, ancestor))
                return false;
 
-       for (i = seen->nr - 2;
-            i >= 0 && seen->d[i] >= id;
+       for (i = seen->ids.nr - 2;
+            i >= 0 && seen->ids.data[i] >= id;
             --i)
-               if (bch2_snapshot_is_ancestor(c, id, seen->d[i]) &&
-                   bch2_snapshot_is_ancestor(c, seen->d[i], ancestor))
+               if (bch2_snapshot_is_ancestor(c, id, seen->ids.data[i]) &&
+                   bch2_snapshot_is_ancestor(c, seen->ids.data[i], ancestor))
                        return false;
 
        return true;
@@ -537,26 +538,25 @@ static int ref_visible(struct bch_fs *c, struct snapshots_seen *s,
 }
 
 #define for_each_visible_inode(_c, _s, _w, _snapshot, _i)      \
-       for (_i = (_w)->d; _i < (_w)->d + (_w)->nr && (_i)->snapshot <= (_snapshot); _i++)\
+       for (_i = (_w)->inodes.data; _i < (_w)->inodes.data + (_w)->inodes.nr && (_i)->snapshot <= (_snapshot); _i++)\
                if (key_visible_in_snapshot(_c, _s, _i->snapshot, _snapshot))
 
+struct inode_walker_entry {
+       struct bch_inode_unpacked inode;
+       u32                     snapshot;
+       u64                     count;
+};
+
 struct inode_walker {
        bool                            first_this_inode;
        u64                             cur_inum;
 
-       size_t                          nr;
-       size_t                          size;
-       struct inode_walker_entry {
-               struct bch_inode_unpacked inode;
-               u32                     snapshot;
-               u64                     count;
-       } *d;
+       DARRAY(struct inode_walker_entry) inodes;
 };
 
 static void inode_walker_exit(struct inode_walker *w)
 {
-       kfree(w->d);
-       w->d = NULL;
+       darray_exit(w->inodes);
 }
 
 static struct inode_walker inode_walker_init(void)
@@ -564,43 +564,17 @@ static struct inode_walker inode_walker_init(void)
        return (struct inode_walker) { 0, };
 }
 
-static int inode_walker_realloc(struct bch_fs *c, struct inode_walker *w)
-{
-       if (w->nr == w->size) {
-               size_t new_size = max_t(size_t, 8UL, w->size * 2);
-               void *d = krealloc(w->d, new_size * sizeof(w->d[0]),
-                                  GFP_KERNEL);
-               if (!d) {
-                       bch_err(c, "fsck: error allocating memory for inode_walker, size %zu",
-                               new_size);
-                       return -ENOMEM;
-               }
-
-               w->d = d;
-               w->size = new_size;
-       }
-
-       return 0;
-}
-
 static int add_inode(struct bch_fs *c, struct inode_walker *w,
                     struct bkey_s_c inode)
 {
        struct bch_inode_unpacked u;
-       int ret;
-
-       ret = inode_walker_realloc(c, w);
-       if (ret)
-               return ret;
 
        BUG_ON(bch2_inode_unpack(inode, &u));
 
-       w->d[w->nr++] = (struct inode_walker_entry) {
+       return darray_push(w->inodes, ((struct inode_walker_entry) {
                .inode          = u,
                .snapshot       = snapshot_t(c, inode.k->p.snapshot)->equiv,
-       };
-
-       return 0;
+       }));
 }
 
 static int __walk_inode(struct btree_trans *trans,
@@ -619,7 +593,7 @@ static int __walk_inode(struct btree_trans *trans,
                goto lookup_snapshot;
        }
 
-       w->nr = 0;
+       w->inodes.nr = 0;
 
        for_each_btree_key(trans, iter, BTREE_ID_inodes, POS(0, pos.inode),
                           BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
@@ -637,26 +611,25 @@ static int __walk_inode(struct btree_trans *trans,
        w->cur_inum             = pos.inode;
        w->first_this_inode     = true;
 lookup_snapshot:
-       for (i = 0; i < w->nr; i++)
-               if (bch2_snapshot_is_ancestor(c, pos.snapshot, w->d[i].snapshot))
+       for (i = 0; i < w->inodes.nr; i++)
+               if (bch2_snapshot_is_ancestor(c, pos.snapshot, w->inodes.data[i].snapshot))
                        goto found;
        return INT_MAX;
 found:
-       BUG_ON(pos.snapshot > w->d[i].snapshot);
+       BUG_ON(pos.snapshot > w->inodes.data[i].snapshot);
 
-       if (pos.snapshot != w->d[i].snapshot) {
+       if (pos.snapshot != w->inodes.data[i].snapshot) {
                ancestor_pos = i;
 
-               while (i && w->d[i - 1].snapshot > pos.snapshot)
+               while (i && w->inodes.data[i - 1].snapshot > pos.snapshot)
                        --i;
 
-               ret = inode_walker_realloc(c, w);
+               ret = darray_insert_item(w->inodes, i, w->inodes.data[ancestor_pos]);
                if (ret)
                        return ret;
 
-               array_insert_item(w->d, w->nr, i, w->d[ancestor_pos]);
-               w->d[i].snapshot = pos.snapshot;
-               w->d[i].count   = 0;
+               w->inodes.data[i].snapshot = pos.snapshot;
+               w->inodes.data[i].count = 0;
        }
 
        return i;
@@ -672,7 +645,7 @@ static int __get_visible_inodes(struct btree_trans *trans,
        struct bkey_s_c k;
        int ret;
 
-       w->nr = 0;
+       w->inodes.nr = 0;
 
        for_each_btree_key(trans, iter, BTREE_ID_inodes, POS(0, inum),
                           BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
@@ -1133,7 +1106,7 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w)
        int ret = 0, ret2 = 0;
        s64 count2;
 
-       for (i = w->d; i < w->d + w->nr; i++) {
+       darray_for_each(w->inodes, i) {
                if (i->inode.bi_sectors == i->count)
                        continue;
 
@@ -1232,7 +1205,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
                goto out;
        }
 
-       i = inode->d + ret;
+       i = inode->inodes.data + ret;
        ret = 0;
 
        if (fsck_err_on(!S_ISREG(i->inode.bi_mode) &&
@@ -1333,7 +1306,7 @@ static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w)
        int ret = 0, ret2 = 0;
        s64 count2;
 
-       for (i = w->d; i < w->d + w->nr; i++) {
+       darray_for_each(w->inodes, i) {
                if (i->inode.bi_nlink == i->count)
                        continue;
 
@@ -1537,7 +1510,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                goto out;
        }
 
-       i = dir->d + ret;
+       i = dir->inodes.data + ret;
        ret = 0;
 
        if (fsck_err_on(!S_ISDIR(i->inode.bi_mode), c,
@@ -1550,7 +1523,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
        }
 
        if (dir->first_this_inode)
-               *hash_info = bch2_hash_info_init(c, &dir->d[0].inode);
+               *hash_info = bch2_hash_info_init(c, &dir->inodes.data[0].inode);
 
        ret = hash_check_key(trans, bch2_dirent_hash_desc,
                             hash_info, iter, k);
@@ -1618,7 +1591,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                if (ret)
                        goto err;
 
-               if (fsck_err_on(!target->nr, c,
+               if (fsck_err_on(!target->inodes.nr, c,
                                "dirent points to missing inode:\n%s",
                                (printbuf_reset(&buf),
                                 bch2_bkey_val_to_text(&buf, c, k),
@@ -1628,7 +1601,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                                goto err;
                }
 
-               for (i = target->d; i < target->d + target->nr; i++) {
+               darray_for_each(target->inodes, i) {
                        ret = check_dirent_target(trans, iter, d,
                                                  &i->inode, i->snapshot);
                        if (ret)
@@ -1726,7 +1699,7 @@ static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
        ret = 0;
 
        if (inode->first_this_inode)
-               *hash_info = bch2_hash_info_init(c, &inode->d[0].inode);
+               *hash_info = bch2_hash_info_init(c, &inode->inodes.data[0].inode);
 
        ret = hash_check_key(trans, bch2_xattr_hash_desc, hash_info, iter, k);
 fsck_err:
@@ -1836,21 +1809,18 @@ static int check_root(struct bch_fs *c)
                check_root_trans(&trans));
 }
 
-struct pathbuf {
-       size_t          nr;
-       size_t          size;
-
-       struct pathbuf_entry {
-               u64     inum;
-               u32     snapshot;
-       }               *entries;
+struct pathbuf_entry {
+       u64     inum;
+       u32     snapshot;
 };
 
-static bool path_is_dup(struct pathbuf *p, u64 inum, u32 snapshot)
+typedef DARRAY(struct pathbuf_entry) pathbuf;
+
+static bool path_is_dup(pathbuf *p, u64 inum, u32 snapshot)
 {
        struct pathbuf_entry *i;
 
-       for (i = p->entries; i < p->entries + p->nr; i++)
+       darray_for_each(*p, i)
                if (i->inum     == inum &&
                    i->snapshot == snapshot)
                        return true;
@@ -1858,29 +1828,18 @@ static bool path_is_dup(struct pathbuf *p, u64 inum, u32 snapshot)
        return false;
 }
 
-static int path_down(struct bch_fs *c, struct pathbuf *p,
+static int path_down(struct bch_fs *c, pathbuf *p,
                     u64 inum, u32 snapshot)
 {
-       if (p->nr == p->size) {
-               size_t new_size = max_t(size_t, 256UL, p->size * 2);
-               void *n = krealloc(p->entries,
-                                  new_size * sizeof(p->entries[0]),
-                                  GFP_KERNEL);
-               if (!n) {
-                       bch_err(c, "fsck: error allocating memory for pathbuf, size %zu",
-                               new_size);
-                       return -ENOMEM;
-               }
-
-               p->entries = n;
-               p->size = new_size;
-       };
-
-       p->entries[p->nr++] = (struct pathbuf_entry) {
+       int ret = darray_push(*p, ((struct pathbuf_entry) {
                .inum           = inum,
                .snapshot       = snapshot,
-       };
-       return 0;
+       }));
+
+       if (ret)
+               bch_err(c, "fsck: error allocating memory for pathbuf, size %zu",
+                       p->size);
+       return ret;
 }
 
 /*
@@ -1889,7 +1848,7 @@ static int path_down(struct bch_fs *c, struct pathbuf *p,
  * XXX: we should also be verifying that inodes are in the right subvolumes
  */
 static int check_path(struct btree_trans *trans,
-                     struct pathbuf *p,
+                     pathbuf *p,
                      struct bch_inode_unpacked *inode,
                      u32 snapshot)
 {
@@ -1963,7 +1922,7 @@ static int check_path(struct btree_trans *trans,
                        /* XXX print path */
                        bch_err(c, "directory structure loop");
 
-                       for (i = p->entries; i < p->entries + p->nr; i++)
+                       darray_for_each(*p, i)
                                pr_err("%llu:%u", i->inum, i->snapshot);
                        pr_err("%llu:%u", inode->bi_inum, snapshot);
 
@@ -2000,7 +1959,7 @@ static int check_directory_structure(struct bch_fs *c)
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_inode_unpacked u;
-       struct pathbuf path = { 0, 0, NULL };
+       pathbuf path = { 0, };
        int ret;
 
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
@@ -2030,7 +1989,7 @@ static int check_directory_structure(struct bch_fs *c)
 
        BUG_ON(ret == -EINTR);
 
-       kfree(path.entries);
+       darray_exit(path);
 
        bch2_trans_exit(&trans);
        return ret;
index 8eb49381b030942e3b9631f922b204faeb2b0599..1de213506adf738069a99b64b421fbc85b5b13b3 100644 (file)
@@ -92,10 +92,10 @@ next:
 
                if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, old_pos.snapshot)) {
                        struct bkey_i *update;
-                       size_t i;
+                       u32 *i;
 
-                       for (i = 0; i < s.nr; i++)
-                               if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, s.d[i]))
+                       darray_for_each(s.ids, i)
+                               if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, *i))
                                        goto next;
 
                        update = bch2_trans_kmalloc(trans, sizeof(struct bkey_i));
@@ -125,7 +125,7 @@ next:
                }
        }
        bch2_trans_iter_exit(trans, &iter);
-       kfree(s.d);
+       darray_exit(s.ids);
 
        return ret;
 }
index 666f1c88a3b618a1fa810f34c13f0dfa2356ed05..cdb89ba216cca3a5f109a97cb6eedfa2c8f4c2fd 100644 (file)
@@ -545,36 +545,21 @@ err:
        return ret;
 }
 
-static int snapshot_id_add(struct snapshot_id_list *s, u32 id)
+static int snapshot_id_add(snapshot_id_list *s, u32 id)
 {
        BUG_ON(snapshot_list_has_id(s, id));
 
-       if (s->nr == s->size) {
-               size_t new_size = max(8U, s->size * 2);
-               void *n = krealloc(s->d,
-                                  new_size * sizeof(s->d[0]),
-                                  GFP_KERNEL);
-               if (!n) {
-                       pr_err("error allocating snapshot ID list");
-                       return -ENOMEM;
-               }
-
-               s->d    = n;
-               s->size = new_size;
-       };
-
-       s->d[s->nr++] = id;
-       return 0;
+       return darray_push(*s, id);
 }
 
 static int bch2_snapshot_delete_keys_btree(struct btree_trans *trans,
-                                          struct snapshot_id_list *deleted,
+                                          snapshot_id_list *deleted,
                                           enum btree_id btree_id)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_s_c k;
-       struct snapshot_id_list equiv_seen = { 0 };
+       snapshot_id_list equiv_seen = { 0 };
        struct bpos last_pos = POS_MIN;
        int ret = 0;
 
@@ -621,7 +606,7 @@ static int bch2_snapshot_delete_keys_btree(struct btree_trans *trans,
        }
        bch2_trans_iter_exit(trans, &iter);
 
-       kfree(equiv_seen.d);
+       darray_exit(equiv_seen);
 
        return ret;
 }
@@ -633,7 +618,7 @@ static void bch2_delete_dead_snapshots_work(struct work_struct *work)
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_s_c_snapshot snap;
-       struct snapshot_id_list deleted = { 0 };
+       snapshot_id_list deleted = { 0 };
        u32 i, id, children[2];
        int ret = 0;
 
@@ -713,15 +698,15 @@ static void bch2_delete_dead_snapshots_work(struct work_struct *work)
 
        for (i = 0; i < deleted.nr; i++) {
                ret = __bch2_trans_do(&trans, NULL, NULL, 0,
-                       bch2_snapshot_node_delete(&trans, deleted.d[i]));
+                       bch2_snapshot_node_delete(&trans, deleted.data[i]));
                if (ret) {
                        bch_err(c, "error deleting snapshot %u: %i",
-                               deleted.d[i], ret);
+                               deleted.data[i], ret);
                        goto err;
                }
        }
 err:
-       kfree(deleted.d);
+       darray_exit(deleted);
        bch2_trans_exit(&trans);
        percpu_ref_put(&c->writes);
 }
@@ -876,14 +861,14 @@ void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *work)
 {
        struct bch_fs *c = container_of(work, struct bch_fs,
                                snapshot_wait_for_pagecache_and_delete_work);
-       struct snapshot_id_list s;
+       snapshot_id_list s;
        u32 *id;
        int ret = 0;
 
        while (!ret) {
                mutex_lock(&c->snapshots_unlinked_lock);
                s = c->snapshots_unlinked;
-               memset(&c->snapshots_unlinked, 0, sizeof(c->snapshots_unlinked));
+               darray_init(c->snapshots_unlinked);
                mutex_unlock(&c->snapshots_unlinked_lock);
 
                if (!s.nr)
@@ -891,7 +876,7 @@ void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *work)
 
                bch2_evict_subvolume_inodes(c, &s);
 
-               for (id = s.d; id < s.d + s.nr; id++) {
+               for (id = s.data; id < s.data + s.nr; id++) {
                        ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
                                      bch2_subvolume_delete(&trans, *id));
                        if (ret) {
@@ -900,7 +885,7 @@ void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *work)
                        }
                }
 
-               kfree(s.d);
+               darray_exit(s);
        }
 
        percpu_ref_put(&c->writes);
index 4abe53df2788466f58fe347f4611a2370fcf1f60..f609291acafa5a1dff95a526325a5c6091166813 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef _BCACHEFS_SUBVOLUME_H
 #define _BCACHEFS_SUBVOLUME_H
 
+#include "darray.h"
 #include "subvolume_types.h"
 
 void bch2_snapshot_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
@@ -58,15 +59,13 @@ static inline bool bch2_snapshot_is_ancestor(struct bch_fs *c, u32 id, u32 ances
 
 struct snapshots_seen {
        struct bpos                     pos;
-       size_t                          nr;
-       size_t                          size;
-       u32                             *d;
+       DARRAY(u32)                     ids;
 };
 
 static inline void snapshots_seen_exit(struct snapshots_seen *s)
 {
-       kfree(s->d);
-       s->d = NULL;
+       kfree(s->ids.data);
+       s->ids.data = NULL;
 }
 
 static inline void snapshots_seen_init(struct snapshots_seen *s)
@@ -76,30 +75,19 @@ static inline void snapshots_seen_init(struct snapshots_seen *s)
 
 static inline int snapshots_seen_add(struct bch_fs *c, struct snapshots_seen *s, u32 id)
 {
-       if (s->nr == s->size) {
-               size_t new_size = max(s->size, (size_t) 128) * 2;
-               u32 *d = krealloc(s->d, new_size * sizeof(s->d[0]), GFP_KERNEL);
-
-               if (!d) {
-                       bch_err(c, "error reallocating snapshots_seen table (new size %zu)",
-                               new_size);
-                       return -ENOMEM;
-               }
-
-               s->size = new_size;
-               s->d    = d;
-       }
-
-       s->d[s->nr++] = id;
-       return 0;
+       int ret = darray_push(s->ids, id);
+       if (ret)
+               bch_err(c, "error reallocating snapshots_seen table (size %zu)",
+                       s->ids.size);
+       return ret;
 }
 
-static inline bool snapshot_list_has_id(struct snapshot_id_list *s, u32 id)
+static inline bool snapshot_list_has_id(snapshot_id_list *s, u32 id)
 {
-       unsigned i;
+       u32 *i;
 
-       for (i = 0; i < s->nr; i++)
-               if (id == s->d[i])
+       darray_for_each(*s, i)
+               if (*i == id)
                        return true;
        return false;
 }
index 9410b9587591e8c479765c911b3a586e5a6d0bef..f7562b5d51dff4ba1c07e52857fe793bcc75a794 100644 (file)
@@ -2,10 +2,8 @@
 #ifndef _BCACHEFS_SUBVOLUME_TYPES_H
 #define _BCACHEFS_SUBVOLUME_TYPES_H
 
-struct snapshot_id_list {
-       u32             nr;
-       u32             size;
-       u32             *d;
-};
+#include "darray.h"
+
+typedef DARRAY(u32) snapshot_id_list;
 
 #endif /* _BCACHEFS_SUBVOLUME_TYPES_H */
diff --git a/qcow2.c b/qcow2.c
index 7cf4992fbd9ffd43bd1d7478bf85d1e41dbfe5ee..d01fa9417088198fee5310a705abd0e42ac3b131 100644 (file)
--- a/qcow2.c
+++ b/qcow2.c
@@ -94,7 +94,7 @@ void qcow2_write_image(int infd, int outfd, ranges *data,
        ranges_sort_merge(data);
 
        /* Write data: */
-       darray_foreach(r, *data)
+       darray_for_each(*data, r)
                for (src_offset = r->start;
                     src_offset < r->end;
                     src_offset += block_size) {
index 621ab42548e7ab573da7f3adcf98ba592c9b8cfe..e338152185b88a8d8702af5d2fa81c111441b968 100644 (file)
@@ -295,22 +295,21 @@ static int range_cmp(const void *_l, const void *_r)
 void ranges_sort_merge(ranges *r)
 {
        struct range *t, *i;
-       ranges tmp = { NULL };
+       ranges tmp = { 0 };
 
-       sort(&darray_item(*r, 0), darray_size(*r),
-            sizeof(darray_item(*r, 0)), range_cmp, NULL);
+       sort(r->data, r->nr, sizeof(r->data[0]), range_cmp, NULL);
 
        /* Merge contiguous ranges: */
-       darray_foreach(i, *r) {
-               t = tmp.size ?  &tmp.item[tmp.size - 1] : NULL;
+       darray_for_each(*r, i) {
+               t = tmp.nr ?  &tmp.data[tmp.nr - 1] : NULL;
 
                if (t && t->end >= i->start)
                        t->end = max(t->end, i->end);
                else
-                       darray_append(tmp, *i);
+                       darray_push(tmp, *i);
        }
 
-       darray_free(*r);
+       darray_exit(*r);
        *r = tmp;
 }
 
@@ -318,7 +317,7 @@ void ranges_roundup(ranges *r, unsigned block_size)
 {
        struct range *i;
 
-       darray_foreach(i, *r) {
+       darray_for_each(*r, i) {
                i->start = round_down(i->start, block_size);
                i->end  = round_up(i->end, block_size);
        }
@@ -328,7 +327,7 @@ void ranges_rounddown(ranges *r, unsigned block_size)
 {
        struct range *i;
 
-       darray_foreach(i, *r) {
+       darray_for_each(*r, i) {
                i->start = round_up(i->start, block_size);
                i->end  = round_down(i->end, block_size);
                i->end  = max(i->end, i->start);
index 78827b847e42bf9b6d21199dcd38c5a4f31d30eb..a0e20ebf6eb970eb73f82c649dd7f0a66dbb437d 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/uuid.h>
-#include "ccan/darray/darray.h"
+#include "libbcachefs/darray.h"
 
 #define noreturn __attribute__((noreturn))
 
@@ -72,14 +72,14 @@ struct range {
        u64             end;
 };
 
-typedef darray(struct range) ranges;
+typedef DARRAY(struct range) ranges;
 
 static inline void range_add(ranges *data, u64 offset, u64 size)
 {
-       darray_append(*data, (struct range) {
+       darray_push(*data, ((struct range) {
                .start = offset,
                .end = offset + size
-       });
+       }));
 }
 
 void ranges_sort_merge(ranges *);
@@ -95,9 +95,9 @@ struct hole_iter {
 static inline struct range hole_iter_next(struct hole_iter *iter)
 {
        struct range r = {
-               .start  = iter->idx ? iter->r.item[iter->idx - 1].end : 0,
+               .start  = iter->idx ? iter->r.data[iter->idx - 1].end : 0,
                .end    = iter->idx < iter->r.size
-                       ? iter->r.item[iter->idx].start : iter->end,
+                       ? iter->r.data[iter->idx].start : iter->end,
        };
 
        BUG_ON(r.start > r.end);