]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/buckets.h
Update bcachefs sources to 8d3fc97ca3 bcachefs: Fixes for building in userspace
[bcachefs-tools-debian] / libbcachefs / buckets.h
index 56c06ccde14f8a39a19ded9475d6861624f35d63..b6a1db7619ff659666eb385595a0beb7c983daf9 100644 (file)
@@ -259,15 +259,39 @@ int bch2_trans_mark_dev_sb(struct bch_fs *, struct bch_dev *);
 static inline void bch2_disk_reservation_put(struct bch_fs *c,
                                             struct disk_reservation *res)
 {
-       this_cpu_sub(*c->online_reserved, res->sectors);
-       res->sectors = 0;
+       if (res->sectors) {
+               this_cpu_sub(*c->online_reserved, res->sectors);
+               res->sectors = 0;
+       }
 }
 
 #define BCH_DISK_RESERVATION_NOFAIL            (1 << 0)
 
-int bch2_disk_reservation_add(struct bch_fs *,
-                             struct disk_reservation *,
-                             u64, int);
+int __bch2_disk_reservation_add(struct bch_fs *,
+                               struct disk_reservation *,
+                               u64, int);
+
+static inline int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
+                                           u64 sectors, int flags)
+{
+#ifdef __KERNEL__
+       u64 old, new;
+
+       do {
+               old = this_cpu_read(c->pcpu->sectors_available);
+               if (sectors > old)
+                       return __bch2_disk_reservation_add(c, res, sectors, flags);
+
+               new = old - sectors;
+       } while (this_cpu_cmpxchg(c->pcpu->sectors_available, old, new) != old);
+
+       this_cpu_add(*c->online_reserved, sectors);
+       res->sectors                    += sectors;
+       return 0;
+#else
+       return __bch2_disk_reservation_add(c, res, sectors, flags);
+#endif
+}
 
 static inline struct disk_reservation
 bch2_disk_reservation_init(struct bch_fs *c, unsigned nr_replicas)