mirror of
https://github.com/versity/scoutfs.git
synced 2026-06-08 04:32:35 +00:00
scoutfs: use rid instead of node_id in items
Use the mount's generated random id in persistent items and the lock that protects them instead of the assigned node_id. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -63,8 +63,8 @@
|
||||
|
||||
/*
|
||||
* The largest extent that we'll store in a single item. This will
|
||||
* determine the granularity of interleaved concurrent allocations on a
|
||||
* node. Sequential max length allocations could still see contiguous
|
||||
* determine the granularity of interleaved concurrent allocations in a
|
||||
* mount. Sequential max length allocations could still see contiguous
|
||||
* physical extent allocations. It limits the amount of IO needed to
|
||||
* invalidate a lock. And it determines the granularity of parallel
|
||||
* writes to a file between nodes.
|
||||
@@ -100,12 +100,12 @@ static void init_file_extent_key(struct scoutfs_key *key, u64 ino, u64 last)
|
||||
};
|
||||
}
|
||||
|
||||
static void init_free_extent_key(struct scoutfs_key *key, u8 type, u64 node_id,
|
||||
static void init_free_extent_key(struct scoutfs_key *key, u8 type, u64 rid,
|
||||
u64 major, u64 minor)
|
||||
{
|
||||
*key = (struct scoutfs_key) {
|
||||
.sk_zone = SCOUTFS_NODE_ZONE,
|
||||
.sknf_node_id = cpu_to_le64(node_id),
|
||||
.sk_zone = SCOUTFS_RID_ZONE,
|
||||
.sknf_rid = cpu_to_le64(rid),
|
||||
.sk_type = type,
|
||||
.sknf_major = cpu_to_le64(major),
|
||||
.sknf_minor = cpu_to_le64(minor),
|
||||
@@ -135,7 +135,7 @@ static int init_extent_from_item(struct scoutfs_extent *ext,
|
||||
flags = fex->flags;
|
||||
|
||||
} else {
|
||||
owner = le64_to_cpu(key->sknf_node_id);
|
||||
owner = le64_to_cpu(key->sknf_rid);
|
||||
start = le64_to_cpu(key->sknf_major);
|
||||
len = le64_to_cpu(key->sknf_minor);
|
||||
if (key->sk_type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE)
|
||||
@@ -159,7 +159,7 @@ static int init_extent_from_item(struct scoutfs_extent *ext,
|
||||
* keeping their _BLOCKS_ item in sync with the primary _BLKNO_ item
|
||||
* that callers operate on.
|
||||
*
|
||||
* The count of free blocks stored in node items is kept consistent by
|
||||
* The count of free blocks stored in items is kept consistent by
|
||||
* updating the count every time we create or delete items. Updated
|
||||
* extents are deleted and then recreated so the count can bounce around
|
||||
* a bit, but it's OK for it to be imprecise at the margins.
|
||||
@@ -315,9 +315,9 @@ static s64 truncate_one_extent(struct super_block *sb, struct inode *inode,
|
||||
/* free an allocated mapping */
|
||||
if (rem.map) {
|
||||
scoutfs_extent_init(&fr, SCOUTFS_FREE_EXTENT_BLKNO_TYPE,
|
||||
sbi->node_id, rem.map, rem.len, 0, 0);
|
||||
sbi->rid, rem.map, rem.len, 0, 0);
|
||||
ret = scoutfs_extent_add(sb, data_extent_io, &fr,
|
||||
sbi->node_id_lock);
|
||||
sbi->rid_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
rem_fr = true;
|
||||
@@ -360,7 +360,7 @@ out:
|
||||
SC_DATA_EXTENT_TRUNC_CLEANUP,
|
||||
corrupt_data_extent_trunc_cleanup, &rem);
|
||||
scoutfs_extent_cleanup(ret < 0 && rem_fr, scoutfs_extent_remove, sb,
|
||||
data_extent_io, &fr, sbi->node_id_lock,
|
||||
data_extent_io, &fr, sbi->rid_lock,
|
||||
SC_DATA_EXTENT_TRUNC_CLEANUP,
|
||||
corrupt_data_extent_trunc_cleanup, &rem);
|
||||
|
||||
@@ -457,9 +457,9 @@ static int get_server_extent(struct super_block *sb)
|
||||
goto out;
|
||||
|
||||
scoutfs_extent_init(&ext, SCOUTFS_FREE_EXTENT_BLKNO_TYPE,
|
||||
sbi->node_id, start, len, 0, 0);
|
||||
sbi->rid, start, len, 0, 0);
|
||||
trace_scoutfs_data_get_server_extent(sb, &ext);
|
||||
ret = scoutfs_extent_add(sb, data_extent_io, &ext, sbi->node_id_lock);
|
||||
ret = scoutfs_extent_add(sb, data_extent_io, &ext, sbi->rid_lock);
|
||||
/* XXX don't free extent on error, crash recovery with server */
|
||||
|
||||
out:
|
||||
@@ -488,14 +488,14 @@ static int find_free_extent(struct super_block *sb, u64 len,
|
||||
for (;;) {
|
||||
/* first try to find the first sufficient extent */
|
||||
scoutfs_extent_init(ext, SCOUTFS_FREE_EXTENT_BLOCKS_TYPE,
|
||||
sbi->node_id, 0, len, 0, 0);
|
||||
sbi->rid, 0, len, 0, 0);
|
||||
ret = scoutfs_extent_next(sb, data_extent_io, ext,
|
||||
sbi->node_id_lock);
|
||||
sbi->rid_lock);
|
||||
|
||||
/* if none big enough, look for last largest smaller */
|
||||
if (ret == -ENOENT && len > 1)
|
||||
ret = scoutfs_extent_prev(sb, data_extent_io, ext,
|
||||
sbi->node_id_lock);
|
||||
sbi->rid_lock);
|
||||
|
||||
/* ask the server for more if we think it'll help */
|
||||
if (ret == -ENOENT || ext->len < len) {
|
||||
@@ -510,7 +510,7 @@ static int find_free_extent(struct super_block *sb, u64 len,
|
||||
|
||||
if (ret == 0)
|
||||
scoutfs_extent_init(ext, SCOUTFS_FREE_EXTENT_BLKNO_TYPE,
|
||||
sbi->node_id, ext->start,
|
||||
sbi->rid, ext->start,
|
||||
min(ext->len, len), 0, 0);
|
||||
|
||||
trace_scoutfs_data_find_free_extent(sb, ext);
|
||||
@@ -587,7 +587,7 @@ static int alloc_block(struct super_block *sb, struct inode *inode,
|
||||
iblock, 1, fr.start, 0);
|
||||
|
||||
/* remove the free extent that we're allocating */
|
||||
ret = scoutfs_extent_remove(sb, data_extent_io, &fr, sbi->node_id_lock);
|
||||
ret = scoutfs_extent_remove(sb, data_extent_io, &fr, sbi->rid_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
add_fr = true;
|
||||
@@ -631,7 +631,7 @@ out:
|
||||
SC_DATA_EXTENT_ALLOC_CLEANUP,
|
||||
corrupt_data_extent_alloc_cleanup, &blk);
|
||||
scoutfs_extent_cleanup(ret < 0 && add_fr, scoutfs_extent_add, sb,
|
||||
data_extent_io, &fr, sbi->node_id_lock,
|
||||
data_extent_io, &fr, sbi->rid_lock,
|
||||
SC_DATA_EXTENT_ALLOC_CLEANUP,
|
||||
corrupt_data_extent_alloc_cleanup, &blk);
|
||||
|
||||
@@ -1069,7 +1069,7 @@ static s64 fallocate_one_extent(struct super_block *sb, u64 ino, u64 start,
|
||||
if (WARN_ON_ONCE(ret))
|
||||
goto out;
|
||||
|
||||
ret = scoutfs_extent_remove(sb, data_extent_io, &fr, sbi->node_id_lock);
|
||||
ret = scoutfs_extent_remove(sb, data_extent_io, &fr, sbi->rid_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
add_fr = true;
|
||||
@@ -1093,7 +1093,7 @@ out:
|
||||
SC_DATA_EXTENT_FALLOCATE_CLEANUP,
|
||||
corrupt_data_extent_fallocate_cleanup, &fal);
|
||||
scoutfs_extent_cleanup(ret < 0 && add_fr, scoutfs_extent_add, sb,
|
||||
data_extent_io, &fr, sbi->node_id_lock,
|
||||
data_extent_io, &fr, sbi->rid_lock,
|
||||
SC_DATA_EXTENT_FALLOCATE_CLEANUP,
|
||||
corrupt_data_extent_alloc_cleanup, &fal);
|
||||
return ret;
|
||||
@@ -1649,9 +1649,9 @@ static void scoutfs_data_return_server_extents_worker(struct work_struct *work)
|
||||
free > NODE_FREE_HIGH_WATER_BLOCKS) {
|
||||
|
||||
scoutfs_extent_init(&ext, SCOUTFS_FREE_EXTENT_BLOCKS_TYPE,
|
||||
sbi->node_id, 0, 1, 0, 0);
|
||||
sbi->rid, 0, 1, 0, 0);
|
||||
ret = scoutfs_extent_next(sb, data_extent_io, &ext,
|
||||
sbi->node_id_lock);
|
||||
sbi->rid_lock);
|
||||
if (ret < 0) {
|
||||
if (ret == -ENOENT)
|
||||
ret = 0;
|
||||
@@ -1664,7 +1664,7 @@ static void scoutfs_data_return_server_extents_worker(struct work_struct *work)
|
||||
ext.len = min(ext.len, free - NODE_FREE_HIGH_WATER_BLOCKS);
|
||||
|
||||
ret = scoutfs_extent_remove(sb, data_extent_io, &ext,
|
||||
sbi->node_id_lock);
|
||||
sbi->rid_lock);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
|
||||
@@ -114,12 +114,12 @@ struct scoutfs_key {
|
||||
#define skxi_id _sk_third
|
||||
|
||||
/* node free extent */
|
||||
#define sknf_node_id _sk_first
|
||||
#define sknf_rid _sk_first
|
||||
#define sknf_major _sk_second
|
||||
#define sknf_minor _sk_third
|
||||
|
||||
/* node orphan inode */
|
||||
#define sko_node_id _sk_first
|
||||
#define sko_rid _sk_first
|
||||
#define sko_ino _sk_second
|
||||
|
||||
/* inode */
|
||||
@@ -357,7 +357,7 @@ struct scoutfs_segment_block {
|
||||
*/
|
||||
#define SCOUTFS_INODE_INDEX_ZONE 1
|
||||
#define SCOUTFS_XATTR_INDEX_ZONE 2
|
||||
#define SCOUTFS_NODE_ZONE 3
|
||||
#define SCOUTFS_RID_ZONE 3
|
||||
#define SCOUTFS_FS_ZONE 4
|
||||
#define SCOUTFS_LOCK_ZONE 5
|
||||
#define SCOUTFS_MAX_ZONE 8 /* power of 2 is efficient */
|
||||
@@ -370,9 +370,10 @@ struct scoutfs_segment_block {
|
||||
/* xattr index zone */
|
||||
#define SCOUTFS_XATTR_INDEX_NAME_TYPE 1
|
||||
|
||||
/* node zone (also used in server alloc btree) */
|
||||
/* rid zone (also used in server alloc btree) */
|
||||
#define SCOUTFS_FREE_EXTENT_BLKNO_TYPE 1
|
||||
#define SCOUTFS_FREE_EXTENT_BLOCKS_TYPE 2
|
||||
#define SCOUTFS_ORPHAN_TYPE 3
|
||||
|
||||
/* fs zone */
|
||||
#define SCOUTFS_INODE_TYPE 1
|
||||
@@ -382,12 +383,11 @@ struct scoutfs_segment_block {
|
||||
#define SCOUTFS_LINK_BACKREF_TYPE 5
|
||||
#define SCOUTFS_SYMLINK_TYPE 6
|
||||
#define SCOUTFS_FILE_EXTENT_TYPE 7
|
||||
#define SCOUTFS_ORPHAN_TYPE 8
|
||||
|
||||
/* lock zone, only ever found in lock ranges, never in persistent items */
|
||||
#define SCOUTFS_RENAME_TYPE 1
|
||||
|
||||
#define SCOUTFS_MAX_TYPE 16 /* power of 2 is efficient */
|
||||
#define SCOUTFS_MAX_TYPE 8 /* power of 2 is efficient */
|
||||
|
||||
/*
|
||||
* File extents have more data than easily fits in the key so we move
|
||||
|
||||
@@ -1410,11 +1410,11 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
|
||||
return inode;
|
||||
}
|
||||
|
||||
static void init_orphan_key(struct scoutfs_key *key, u64 node_id, u64 ino)
|
||||
static void init_orphan_key(struct scoutfs_key *key, u64 rid, u64 ino)
|
||||
{
|
||||
*key = (struct scoutfs_key) {
|
||||
.sk_zone = SCOUTFS_NODE_ZONE,
|
||||
.sko_node_id = cpu_to_le64(node_id),
|
||||
.sk_zone = SCOUTFS_RID_ZONE,
|
||||
.sko_rid = cpu_to_le64(rid),
|
||||
.sk_type = SCOUTFS_ORPHAN_TYPE,
|
||||
.sko_ino = cpu_to_le64(ino),
|
||||
};
|
||||
@@ -1423,11 +1423,11 @@ static void init_orphan_key(struct scoutfs_key *key, u64 node_id, u64 ino)
|
||||
static int remove_orphan_item(struct super_block *sb, u64 ino)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_lock *lock = sbi->node_id_lock;
|
||||
struct scoutfs_lock *lock = sbi->rid_lock;
|
||||
struct scoutfs_key key;
|
||||
int ret;
|
||||
|
||||
init_orphan_key(&key, sbi->node_id, ino);
|
||||
init_orphan_key(&key, sbi->rid, ino);
|
||||
|
||||
ret = scoutfs_item_delete(sb, &key, lock);
|
||||
if (ret == -ENOENT)
|
||||
@@ -1574,7 +1574,7 @@ int scoutfs_drop_inode(struct inode *inode)
|
||||
int scoutfs_scan_orphans(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_lock *lock = sbi->node_id_lock;
|
||||
struct scoutfs_lock *lock = sbi->rid_lock;
|
||||
struct scoutfs_key key;
|
||||
struct scoutfs_key last;
|
||||
int err = 0;
|
||||
@@ -1582,8 +1582,8 @@ int scoutfs_scan_orphans(struct super_block *sb)
|
||||
|
||||
trace_scoutfs_scan_orphans(sb);
|
||||
|
||||
init_orphan_key(&key, sbi->node_id, 0);
|
||||
init_orphan_key(&last, sbi->node_id, ~0ULL);
|
||||
init_orphan_key(&key, sbi->rid, 0);
|
||||
init_orphan_key(&last, sbi->rid, ~0ULL);
|
||||
|
||||
while (1) {
|
||||
ret = scoutfs_item_next(sb, &key, &last, NULL, lock);
|
||||
@@ -1612,13 +1612,13 @@ int scoutfs_orphan_inode(struct inode *inode)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_lock *lock = sbi->node_id_lock;
|
||||
struct scoutfs_lock *lock = sbi->rid_lock;
|
||||
struct scoutfs_key key;
|
||||
int ret;
|
||||
|
||||
trace_scoutfs_orphan_inode(sb, inode);
|
||||
|
||||
init_orphan_key(&key, sbi->node_id, scoutfs_ino(inode));
|
||||
init_orphan_key(&key, sbi->rid, scoutfs_ino(inode));
|
||||
|
||||
ret = scoutfs_item_create(sb, &key, NULL, lock);
|
||||
|
||||
|
||||
@@ -1177,29 +1177,29 @@ int scoutfs_lock_xattr_index(struct super_block *sb, int mode, int flags,
|
||||
}
|
||||
|
||||
/*
|
||||
* The node_id lock protects a mount's private persistent items in the
|
||||
* node_id zone. It's held for the duration of the mount. It lets the
|
||||
* mount modify the node_id items at will and signals to other mounts
|
||||
* that we're still alive and our node_id items shouldn't be reclaimed.
|
||||
* The rid lock protects a mount's private persistent items in the rid
|
||||
* zone. It's held for the duration of the mount. It lets the mount
|
||||
* modify the rid items at will and signals to other mounts that we're
|
||||
* still alive and our rid items shouldn't be reclaimed.
|
||||
*
|
||||
* Being held for the entire mount prevents other nodes from reclaiming
|
||||
* our items, like free blocks, when it would make sense for them to be
|
||||
* able to. Maybe we have a bunch free and they're trying to allocate
|
||||
* and are getting ENOSPC.
|
||||
*/
|
||||
int scoutfs_lock_node_id(struct super_block *sb, int mode, int flags,
|
||||
u64 node_id, struct scoutfs_lock **lock)
|
||||
int scoutfs_lock_rid(struct super_block *sb, int mode, int flags,
|
||||
u64 rid, struct scoutfs_lock **lock)
|
||||
{
|
||||
struct scoutfs_key start;
|
||||
struct scoutfs_key end;
|
||||
|
||||
scoutfs_key_set_zeros(&start);
|
||||
start.sk_zone = SCOUTFS_NODE_ZONE;
|
||||
start.sko_node_id = cpu_to_le64(node_id);
|
||||
start.sk_zone = SCOUTFS_RID_ZONE;
|
||||
start.sko_rid = cpu_to_le64(rid);
|
||||
|
||||
scoutfs_key_set_ones(&end);
|
||||
end.sk_zone = SCOUTFS_NODE_ZONE;
|
||||
end.sko_node_id = cpu_to_le64(node_id);
|
||||
end.sk_zone = SCOUTFS_RID_ZONE;
|
||||
end.sko_rid = cpu_to_le64(rid);
|
||||
|
||||
return lock_key_range(sb, mode, flags, &start, &end, lock);
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ int scoutfs_lock_inodes(struct super_block *sb, int mode, int flags,
|
||||
struct inode *d, struct scoutfs_lock **D_lock);
|
||||
int scoutfs_lock_rename(struct super_block *sb, int mode, int flags,
|
||||
struct scoutfs_lock **lock);
|
||||
int scoutfs_lock_node_id(struct super_block *sb, int mode, int flags,
|
||||
u64 node_id, struct scoutfs_lock **lock);
|
||||
int scoutfs_lock_rid(struct super_block *sb, int mode, int flags,
|
||||
u64 rid, struct scoutfs_lock **lock);
|
||||
void scoutfs_unlock(struct super_block *sb, struct scoutfs_lock *lock,
|
||||
int level);
|
||||
|
||||
|
||||
@@ -182,8 +182,8 @@ static void scoutfs_put_super(struct super_block *sb)
|
||||
|
||||
scoutfs_data_destroy(sb);
|
||||
|
||||
scoutfs_unlock(sb, sbi->node_id_lock, SCOUTFS_LOCK_WRITE);
|
||||
sbi->node_id_lock = NULL;
|
||||
scoutfs_unlock(sb, sbi->rid_lock, SCOUTFS_LOCK_WRITE);
|
||||
sbi->rid_lock = NULL;
|
||||
|
||||
scoutfs_shutdown_trans(sb);
|
||||
scoutfs_client_destroy(sb);
|
||||
@@ -429,8 +429,8 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
scoutfs_server_setup(sb) ?:
|
||||
scoutfs_client_setup(sb) ?:
|
||||
scoutfs_client_wait_node_id(sb) ?:
|
||||
scoutfs_lock_node_id(sb, SCOUTFS_LOCK_WRITE, 0, sbi->node_id,
|
||||
&sbi->node_id_lock);
|
||||
scoutfs_lock_rid(sb, SCOUTFS_LOCK_WRITE, 0, sbi->rid,
|
||||
&sbi->rid_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ struct scoutfs_sb_info {
|
||||
/* assigned once at the start of each mount, read-only */
|
||||
u64 rid;
|
||||
u64 node_id;
|
||||
struct scoutfs_lock *node_id_lock;
|
||||
struct scoutfs_lock *rid_lock;
|
||||
|
||||
struct scoutfs_super_block super;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user