Files
scoutfs/kmod/src/super.h
T
Zach Brown f57c07381a Go back to having our own scoutfs_block cache
We used to have 16k blocks in our own radix_tree cache.  When we
introduced the simple file block mapping code it preferred to have block
size == page size.  That let us remove a bunch of code and reuse all the
kernel's buffer head code.

But it turns out that the buffer heads are just a bit too inflexible.

We'd like to have blocks larger than page size, obviously, but it turns
out there's real functional differences.

Resolving the problem of unlocked readers and allocating writers working
with the same blkno is the most powerful example of this.  It's trivial
to fix by always inserting new allocated cached blocks in the cache. But
solving it with buffer heads requires expensive and risky locking around
the buffer head cache which can only support a single physical instance
of a given blkno because there can be multiple blocks per page.

So this restores the simple block cache that was removed back in commit
'c8e76e2 scoutfs: use buffer heads'.  There's still work to do to get
this fully functional but it's worth it.

Signed-off-by: Zach Brown <zab@versity.com>
Reviewed-by: Mark Fasheh <mfasheh@versity.com>
2016-11-16 14:45:07 -08:00

72 lines
1.5 KiB
C

#ifndef _SCOUTFS_SUPER_H_
#define _SCOUTFS_SUPER_H_
#include <linux/fs.h>
#include <linux/rbtree.h>
#include "format.h"
#include "buddy.h"
struct scoutfs_counters;
struct buddy_info;
struct scoutfs_sb_info {
struct super_block *sb;
struct scoutfs_super_block super;
struct scoutfs_super_block stable_super;
spinlock_t next_ino_lock;
spinlock_t block_lock;
struct radix_tree_root block_radix;
wait_queue_head_t block_wq;
atomic_t block_writes;
int block_write_err;
struct buddy_info *buddy_info;
struct rw_semaphore btree_rwsem;
atomic_t trans_holds;
wait_queue_head_t trans_hold_wq;
spinlock_t trans_write_lock;
u64 trans_write_count;
int trans_write_ret;
struct work_struct trans_write_work;
wait_queue_head_t trans_write_wq;
struct workqueue_struct *trans_write_workq;
/* $sysfs/fs/scoutfs/$id/ */
struct kset *kset;
struct scoutfs_counters *counters;
/* XXX we'd like this to be per task, not per super */
spinlock_t file_alloc_lock;
u64 file_alloc_blkno;
u64 file_alloc_count;
};
static inline struct scoutfs_sb_info *SCOUTFS_SB(struct super_block *sb)
{
return sb->s_fs_info;
}
/* The root of the metadata btree */
static inline struct scoutfs_btree_root *SCOUTFS_META(struct super_block *sb)
{
return &SCOUTFS_SB(sb)->super.btree_root;
}
static inline struct scoutfs_btree_root *SCOUTFS_STABLE_META(struct super_block *sb)
{
return &SCOUTFS_SB(sb)->stable_super.btree_root;
}
void scoutfs_advance_dirty_super(struct super_block *sb);
int scoutfs_write_dirty_super(struct super_block *sb);
#endif