mirror of
https://github.com/versity/scoutfs.git
synced 2026-07-28 02:55:20 +00:00
scoutfs: remove dead server allocator code
Remove the bitmap segno allocator code that the server used to use to manage allocations. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ CFLAGS_super.o = -DSCOUTFS_GIT_DESCRIBE=\"$(SCOUTFS_GIT_DESCRIBE)\" \
|
||||
|
||||
CFLAGS_scoutfs_trace.o = -I$(src) # define_trace.h double include
|
||||
|
||||
scoutfs-y += alloc.o bio.o btree.o client.o compact.o counters.o data.o dir.o \
|
||||
scoutfs-y += bio.o btree.o client.o compact.o counters.o data.o dir.o \
|
||||
export.o extents.o file.o inode.o ioctl.o item.o key.o lock.o \
|
||||
manifest.o msg.o options.o per_task.o seg.o server.o \
|
||||
scoutfs_trace.o sock.o sort_priv.o super.o sysfs.o trans.o \
|
||||
|
||||
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Versity Software, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/radix-tree.h>
|
||||
|
||||
#include "super.h"
|
||||
#include "format.h"
|
||||
#include "btree.h"
|
||||
#include "cmp.h"
|
||||
#include "alloc.h"
|
||||
#include "counters.h"
|
||||
#include "scoutfs_trace.h"
|
||||
|
||||
/*
|
||||
* scoutfs allocates segments using regions of an allocation bitmap
|
||||
* stored in btree items.
|
||||
*
|
||||
* Freed segments are recorded in nodes in an rbtree. The frees can't
|
||||
* satisfy allocation until they're committed to prevent overwriting
|
||||
* live data so they're only applied to the region nodes as their
|
||||
* transaction is written.
|
||||
*
|
||||
* We allocate by sweeping a cursor through the volume. This gives
|
||||
* racing unlocked readers more time to try to sample a stale freed
|
||||
* segment, when its safe to do so, before it is reallocated and
|
||||
* rewritten and they're forced to retry their racey read.
|
||||
*/
|
||||
|
||||
struct seg_alloc {
|
||||
struct rw_semaphore rwsem;
|
||||
struct rb_root pending_root;
|
||||
u64 next_segno;
|
||||
};
|
||||
|
||||
#define DECLARE_SEG_ALLOC(sb, name) \
|
||||
struct seg_alloc *name = SCOUTFS_SB(sb)->seg_alloc
|
||||
|
||||
struct pending_region {
|
||||
struct rb_node node;
|
||||
u64 ind;
|
||||
struct scoutfs_alloc_region_btree_val reg_val;
|
||||
};
|
||||
|
||||
static struct pending_region *find_pending(struct rb_root *root, u64 ind)
|
||||
{
|
||||
struct rb_node *node = root->rb_node;
|
||||
struct pending_region *pend;
|
||||
|
||||
while (node) {
|
||||
pend = container_of(node, struct pending_region, node);
|
||||
|
||||
if (ind < pend->ind)
|
||||
node = node->rb_left;
|
||||
else if (ind > pend->ind)
|
||||
node = node->rb_right;
|
||||
else
|
||||
return pend;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void insert_pending(struct rb_root *root, struct pending_region *ins)
|
||||
{
|
||||
struct rb_node **node = &root->rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct pending_region *pend;
|
||||
|
||||
while (*node) {
|
||||
parent = *node;
|
||||
pend = container_of(*node, struct pending_region, node);
|
||||
|
||||
if (ins->ind < pend->ind)
|
||||
node = &(*node)->rb_left;
|
||||
else if (ins->ind > pend->ind)
|
||||
node = &(*node)->rb_right;
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
||||
rb_link_node(&ins->node, parent, node);
|
||||
rb_insert_color(&ins->node, root);
|
||||
}
|
||||
|
||||
static int copy_region_item(struct scoutfs_alloc_region_btree_key *reg_key,
|
||||
struct scoutfs_alloc_region_btree_val *reg_val,
|
||||
struct scoutfs_btree_item_ref *iref)
|
||||
{
|
||||
if (iref->key_len != sizeof(struct scoutfs_alloc_region_btree_key) ||
|
||||
iref->val_len != sizeof(struct scoutfs_alloc_region_btree_val))
|
||||
return -EIO;
|
||||
|
||||
memcpy(reg_key, iref->key, iref->key_len);
|
||||
memcpy(reg_val, iref->val, iref->val_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're careful to copy the bitmaps out to aligned versions so that
|
||||
* we can use native bitops that require aligned longs.
|
||||
*/
|
||||
int scoutfs_alloc_segno(struct super_block *sb, u64 *segno)
|
||||
{
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
struct scoutfs_alloc_region_btree_key reg_key;
|
||||
struct scoutfs_alloc_region_btree_val __aligned(sizeof(long)) reg_val;
|
||||
SCOUTFS_BTREE_ITEM_REF(iref);
|
||||
DECLARE_SEG_ALLOC(sb, sal);
|
||||
u64 ind;
|
||||
int ret;
|
||||
int nr;
|
||||
|
||||
down_write(&sal->rwsem);
|
||||
|
||||
/* initially sweep through all segments */
|
||||
if (super->alloc_uninit != super->total_segs) {
|
||||
*segno = le64_to_cpu(super->alloc_uninit);
|
||||
/* done when inc hits total_segs */
|
||||
le64_add_cpu(&super->alloc_uninit, 1);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* but usually search for region nodes */
|
||||
ind = sal->next_segno >> SCOUTFS_ALLOC_REGION_SHIFT;
|
||||
nr = sal->next_segno & SCOUTFS_ALLOC_REGION_MASK;
|
||||
|
||||
for (;;) {
|
||||
reg_key.index = cpu_to_be64(ind);
|
||||
ret = scoutfs_btree_next(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key), &iref);
|
||||
if (ret == -ENOENT && ind != 0) {
|
||||
ind = 0;
|
||||
nr = 0;
|
||||
continue;
|
||||
}
|
||||
if (ret < 0) {
|
||||
if (ret == -ENOENT)
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = copy_region_item(®_key, ®_val, &iref);
|
||||
scoutfs_btree_put_iref(&iref);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ind = be64_to_cpu(reg_key.index);
|
||||
nr = find_next_bit_le(reg_val.bits, SCOUTFS_ALLOC_REGION_BITS, nr);
|
||||
if (nr < SCOUTFS_ALLOC_REGION_BITS) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* possible for nr to be after all free bits, keep going */
|
||||
ind++;
|
||||
nr = 0;
|
||||
}
|
||||
|
||||
clear_bit_le(nr, reg_val.bits);
|
||||
|
||||
if (bitmap_empty((long *)reg_val.bits, SCOUTFS_ALLOC_REGION_BITS))
|
||||
ret = scoutfs_btree_delete(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key));
|
||||
else
|
||||
ret = scoutfs_btree_update(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key),
|
||||
®_val, sizeof(reg_val));
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
*segno = (ind << SCOUTFS_ALLOC_REGION_SHIFT) + nr;
|
||||
sal->next_segno = *segno + 1;
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (ret == 0) {
|
||||
scoutfs_inc_counter(sb, alloc_alloc);
|
||||
le64_add_cpu(&super->free_segs, -1);
|
||||
}
|
||||
up_write(&sal->rwsem);
|
||||
|
||||
trace_scoutfs_alloc_segno(sb, *segno, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record newly freed sgements in pending regions. These are applied to
|
||||
* persistent regions in btree items as the transaction commits.
|
||||
*/
|
||||
int scoutfs_alloc_free(struct super_block *sb, u64 segno)
|
||||
{
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
struct pending_region *pend;
|
||||
DECLARE_SEG_ALLOC(sb, sal);
|
||||
u64 ind;
|
||||
int ret;
|
||||
int nr;
|
||||
|
||||
ind = segno >> SCOUTFS_ALLOC_REGION_SHIFT;
|
||||
nr = segno & SCOUTFS_ALLOC_REGION_MASK;
|
||||
|
||||
down_write(&sal->rwsem);
|
||||
|
||||
pend = find_pending(&sal->pending_root, ind);
|
||||
if (!pend) {
|
||||
pend = kzalloc(sizeof(struct pending_region), GFP_NOFS);
|
||||
if (!pend) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pend->ind = ind;
|
||||
insert_pending(&sal->pending_root, pend);
|
||||
}
|
||||
|
||||
set_bit_le(nr, pend->reg_val.bits);
|
||||
scoutfs_inc_counter(sb, alloc_free);
|
||||
le64_add_cpu(&super->free_segs, 1);
|
||||
ret = 0;
|
||||
out:
|
||||
up_write(&sal->rwsem);
|
||||
|
||||
trace_scoutfs_alloc_free(sb, segno, ind, nr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the pending frees to create the final set of dirty btree
|
||||
* blocks. The caller will write the btree blocks. We're destroying
|
||||
* the pending free record here so from this point on the pending free
|
||||
* blocks could be visible to allocation. The caller can't finish with
|
||||
* the transaction until the btree is written successfully.
|
||||
*/
|
||||
int scoutfs_alloc_apply_pending(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
DECLARE_SEG_ALLOC(sb, sal);
|
||||
struct pending_region *pend;
|
||||
struct rb_node *node;
|
||||
struct scoutfs_alloc_region_btree_key reg_key;
|
||||
struct scoutfs_alloc_region_btree_val __aligned(sizeof(long)) reg_val;
|
||||
SCOUTFS_BTREE_ITEM_REF(iref);
|
||||
int ret;
|
||||
|
||||
down_write(&sal->rwsem);
|
||||
|
||||
ret = 0;
|
||||
while ((node = rb_first(&sal->pending_root))) {
|
||||
pend = container_of(node, struct pending_region, node);
|
||||
|
||||
/* see if we have a region for this index */
|
||||
reg_key.index = cpu_to_be64(pend->ind);
|
||||
ret = scoutfs_btree_lookup(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key), &iref);
|
||||
if (ret == -ENOENT) {
|
||||
/* create a new item if we don't */
|
||||
ret = scoutfs_btree_insert(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key),
|
||||
&pend->reg_val,
|
||||
sizeof(pend->reg_val));
|
||||
} else if (ret == 0) {
|
||||
/* and update the existing item if we do */
|
||||
ret = copy_region_item(®_key, ®_val, &iref);
|
||||
scoutfs_btree_put_iref(&iref);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
bitmap_or((long *)reg_val.bits, (long *)reg_val.bits,
|
||||
(long *)pend->reg_val.bits,
|
||||
SCOUTFS_ALLOC_REGION_BITS);
|
||||
|
||||
ret = scoutfs_btree_update(sb, &super->alloc_root,
|
||||
®_key, sizeof(reg_key),
|
||||
®_val, sizeof(reg_val));
|
||||
}
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
rb_erase(&pend->node, &sal->pending_root);
|
||||
kfree(pend);
|
||||
}
|
||||
|
||||
up_write(&sal->rwsem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of blocks free for statfs.
|
||||
*/
|
||||
u64 scoutfs_alloc_bfree(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
DECLARE_SEG_ALLOC(sb, sal);
|
||||
u64 bfree;
|
||||
|
||||
down_read(&sal->rwsem);
|
||||
bfree = le64_to_cpu(super->free_segs) << SCOUTFS_SEGMENT_BLOCK_SHIFT;
|
||||
up_read(&sal->rwsem);
|
||||
|
||||
return bfree;
|
||||
}
|
||||
|
||||
int scoutfs_alloc_setup(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct seg_alloc *sal;
|
||||
|
||||
/* bits need to be aligned so hosts can use native bitops */
|
||||
BUILD_BUG_ON(offsetof(struct scoutfs_alloc_region_btree_val, bits) &
|
||||
(sizeof(long) - 1));
|
||||
|
||||
sal = kzalloc(sizeof(struct seg_alloc), GFP_KERNEL);
|
||||
if (!sal)
|
||||
return -ENOMEM;
|
||||
|
||||
init_rwsem(&sal->rwsem);
|
||||
sal->pending_root = RB_ROOT;
|
||||
|
||||
/* XXX read next_segno from super? */
|
||||
|
||||
sbi->seg_alloc = sal;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scoutfs_alloc_destroy(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
DECLARE_SEG_ALLOC(sb, sal);
|
||||
struct pending_region *pend;
|
||||
struct rb_node *node;
|
||||
|
||||
if (sal) {
|
||||
while ((node = rb_first(&sal->pending_root))) {
|
||||
pend = container_of(node, struct pending_region, node);
|
||||
rb_erase(&pend->node, &sal->pending_root);
|
||||
kfree(pend);
|
||||
}
|
||||
kfree(sal);
|
||||
sbi->seg_alloc = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef _SCOUTFS_ALLOC_H_
|
||||
#define _SCOUTFS_ALLOC_H_
|
||||
|
||||
struct scoutfs_alloc_region;
|
||||
|
||||
int scoutfs_alloc_segno(struct super_block *sb, u64 *segno);
|
||||
int scoutfs_alloc_free(struct super_block *sb, u64 segno);
|
||||
|
||||
int scoutfs_alloc_apply_pending(struct super_block *sb);
|
||||
u64 scoutfs_alloc_bfree(struct super_block *sb);
|
||||
|
||||
int scoutfs_alloc_setup(struct super_block *sb);
|
||||
void scoutfs_alloc_destroy(struct super_block *sb);
|
||||
|
||||
#endif
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <linux/in.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/sort.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#include "format.h"
|
||||
@@ -607,97 +606,6 @@ int scoutfs_client_record_segment(struct super_block *sb,
|
||||
sizeof(net_ment), NULL, 0);
|
||||
}
|
||||
|
||||
static int sort_cmp_u64s(const void *A, const void *B)
|
||||
{
|
||||
const u64 *a = A;
|
||||
const u64 *b = B;
|
||||
|
||||
return *a < *b ? -1 : *a > *b ? 1 : 0;
|
||||
}
|
||||
|
||||
static void sort_swap_u64s(void *A, void *B, int size)
|
||||
{
|
||||
u64 *a = A;
|
||||
u64 *b = B;
|
||||
|
||||
swap(*a, *b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a 0-terminated allocated array of segnos, the caller is
|
||||
* responsible for freeing it.
|
||||
*
|
||||
* This double alloc is silly. But the caller does have an easier time
|
||||
* with native u64s. We'll probably clean this up.
|
||||
*/
|
||||
u64 *scoutfs_client_bulk_alloc(struct super_block *sb)
|
||||
{
|
||||
struct client_info *client = SCOUTFS_SB(sb)->client_info;
|
||||
struct scoutfs_net_segnos *ns = NULL;
|
||||
u64 *segnos = NULL;
|
||||
size_t size;
|
||||
unsigned nr;
|
||||
u64 prev;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
size = offsetof(struct scoutfs_net_segnos,
|
||||
segnos[SCOUTFS_BULK_ALLOC_COUNT]);
|
||||
ns = kmalloc(size, GFP_NOFS);
|
||||
if (!ns) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = client_request(client, SCOUTFS_NET_BULK_ALLOC, NULL, 0, ns, size);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nr = le16_to_cpu(ns->nr);
|
||||
if (nr == 0) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nr > SCOUTFS_BULK_ALLOC_COUNT) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
segnos = kmalloc_array(nr + 1, sizeof(*segnos), GFP_NOFS);
|
||||
if (segnos == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
segnos[i] = le64_to_cpu(ns->segnos[i]);
|
||||
segnos[nr] = 0;
|
||||
|
||||
/* sort segnos for the caller so they can merge easily */
|
||||
sort(segnos, nr, sizeof(segnos[0]), sort_cmp_u64s, sort_swap_u64s);
|
||||
|
||||
/* make sure they're all non-zero and unique */
|
||||
prev = 0;
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (segnos[i] == prev) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
prev = segnos[i];
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(ns);
|
||||
if (ret) {
|
||||
kfree(segnos);
|
||||
segnos = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return segnos;
|
||||
}
|
||||
|
||||
int scoutfs_client_advance_seq(struct super_block *sb, u64 *seq)
|
||||
{
|
||||
struct client_info *client = SCOUTFS_SB(sb)->client_info;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "compact.h"
|
||||
#include "manifest.h"
|
||||
#include "counters.h"
|
||||
#include "alloc.h"
|
||||
#include "server.h"
|
||||
#include "scoutfs_trace.h"
|
||||
|
||||
|
||||
+1
-3
@@ -12,8 +12,6 @@
|
||||
* other places by this macro. Don't forget to update LAST_COUNTER.
|
||||
*/
|
||||
#define EXPAND_EACH_COUNTER \
|
||||
EXPAND_COUNTER(alloc_alloc) \
|
||||
EXPAND_COUNTER(alloc_free) \
|
||||
EXPAND_COUNTER(btree_read_error) \
|
||||
EXPAND_COUNTER(btree_stale_read) \
|
||||
EXPAND_COUNTER(btree_write_error) \
|
||||
@@ -117,7 +115,7 @@
|
||||
EXPAND_COUNTER(trans_level0_seg_writes)
|
||||
|
||||
|
||||
#define FIRST_COUNTER alloc_alloc
|
||||
#define FIRST_COUNTER btree_read_error
|
||||
#define LAST_COUNTER trans_level0_seg_writes
|
||||
|
||||
#undef EXPAND_COUNTER
|
||||
|
||||
@@ -249,19 +249,6 @@ struct scoutfs_extent_btree_key {
|
||||
__be64 minor;
|
||||
} __packed;
|
||||
|
||||
#define SCOUTFS_ALLOC_REGION_SHIFT 8
|
||||
#define SCOUTFS_ALLOC_REGION_BITS (1 << SCOUTFS_ALLOC_REGION_SHIFT)
|
||||
#define SCOUTFS_ALLOC_REGION_MASK (SCOUTFS_ALLOC_REGION_BITS - 1)
|
||||
|
||||
struct scoutfs_alloc_region_btree_key {
|
||||
__be64 index;
|
||||
} __packed;
|
||||
|
||||
/* The bits need to be aligned so that the hosts can use native long bit ops */
|
||||
struct scoutfs_alloc_region_btree_val {
|
||||
__le64 bits[SCOUTFS_ALLOC_REGION_BITS / 64];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* The max number of links defines the max number of entries that we can
|
||||
* index in o(log n) and the static list head storage size in the
|
||||
@@ -380,9 +367,6 @@ struct scoutfs_super_block {
|
||||
__u8 uuid[SCOUTFS_UUID_BYTES];
|
||||
__le64 next_ino;
|
||||
__le64 next_seq;
|
||||
__le64 alloc_uninit;
|
||||
__le64 total_segs;
|
||||
__le64 free_segs;
|
||||
__le64 total_blocks;
|
||||
__le64 free_blocks;
|
||||
__le64 alloc_cursor;
|
||||
@@ -571,14 +555,6 @@ struct scoutfs_net_manifest_entry {
|
||||
__u8 keys[0];
|
||||
} __packed;
|
||||
|
||||
/* XXX I dunno, totally made up */
|
||||
#define SCOUTFS_BULK_ALLOC_COUNT 32
|
||||
|
||||
struct scoutfs_net_segnos {
|
||||
__le16 nr;
|
||||
__le64 segnos[0];
|
||||
} __packed;
|
||||
|
||||
struct scoutfs_net_statfs {
|
||||
__le64 total_blocks; /* total blocks in device */
|
||||
__le64 next_ino; /* next unused inode number */
|
||||
@@ -601,7 +577,6 @@ enum {
|
||||
SCOUTFS_NET_ALLOC_EXTENT,
|
||||
SCOUTFS_NET_ALLOC_SEGNO,
|
||||
SCOUTFS_NET_RECORD_SEGMENT,
|
||||
SCOUTFS_NET_BULK_ALLOC,
|
||||
SCOUTFS_NET_ADVANCE_SEQ,
|
||||
SCOUTFS_NET_GET_LAST_SEQ,
|
||||
SCOUTFS_NET_GET_MANIFEST_ROOT,
|
||||
|
||||
@@ -1087,54 +1087,6 @@ TRACE_EVENT(scoutfs_compact_func,
|
||||
TP_printk(FSID_FMT" ret %d", __entry->fsid, __entry->ret)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scoutfs_alloc_free,
|
||||
TP_PROTO(struct super_block *sb, __u64 segno, __u64 index, int nr,
|
||||
int ret),
|
||||
|
||||
TP_ARGS(sb, segno, index, nr, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(__u64, fsid)
|
||||
__field(__u64, segno)
|
||||
__field(__u64, index)
|
||||
__field(int, nr)
|
||||
__field(int, ret)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fsid = FSID_ARG(sb);
|
||||
__entry->segno = segno;
|
||||
__entry->index = index;
|
||||
__entry->nr = nr;
|
||||
__entry->ret = ret;
|
||||
),
|
||||
|
||||
TP_printk(FSID_FMT" freeing segno %llu ind %llu nr %d ret %d",
|
||||
__entry->fsid, __entry->segno, __entry->index, __entry->nr,
|
||||
__entry->ret)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scoutfs_alloc_segno,
|
||||
TP_PROTO(struct super_block *sb, __u64 segno, int ret),
|
||||
|
||||
TP_ARGS(sb, segno, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(__u64, fsid)
|
||||
__field(__u64, segno)
|
||||
__field(int, ret)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fsid = FSID_ARG(sb);
|
||||
__entry->segno = segno;
|
||||
__entry->ret = ret;
|
||||
),
|
||||
|
||||
TP_printk(FSID_FMT" segno %llu ret %d", __entry->fsid, __entry->segno,
|
||||
__entry->ret)
|
||||
);
|
||||
|
||||
TRACE_EVENT(scoutfs_write_begin,
|
||||
TP_PROTO(struct super_block *sb, u64 ino, loff_t pos, unsigned len),
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "kvec.h"
|
||||
#include "cmp.h"
|
||||
#include "manifest.h"
|
||||
#include "alloc.h"
|
||||
#include "key.h"
|
||||
#include "counters.h"
|
||||
#include "triggers.h"
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <linux/in.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
#include "format.h"
|
||||
@@ -27,7 +26,6 @@
|
||||
#include "inode.h"
|
||||
#include "btree.h"
|
||||
#include "manifest.h"
|
||||
#include "alloc.h"
|
||||
#include "seg.h"
|
||||
#include "compact.h"
|
||||
#include "scoutfs_trace.h"
|
||||
@@ -811,58 +809,6 @@ out:
|
||||
return send_reply(conn, id, type, ret, NULL, 0);
|
||||
}
|
||||
|
||||
static int process_bulk_alloc(struct server_connection *conn, u64 id, u8 type,
|
||||
void *data, unsigned data_len)
|
||||
{
|
||||
struct server_info *server = conn->server;
|
||||
struct super_block *sb = server->sb;
|
||||
struct scoutfs_net_segnos *ns = NULL;
|
||||
struct commit_waiter cw;
|
||||
size_t size;
|
||||
u64 segno;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (data_len != 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = offsetof(struct scoutfs_net_segnos,
|
||||
segnos[SCOUTFS_BULK_ALLOC_COUNT]);
|
||||
ns = kmalloc(size, GFP_NOFS);
|
||||
if (!ns) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
down_read(&server->commit_rwsem);
|
||||
|
||||
ns->nr = cpu_to_le16(SCOUTFS_BULK_ALLOC_COUNT);
|
||||
for (i = 0; i < SCOUTFS_BULK_ALLOC_COUNT; i++) {
|
||||
ret = scoutfs_alloc_segno(sb, &segno);
|
||||
if (ret) {
|
||||
while (i-- > 0)
|
||||
scoutfs_alloc_free(sb,
|
||||
le64_to_cpu(ns->segnos[i]));
|
||||
break;
|
||||
}
|
||||
|
||||
ns->segnos[i] = cpu_to_le64(segno);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
queue_commit_work(server, &cw);
|
||||
up_read(&server->commit_rwsem);
|
||||
|
||||
if (ret == 0)
|
||||
ret = wait_for_commit(server, &cw, id, type);
|
||||
out:
|
||||
ret = send_reply(conn, id, type, ret, ns, size);
|
||||
kfree(ns);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct pending_seq {
|
||||
struct list_head head;
|
||||
u64 seq;
|
||||
@@ -1125,7 +1071,6 @@ static void scoutfs_server_process_func(struct work_struct *work)
|
||||
[SCOUTFS_NET_ALLOC_EXTENT] = process_alloc_extent,
|
||||
[SCOUTFS_NET_ALLOC_SEGNO] = process_alloc_segno,
|
||||
[SCOUTFS_NET_RECORD_SEGMENT] = process_record_segment,
|
||||
[SCOUTFS_NET_BULK_ALLOC] = process_bulk_alloc,
|
||||
[SCOUTFS_NET_ADVANCE_SEQ] = process_advance_seq,
|
||||
[SCOUTFS_NET_GET_LAST_SEQ] = process_get_last_seq,
|
||||
[SCOUTFS_NET_GET_MANIFEST_ROOT] = process_get_manifest_root,
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "manifest.h"
|
||||
#include "seg.h"
|
||||
#include "bio.h"
|
||||
#include "alloc.h"
|
||||
#include "compact.h"
|
||||
#include "data.h"
|
||||
#include "lock.h"
|
||||
|
||||
Reference in New Issue
Block a user