scoutfs: sort keys by zone, then inode, then type

Holding a DLM lock protects a range of the key space.  The DLM locks
span inodes or regions of inodes.  We need the sort order in LSM items
to match the DLM range keys so that we can read all the items covered by
a lock into the cache from a region of LSM segments.  If their orders
differered then we'd have to jump around segments to find all the items
covered by a given DLM lock.

Previously we were sorting by type then, within types, by inode.  Now we
want to sort by inode then by type.  But there are structures which
previously had a type but weren't then sorted by inode.  We introduce
zones as the primary sort key.  Inode index and node zones are sorted by
the inode fields and node ids respectively.  Then comes the fs zone
first sorted by inode then the type of the key.

The bulk of this is the mechanical introduction of the zone field to the
keys, moving the type field down, and a bulk rename of _KEY to _TYPE.
But there are some more substantial changes.

The orphan keys needed to be put in a zone.   They fit in the NODE zone
which is all about resources that nodes hold and would need to be
cleaned up if the node went away.

The key formatting is significantly changed to match the new formatting.
Formatted keys are now generally of the form "zone.primary.type..."

And finally with the keys now properly sorted by inodes we can correctly
construct a single range of item cache keys to invalidate when unlocking
the inode group locks.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-07-12 11:50:32 -07:00
parent 690049c293
commit 8d29c82306
10 changed files with 224 additions and 164 deletions

View File

@@ -139,8 +139,9 @@ static void init_file_extent_key(struct scoutfs_key_buf *key, void *key_bytes,
{
struct scoutfs_file_extent_key *fkey = key_bytes;
fkey->type = SCOUTFS_FILE_EXTENT_KEY;
fkey->zone = SCOUTFS_FS_ZONE;
fkey->ino = cpu_to_be64(arg);
fkey->type = SCOUTFS_FILE_EXTENT_TYPE;
fkey->last_blk_off = cpu_to_be64(ext->blk_off + ext->blocks - 1);
fkey->last_blkno = cpu_to_be64(ext->blkno + ext->blocks - 1);
fkey->blocks = cpu_to_be64(ext->blocks);
@@ -153,8 +154,9 @@ static void init_file_extent_key(struct scoutfs_key_buf *key, void *key_bytes,
do { \
struct which_type *fkey = key_bytes; \
\
fkey->type = type; \
fkey->zone = SCOUTFS_NODE_ZONE; \
fkey->node_id = cpu_to_be64(arg); \
fkey->type = type; \
fkey->last_blkno = cpu_to_be64(ext->blkno + ext->blocks - 1); \
fkey->blocks = cpu_to_be64(ext->blocks); \
\
@@ -164,9 +166,9 @@ do { \
static void init_extent_key(struct scoutfs_key_buf *key, void *key_bytes,
struct native_extent *ext, u64 arg, u8 type)
{
if (type == SCOUTFS_FILE_EXTENT_KEY)
if (type == SCOUTFS_FILE_EXTENT_TYPE)
init_file_extent_key(key, key_bytes, ext, arg);
else if(type == SCOUTFS_FREE_EXTENT_BLKNO_KEY)
else if(type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE)
INIT_FREE_EXTENT_KEY(scoutfs_free_extent_blkno_key,
key, key_bytes, ext, arg, type);
else
@@ -206,9 +208,9 @@ static void load_extent(struct native_extent *ext, struct scoutfs_key_buf *key)
offsetof(struct scoutfs_file_extent_key, type) !=
offsetof(struct scoutfs_free_extent_blocks_key, type));
if (fkey->type == SCOUTFS_FILE_EXTENT_KEY)
if (fkey->type == SCOUTFS_FILE_EXTENT_TYPE)
load_file_extent(ext, key);
else if (fkey->type == SCOUTFS_FREE_EXTENT_BLKNO_KEY)
else if (fkey->type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE)
LOAD_FREE_EXTENT(scoutfs_free_extent_blkno_key, ext, key);
else
LOAD_FREE_EXTENT(scoutfs_free_extent_blocks_key, ext, key);
@@ -344,16 +346,16 @@ static int modify_items(struct super_block *sb, struct native_extent *ext,
trace_printk("mod cre %u "EXTF"\n", create, EXTA(ext));
BUG_ON(type != SCOUTFS_FILE_EXTENT_KEY &&
type != SCOUTFS_FREE_EXTENT_BLKNO_KEY);
BUG_ON(type != SCOUTFS_FILE_EXTENT_TYPE &&
type != SCOUTFS_FREE_EXTENT_BLKNO_TYPE);
init_extent_key(&key, key_bytes, ext, arg, type);
ret = create ? scoutfs_item_create(sb, &key, NULL) :
scoutfs_item_delete(sb, &key);
if (ret == 0 && type == SCOUTFS_FREE_EXTENT_BLKNO_KEY) {
if (ret == 0 && type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE) {
init_extent_key(&key, key_bytes, ext, arg,
SCOUTFS_FREE_EXTENT_BLOCKS_KEY);
SCOUTFS_FREE_EXTENT_BLOCKS_TYPE);
ret = create ? scoutfs_item_create(sb, &key, NULL) :
scoutfs_item_delete(sb, &key);
if (ret) {
@@ -538,7 +540,7 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock,
iblock, len, offline);
memset(&ext, ~0, sizeof(ext));
init_extent_key(&last, last_bytes, &ext, ino, SCOUTFS_FILE_EXTENT_KEY);
init_extent_key(&last, last_bytes, &ext, ino, SCOUTFS_FILE_EXTENT_TYPE);
rng.blk_off = iblock;
rng.blocks = len;
@@ -548,7 +550,7 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock,
while (rng.blocks) {
/* find the next extent that could include our first block */
init_extent_key(&key, key_bytes, &rng, ino,
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
ret = scoutfs_item_next_same(sb, &key, &last, NULL);
if (ret < 0) {
@@ -602,14 +604,14 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock,
fr = ext;
fr.blk_off = fr.blkno;
ret = insert_extent(sb, &fr, sbi->node_id,
SCOUTFS_FREE_EXTENT_BLKNO_KEY);
SCOUTFS_FREE_EXTENT_BLKNO_TYPE);
if (ret)
break;
rem_fr = true;
}
/* always remove the overlapping file extent */
ret = remove_extent(sb, &ext, ino, SCOUTFS_FILE_EXTENT_KEY);
ret = remove_extent(sb, &ext, ino, SCOUTFS_FILE_EXTENT_TYPE);
if (ret)
break;
ins_ext = true;
@@ -620,7 +622,7 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock,
ofl.blkno = 0;
ofl.flags = SCOUTFS_FILE_EXTENT_OFFLINE;
ret = insert_extent(sb, &ofl, sbi->node_id,
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
if (ret)
break;
}
@@ -637,12 +639,12 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock,
if (ret) {
if (ins_ext) {
err = insert_extent(sb, &ext, ino,
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
BUG_ON(err);
}
if (rem_fr) {
err = remove_extent(sb, &fr, sbi->node_id,
SCOUTFS_FREE_EXTENT_BLKNO_KEY);
SCOUTFS_FREE_EXTENT_BLKNO_TYPE);
BUG_ON(err);
}
}
@@ -720,7 +722,7 @@ static int bulk_alloc(struct super_block *sb)
ext.blk_off = ext.blkno;
ext.flags = 0;
ret = insert_extent(sb, &ext, sbi->node_id,
SCOUTFS_FREE_EXTENT_BLKNO_KEY);
SCOUTFS_FREE_EXTENT_BLKNO_TYPE);
if (ret)
break;
}
@@ -778,11 +780,11 @@ reset_cursor:
if (curs->blocks) {
ext.blkno = curs->blkno;
ext.blocks = 0;
type = SCOUTFS_FREE_EXTENT_BLKNO_KEY;
type = SCOUTFS_FREE_EXTENT_BLKNO_TYPE;
} else {
ext.blkno = datinf->next_large_blkno;
ext.blocks = LARGE_EXTENT_BLOCKS;
type = SCOUTFS_FREE_EXTENT_BLOCKS_KEY;
type = SCOUTFS_FREE_EXTENT_BLOCKS_TYPE;
}
ext.flags = 0;
@@ -825,7 +827,7 @@ retry:
if (ext.blocks) {
ext.blkno = 0;
ext.blocks = 0;
type = SCOUTFS_FREE_EXTENT_BLKNO_KEY;
type = SCOUTFS_FREE_EXTENT_BLKNO_TYPE;
goto retry;
}
@@ -876,7 +878,7 @@ retry:
ofl.blkno = 0;
ofl.blocks = 1;
ofl.flags = SCOUTFS_FILE_EXTENT_OFFLINE;
ret = remove_extent(sb, &ofl, ino, SCOUTFS_FILE_EXTENT_KEY);
ret = remove_extent(sb, &ofl, ino, SCOUTFS_FILE_EXTENT_TYPE);
if (ret < 0)
goto out;
ins_ofl = true;
@@ -888,7 +890,7 @@ retry:
ext.blkno = found.blkno;
ext.blocks = 1;
ext.flags = 0;
ret = insert_extent(sb, &ext, ino, SCOUTFS_FILE_EXTENT_KEY);
ret = insert_extent(sb, &ext, ino, SCOUTFS_FILE_EXTENT_TYPE);
if (ret < 0)
goto out;
rem_ext = true;
@@ -897,7 +899,7 @@ retry:
fr = ext;
fr.blk_off = ext.blkno;
ret = remove_extent(sb, &fr, sbi->node_id,
SCOUTFS_FREE_EXTENT_BLKNO_KEY);
SCOUTFS_FREE_EXTENT_BLKNO_TYPE);
if (ret)
goto out;
@@ -914,12 +916,12 @@ out:
if (ret) {
if (rem_ext) {
err = remove_extent(sb, &ext, ino,
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
BUG_ON(err);
}
if (ins_ofl) {
err = insert_extent(sb, &ofl, ino,
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
BUG_ON(err);
}
}
@@ -953,11 +955,11 @@ static int scoutfs_get_block(struct inode *inode, sector_t iblock,
ext.blkno = 0;
ext.flags = 0;
init_extent_key(&key, key_bytes, &ext, scoutfs_ino(inode),
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
memset(&ext, ~0, sizeof(ext));
init_extent_key(&last, last_bytes, &ext, scoutfs_ino(inode),
SCOUTFS_FILE_EXTENT_KEY);
SCOUTFS_FILE_EXTENT_TYPE);
/*
* XXX think about how far this next can go, given locking and
@@ -1107,7 +1109,7 @@ int scoutfs_data_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
struct super_block *sb = inode->i_sb;
const u8 type = SCOUTFS_FILE_EXTENT_KEY;
const u8 type = SCOUTFS_FILE_EXTENT_TYPE;
const u64 ino = scoutfs_ino(inode);
u8 last_bytes[MAX_KEY_BYTES];
u8 key_bytes[MAX_KEY_BYTES];

View File

@@ -178,8 +178,9 @@ static struct scoutfs_key_buf *alloc_dirent_key(struct super_block *sb,
name[dentry->d_name.len]));
if (key) {
dkey = key->data;
dkey->type = SCOUTFS_DIRENT_KEY;
dkey->zone = SCOUTFS_FS_ZONE;
dkey->ino = cpu_to_be64(scoutfs_ino(dir));
dkey->type = SCOUTFS_DIRENT_TYPE;
memcpy(dkey->name, (void *)dentry->d_name.name,
dentry->d_name.len);
}
@@ -192,8 +193,9 @@ static void init_link_backref_key(struct scoutfs_key_buf *key,
u64 ino, u64 dir_ino,
char *name, unsigned name_len)
{
lbrkey->type = SCOUTFS_LINK_BACKREF_KEY;
lbrkey->zone = SCOUTFS_FS_ZONE;
lbrkey->ino = cpu_to_be64(ino);
lbrkey->type = SCOUTFS_LINK_BACKREF_TYPE;
lbrkey->dir_ino = cpu_to_be64(dir_ino);
if (name_len)
memcpy(lbrkey->name, name, name_len);
@@ -297,8 +299,9 @@ static void init_readdir_key(struct scoutfs_key_buf *key,
struct scoutfs_readdir_key *rkey,
struct inode *inode, loff_t pos)
{
rkey->type = SCOUTFS_READDIR_KEY;
rkey->zone = SCOUTFS_FS_ZONE;
rkey->ino = cpu_to_be64(scoutfs_ino(inode));
rkey->type = SCOUTFS_READDIR_TYPE;
rkey->pos = cpu_to_be64(pos);
scoutfs_key_init(key, rkey, sizeof(struct scoutfs_readdir_key));
@@ -636,8 +639,9 @@ out:
static void init_symlink_key(struct scoutfs_key_buf *key,
struct scoutfs_symlink_key *skey, u64 ino, u8 nr)
{
skey->type = SCOUTFS_SYMLINK_KEY;
skey->zone = SCOUTFS_FS_ZONE;
skey->ino = cpu_to_be64(ino);
skey->type = SCOUTFS_SYMLINK_TYPE;
skey->nr = nr;
scoutfs_key_init(key, skey, sizeof(struct scoutfs_symlink_key));

View File

@@ -236,73 +236,78 @@ struct scoutfs_segment_block {
} __packed;
/*
* Currently we sort keys by the numeric value of the types, but that
* isn't necessary. We could have an arbitrary sort order. So we don't
* have to stress about cleverly allocating the types.
* Keys are first sorted by major key zones.
*/
#define SCOUTFS_INODE_KEY 1
#define SCOUTFS_XATTR_KEY 3
#define SCOUTFS_DIRENT_KEY 5
#define SCOUTFS_READDIR_KEY 6
#define SCOUTFS_LINK_BACKREF_KEY 7
#define SCOUTFS_SYMLINK_KEY 8
#define SCOUTFS_FILE_EXTENT_KEY 9
#define SCOUTFS_ORPHAN_KEY 10
#define SCOUTFS_FREE_EXTENT_BLKNO_KEY 11
#define SCOUTFS_FREE_EXTENT_BLOCKS_KEY 12
#define SCOUTFS_INODE_INDEX_CTIME_KEY 13 /* don't forget first and last */
#define SCOUTFS_INODE_INDEX_MTIME_KEY 14
#define SCOUTFS_INODE_INDEX_SIZE_KEY 15
#define SCOUTFS_INODE_INDEX_META_SEQ_KEY 16
#define SCOUTFS_INODE_INDEX_DATA_SEQ_KEY 17
/* not found in the fs */
#define SCOUTFS_MAX_UNUSED_KEY 253
#define SCOUTFS_NET_ADDR_KEY 254
#define SCOUTFS_NET_LISTEN_KEY 255
#define SCOUTFS_INODE_INDEX_ZONE 1
#define SCOUTFS_NODE_ZONE 2
#define SCOUTFS_FS_ZONE 3
/* inode index zone */
#define SCOUTFS_INODE_INDEX_CTIME_TYPE 1
#define SCOUTFS_INODE_INDEX_MTIME_TYPE 2
#define SCOUTFS_INODE_INDEX_SIZE_TYPE 3
#define SCOUTFS_INODE_INDEX_META_SEQ_TYPE 4
#define SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE 5
#define SCOUTFS_INODE_INDEX_FIRST SCOUTFS_INODE_INDEX_CTIME_KEY
#define SCOUTFS_INODE_INDEX_LAST SCOUTFS_INODE_INDEX_DATA_SEQ_KEY
#define SCOUTFS_INODE_INDEX_NR \
(SCOUTFS_INODE_INDEX_LAST - SCOUTFS_INODE_INDEX_FIRST + 1)
(SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE - SCOUTFS_INODE_INDEX_CTIME_TYPE + 1)
/* node zone */
#define SCOUTFS_FREE_EXTENT_BLKNO_TYPE 11
#define SCOUTFS_FREE_EXTENT_BLOCKS_TYPE 12
/* fs zone */
#define SCOUTFS_INODE_TYPE 1
#define SCOUTFS_XATTR_TYPE 2
#define SCOUTFS_DIRENT_TYPE 3
#define SCOUTFS_READDIR_TYPE 4
#define SCOUTFS_LINK_BACKREF_TYPE 5
#define SCOUTFS_SYMLINK_TYPE 6
#define SCOUTFS_FILE_EXTENT_TYPE 7
#define SCOUTFS_ORPHAN_TYPE 8
/* XXX don't need these now that we have dlm lock spaces and resources */
#define SCOUTFS_NET_ADDR_TYPE 254
#define SCOUTFS_NET_LISTEN_TYPE 255
/* value is struct scoutfs_inode */
struct scoutfs_inode_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
} __packed;
/* value is struct scoutfs_dirent without the name */
struct scoutfs_dirent_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
__u8 name[0];
} __packed;
/* value is struct scoutfs_dirent with the name */
struct scoutfs_readdir_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
__be64 pos;
} __packed;
/* value is empty */
struct scoutfs_link_backref_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
__be64 dir_ino;
__u8 name[0];
} __packed;
/* no value */
struct scoutfs_orphan_key {
__u8 type;
__be64 ino;
} __packed;
/* no value */
struct scoutfs_file_extent_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
__be64 last_blk_off;
__be64 last_blkno;
__be64 blocks;
@@ -313,23 +318,34 @@ struct scoutfs_file_extent_key {
/* no value */
struct scoutfs_free_extent_blkno_key {
__u8 type;
__u8 zone;
__be64 node_id;
__u8 type;
__be64 last_blkno;
__be64 blocks;
} __packed;
struct scoutfs_free_extent_blocks_key {
__u8 type;
__u8 zone;
__be64 node_id;
__u8 type;
__be64 blocks;
__be64 last_blkno;
} __packed;
/* value is each item's part of the full xattr value for the off/len */
struct scoutfs_xattr_key {
/* no value */
struct scoutfs_orphan_key {
__u8 zone;
__be64 node_id;
__u8 type;
__be64 ino;
} __packed;
/* value is each item's part of the full xattr value for the off/len */
struct scoutfs_xattr_key {
__u8 zone;
__be64 ino;
__u8 type;
__u8 name[0];
} __packed;
@@ -345,8 +361,9 @@ struct scoutfs_xattr_val_header {
/* size determines nr needed to store full target path in their values */
struct scoutfs_symlink_key {
__u8 type;
__u8 zone;
__be64 ino;
__u8 type;
__u8 nr;
} __packed;
@@ -356,6 +373,7 @@ struct scoutfs_betimespec {
} __packed;
struct scoutfs_inode_index_key {
__u8 zone;
__u8 type;
__be64 major;
__be32 minor;

View File

@@ -224,8 +224,9 @@ static void load_inode(struct inode *inode, struct scoutfs_inode *cinode)
void scoutfs_inode_init_key(struct scoutfs_key_buf *key,
struct scoutfs_inode_key *ikey, u64 ino)
{
ikey->type = SCOUTFS_INODE_KEY;
ikey->zone = SCOUTFS_FS_ZONE;
ikey->ino = cpu_to_be64(ino);
ikey->type = SCOUTFS_INODE_TYPE;
scoutfs_key_init(key, ikey, sizeof(struct scoutfs_inode_key));
}
@@ -479,6 +480,7 @@ static int update_index(struct inode *inode, u8 type, u64 now_major,
if (si->have_item && now_major == then_major && now_minor == then_minor)
return 0;
ins_ikey.zone = SCOUTFS_INODE_INDEX_ZONE;
ins_ikey.type = type;
ins_ikey.major = cpu_to_be64(now_major);
ins_ikey.minor = cpu_to_be32(now_minor);
@@ -489,6 +491,7 @@ static int update_index(struct inode *inode, u8 type, u64 now_major,
if (ret || !si->have_item)
return ret;
del_ikey.zone = SCOUTFS_INODE_INDEX_ZONE;
del_ikey.type = type;
del_ikey.major = cpu_to_be64(then_major);
del_ikey.minor = cpu_to_be32(then_minor);
@@ -527,18 +530,18 @@ void scoutfs_update_inode_item(struct inode *inode)
/* set the meta version once per trans for any inode updates */
scoutfs_inode_set_meta_seq(inode);
ret = update_index(inode, SCOUTFS_INODE_INDEX_CTIME_KEY,
ret = update_index(inode, SCOUTFS_INODE_INDEX_CTIME_TYPE,
inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
si->item_ctime.tv_sec, si->item_ctime.tv_nsec) ?:
update_index(inode, SCOUTFS_INODE_INDEX_MTIME_KEY,
update_index(inode, SCOUTFS_INODE_INDEX_MTIME_TYPE,
inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
si->item_mtime.tv_sec, si->item_mtime.tv_nsec) ?:
update_index(inode, SCOUTFS_INODE_INDEX_SIZE_KEY,
update_index(inode, SCOUTFS_INODE_INDEX_SIZE_TYPE,
i_size_read(inode), 0, si->item_size, 0) ?:
update_index(inode, SCOUTFS_INODE_INDEX_META_SEQ_KEY,
update_index(inode, SCOUTFS_INODE_INDEX_META_SEQ_TYPE,
scoutfs_inode_meta_seq(inode), 0,
si->item_meta_seq, 0) ?:
update_index(inode, SCOUTFS_INODE_INDEX_DATA_SEQ_KEY,
update_index(inode, SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE,
scoutfs_inode_data_seq(inode), 0,
si->item_data_seq, 0);
BUG_ON(ret);
@@ -753,9 +756,11 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
}
static void init_orphan_key(struct scoutfs_key_buf *key,
struct scoutfs_orphan_key *okey, u64 ino)
struct scoutfs_orphan_key *okey, u64 node_id, u64 ino)
{
okey->type = SCOUTFS_ORPHAN_KEY;
okey->zone = SCOUTFS_NODE_ZONE;
okey->node_id = cpu_to_be64(node_id);
okey->type = SCOUTFS_ORPHAN_TYPE;
okey->ino = cpu_to_be64(ino);
scoutfs_key_init(key, okey, sizeof(struct scoutfs_orphan_key));
@@ -763,11 +768,12 @@ static void init_orphan_key(struct scoutfs_key_buf *key,
static int remove_orphan_item(struct super_block *sb, u64 ino)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_orphan_key okey;
struct scoutfs_key_buf key;
int ret;
init_orphan_key(&key, &okey, ino);
init_orphan_key(&key, &okey, sbi->node_id, ino);
ret = scoutfs_item_delete(sb, &key);
if (ret == -ENOENT)
@@ -907,9 +913,13 @@ static int process_orphaned_inode(struct super_block *sb, u64 ino)
* Runtime of this will be bounded by the number of orphans, which could
* theoretically be very large. If that becomes a problem we might want to push
* this work off to a thread.
*
* This only scans orphans for this node. This will need to be covered by
* the rest of node zone cleanup.
*/
int scoutfs_scan_orphans(struct super_block *sb)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_orphan_key okey;
struct scoutfs_orphan_key last_okey;
struct scoutfs_key_buf key;
@@ -919,8 +929,8 @@ int scoutfs_scan_orphans(struct super_block *sb)
trace_scoutfs_scan_orphans(sb);
init_orphan_key(&key, &okey, 0);
init_orphan_key(&last, &last_okey, ~0ULL);
init_orphan_key(&key, &okey, sbi->node_id, 0);
init_orphan_key(&last, &last_okey, sbi->node_id, ~0ULL);
while (1) {
ret = scoutfs_item_next_same(sb, &key, &last, NULL);
@@ -944,13 +954,14 @@ out:
int scoutfs_orphan_inode(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_orphan_key okey;
struct scoutfs_key_buf key;
int ret;
trace_scoutfs_orphan_inode(sb, inode);
init_orphan_key(&key, &okey, scoutfs_ino(inode));
init_orphan_key(&key, &okey, sbi->node_id, scoutfs_ino(inode));
ret = scoutfs_item_create(sb, &key, NULL);

View File

@@ -47,6 +47,7 @@ static long scoutfs_ioc_walk_inodes(struct file *file, unsigned long arg)
struct scoutfs_key_buf key;
u64 last_seq;
int ret = 0;
u8 type;
u32 nr;
if (copy_from_user(&walk, uwalk, sizeof(walk)))
@@ -58,21 +59,21 @@ static long scoutfs_ioc_walk_inodes(struct file *file, unsigned long arg)
walk.last.ino);
if (walk.index == SCOUTFS_IOC_WALK_INODES_CTIME)
ikey.type = SCOUTFS_INODE_INDEX_CTIME_KEY;
type = SCOUTFS_INODE_INDEX_CTIME_TYPE;
else if (walk.index == SCOUTFS_IOC_WALK_INODES_MTIME)
ikey.type = SCOUTFS_INODE_INDEX_MTIME_KEY;
type = SCOUTFS_INODE_INDEX_MTIME_TYPE;
else if (walk.index == SCOUTFS_IOC_WALK_INODES_SIZE)
ikey.type = SCOUTFS_INODE_INDEX_SIZE_KEY;
type = SCOUTFS_INODE_INDEX_SIZE_TYPE;
else if (walk.index == SCOUTFS_IOC_WALK_INODES_META_SEQ)
ikey.type = SCOUTFS_INODE_INDEX_META_SEQ_KEY;
type = SCOUTFS_INODE_INDEX_META_SEQ_TYPE;
else if (walk.index == SCOUTFS_IOC_WALK_INODES_DATA_SEQ)
ikey.type = SCOUTFS_INODE_INDEX_DATA_SEQ_KEY;
type = SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE;
else
return -EINVAL;
/* clamp results to the inodes in the farthest stable seq */
if (ikey.type == SCOUTFS_INODE_INDEX_META_SEQ_KEY ||
ikey.type == SCOUTFS_INODE_INDEX_DATA_SEQ_KEY) {
if (type == SCOUTFS_INODE_INDEX_META_SEQ_TYPE ||
type == SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE) {
ret = scoutfs_net_get_last_seq(sb, &last_seq);
if (ret)
@@ -85,11 +86,14 @@ static long scoutfs_ioc_walk_inodes(struct file *file, unsigned long arg)
}
}
ikey.zone = SCOUTFS_INODE_INDEX_ZONE;
ikey.type = type;
ikey.major = cpu_to_be64(walk.first.major);
ikey.minor = cpu_to_be32(walk.first.minor);
ikey.ino = cpu_to_be64(walk.first.ino);
scoutfs_key_init(&key, &ikey, sizeof(ikey));
last_ikey.zone = ikey.zone;
last_ikey.type = ikey.type;
last_ikey.major = cpu_to_be64(walk.last.major);
last_ikey.minor = cpu_to_be32(walk.last.minor);

View File

@@ -118,8 +118,10 @@ void scoutfs_key_dec(struct scoutfs_key_buf *key)
*/
int scoutfs_key_str_size(char *buf, struct scoutfs_key_buf *key, size_t size)
{
struct scoutfs_inode_key *ikey;
u8 zone = 0;
u8 type = 0;
int len;
u8 type;
if (key == NULL || key->data == NULL)
return snprintf_null(buf, size, "[NULL]");
@@ -127,21 +129,88 @@ int scoutfs_key_str_size(char *buf, struct scoutfs_key_buf *key, size_t size)
if (key->key_len == 0)
return snprintf_null(buf, size, "[0 len]");
type = *(u8 *)key->data;
zone = *(u8 *)key->data;
switch(type) {
/* handle smaller and unknown zones, fall through to fs types */
switch(zone) {
case SCOUTFS_INODE_INDEX_ZONE: {
struct scoutfs_inode_index_key *ikey = key->data;
static char *type_strings[] = {
[SCOUTFS_INODE_INDEX_CTIME_TYPE] = "ctm",
[SCOUTFS_INODE_INDEX_MTIME_TYPE] = "mtm",
[SCOUTFS_INODE_INDEX_SIZE_TYPE] = "siz",
[SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = "msq",
[SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = "dsq",
};
case SCOUTFS_INODE_KEY: {
if (key->key_len < sizeof(struct scoutfs_inode_index_key))
break;
if (type_strings[ikey->type])
return snprintf_null(buf, size, "iin.%s.%llu.%u.%llu",
type_strings[ikey->type],
be64_to_cpu(ikey->major),
be32_to_cpu(ikey->minor),
be64_to_cpu(ikey->ino));
else
return snprintf_null(buf, size, "[iin type %u?]",
ikey->type);
}
/* node zone keys start with zone, node, type */
case SCOUTFS_NODE_ZONE: {
struct scoutfs_free_extent_blkno_key *fkey = key->data;
static char *type_strings[] = {
[SCOUTFS_FREE_EXTENT_BLKNO_TYPE] = "fno",
[SCOUTFS_FREE_EXTENT_BLOCKS_TYPE] = "fks",
};
switch(fkey->type) {
case SCOUTFS_ORPHAN_TYPE: {
struct scoutfs_orphan_key *okey = key->data;
if (key->key_len < sizeof(struct scoutfs_orphan_key))
break;
return snprintf_null(buf, size, "nod.%llu.orp.%llu",
be64_to_cpu(okey->node_id),
be64_to_cpu(okey->ino));
}
case SCOUTFS_FREE_EXTENT_BLKNO_TYPE:
case SCOUTFS_FREE_EXTENT_BLOCKS_TYPE:
return snprintf_null(buf, size, "nod.%llu.%s.%llu.%llu",
be64_to_cpu(fkey->node_id),
type_strings[fkey->type],
be64_to_cpu(fkey->last_blkno),
be64_to_cpu(fkey->blocks));
default:
return snprintf_null(buf, size, "[nod type %u?]",
fkey->type);
}
}
case SCOUTFS_FS_ZONE:
break;
default:
return snprintf_null(buf, size, "[zone %u?]", zone);
}
/* everything in the fs tree starts with zone, ino, type */
ikey = key->data;
switch(ikey->type) {
case SCOUTFS_INODE_TYPE: {
struct scoutfs_inode_key *ikey = key->data;
if (key->key_len < sizeof(struct scoutfs_inode_key))
break;
return snprintf_null(buf, size, "ino.%llu",
return snprintf_null(buf, size, "fs.%llu.ino",
be64_to_cpu(ikey->ino));
}
case SCOUTFS_XATTR_KEY: {
case SCOUTFS_XATTR_TYPE: {
struct scoutfs_xattr_key *xkey = key->data;
len = (int)key->key_len - offsetof(struct scoutfs_xattr_key,
@@ -149,53 +218,53 @@ int scoutfs_key_str_size(char *buf, struct scoutfs_key_buf *key, size_t size)
if (len <= 0)
break;
return snprintf_null(buf, size, "xat.%llu.%.*s",
return snprintf_null(buf, size, "fs.%llu.xat.%.*s",
be64_to_cpu(xkey->ino), len, xkey->name);
}
case SCOUTFS_DIRENT_KEY: {
case SCOUTFS_DIRENT_TYPE: {
struct scoutfs_dirent_key *dkey = key->data;
len = (int)key->key_len - sizeof(struct scoutfs_dirent_key);
if (len <= 0)
break;
return snprintf_null(buf, size, "dnt.%llu.%.*s",
return snprintf_null(buf, size, "fs.%llu.dnt.%.*s",
be64_to_cpu(dkey->ino), len, dkey->name);
}
case SCOUTFS_READDIR_KEY: {
case SCOUTFS_READDIR_TYPE: {
struct scoutfs_readdir_key *rkey = key->data;
return snprintf_null(buf, size, "rdr.%llu.%llu",
return snprintf_null(buf, size, "fs.%llu.rdr.%llu",
be64_to_cpu(rkey->ino),
be64_to_cpu(rkey->pos));
}
case SCOUTFS_LINK_BACKREF_KEY: {
case SCOUTFS_LINK_BACKREF_TYPE: {
struct scoutfs_link_backref_key *lkey = key->data;
len = (int)key->key_len - sizeof(*lkey);
if (len <= 0)
break;
return snprintf_null(buf, size, "lbr.%llu.%llu.%.*s",
return snprintf_null(buf, size, "fs.%llu.lbr.%llu.%.*s",
be64_to_cpu(lkey->ino),
be64_to_cpu(lkey->dir_ino), len,
lkey->name);
}
case SCOUTFS_SYMLINK_KEY: {
case SCOUTFS_SYMLINK_TYPE: {
struct scoutfs_symlink_key *skey = key->data;
return snprintf_null(buf, size, "sym.%llu",
return snprintf_null(buf, size, "fs.%llu.sym",
be64_to_cpu(skey->ino));
}
case SCOUTFS_FILE_EXTENT_KEY: {
case SCOUTFS_FILE_EXTENT_TYPE: {
struct scoutfs_file_extent_key *ekey = key->data;
return snprintf_null(buf, size, "ext.%llu.%llu.%llu.%llu.%x",
return snprintf_null(buf, size, "fs.%llu.ext.%llu.%llu.%llu.%x",
be64_to_cpu(ekey->ino),
be64_to_cpu(ekey->last_blk_off),
be64_to_cpu(ekey->last_blkno),
@@ -203,49 +272,11 @@ int scoutfs_key_str_size(char *buf, struct scoutfs_key_buf *key, size_t size)
ekey->flags);
}
case SCOUTFS_ORPHAN_KEY: {
struct scoutfs_orphan_key *okey = key->data;
return snprintf_null(buf, size, "orp.%llu",
be64_to_cpu(okey->ino));
}
case SCOUTFS_FREE_EXTENT_BLKNO_KEY:
case SCOUTFS_FREE_EXTENT_BLOCKS_KEY: {
struct scoutfs_free_extent_blkno_key *fkey = key->data;
return snprintf_null(buf, size, "%s.%llu.%llu.%llu",
fkey->type == SCOUTFS_FREE_EXTENT_BLKNO_KEY ? "fel" :
"fes",
be64_to_cpu(fkey->node_id),
be64_to_cpu(fkey->last_blkno),
be64_to_cpu(fkey->blocks));
}
case SCOUTFS_INODE_INDEX_CTIME_KEY:
case SCOUTFS_INODE_INDEX_MTIME_KEY:
case SCOUTFS_INODE_INDEX_SIZE_KEY:
case SCOUTFS_INODE_INDEX_META_SEQ_KEY:
case SCOUTFS_INODE_INDEX_DATA_SEQ_KEY: {
struct scoutfs_inode_index_key *ikey = key->data;
return snprintf_null(buf, size, "%s.%llu.%u.%llu",
ikey->type == SCOUTFS_INODE_INDEX_CTIME_KEY ? "ctm" :
ikey->type == SCOUTFS_INODE_INDEX_MTIME_KEY ? "mtm" :
ikey->type == SCOUTFS_INODE_INDEX_SIZE_KEY ? "siz" :
ikey->type == SCOUTFS_INODE_INDEX_META_SEQ_KEY ? "msq" :
ikey->type == SCOUTFS_INODE_INDEX_DATA_SEQ_KEY ? "dsq" :
"uii", be64_to_cpu(ikey->major),
be32_to_cpu(ikey->minor),
be64_to_cpu(ikey->ino));
}
default:
return snprintf_null(buf, size, "[unknown type %u len %u]",
type, key->key_len);
return snprintf_null(buf, size, "[fs type %u?]", type);
}
return snprintf_null(buf, size, "[truncated type %u len %u]",
return snprintf_null(buf, size, "[fs type %u trunc len %u]",
type, key->key_len);
}

View File

@@ -246,7 +246,7 @@ void scoutfs_kvec_set_max_key(struct kvec *kvec)
{
__u8 *type = kvec[0].iov_base;
*type = SCOUTFS_MAX_UNUSED_KEY;
*type = 255;
scoutfs_kvec_init(kvec, type, 1);
}

View File

@@ -165,9 +165,9 @@ struct sock_info {
* XXX instead of magic keys in the main fs resource we could have
* another resource that contains the server locks.
*/
static u8 listen_type = SCOUTFS_NET_LISTEN_KEY;
static u8 listen_type = SCOUTFS_NET_LISTEN_TYPE;
static struct scoutfs_key_buf listen_key;
static u8 addr_type = SCOUTFS_NET_ADDR_KEY;
static u8 addr_type = SCOUTFS_NET_ADDR_TYPE;
static struct scoutfs_key_buf addr_key;
static int send_msg(struct socket *sock, void *buf, unsigned len)

View File

@@ -33,17 +33,6 @@
struct scoutfs_sb_info;
#define show_key_type(type) \
__print_symbolic(type, \
{ SCOUTFS_INODE_KEY, "INODE" }, \
{ SCOUTFS_XATTR_KEY, "XATTR" }, \
{ SCOUTFS_DIRENT_KEY, "DIRENT" }, \
{ SCOUTFS_LINK_BACKREF_KEY, "LINK_BACKREF"}, \
{ SCOUTFS_SYMLINK_KEY, "SYMLINK" }, \
{ SCOUTFS_EXTENT_KEY, "EXTENT" })
#define TRACE_KEYF "%llu.%s.%llu"
TRACE_EVENT(scoutfs_write_begin,
TP_PROTO(u64 ino, loff_t pos, unsigned len),

View File

@@ -87,8 +87,9 @@ static struct scoutfs_key_buf *alloc_xattr_key(struct super_block *sb,
xkey = key->data;
foot = xattr_key_footer(key);
xkey->type = SCOUTFS_XATTR_KEY;
xkey->zone = SCOUTFS_FS_ZONE;
xkey->ino = cpu_to_be64(ino);
xkey->type = SCOUTFS_XATTR_TYPE;
if (name && name_len)
memcpy(xkey->name, name, name_len);