mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-05 10:10:42 +00:00
Directory entries were the last items that had large variable length keys because they stored the entry name in the key. We'd like to have small fixed size keys so let's store dirents with small keys. Entries for lookup are stored at the hash of the name instead of the full name. The key also contains the unique readdir pos so that we don't have to deal with collision on creation. The lookup procedure now does need to iterate over all the readdir positions for the hash value and compare the names. Entries for link backref walking are stored with the entry's position in the parent dir instead of the entry's name. The name is then stored in the value. Inode to path conversion can still walk the backref items without having to lookup dirent items. These changes mean that all directory entry items are now stored at a small key with some u64s (hash, pos, parent dir, etc) and have a value with the dirent struct and full entry name. This lets us use the same key and value format for the three entry key types. We no longer have to allocate keys, we can store them on the stack. We store the entry's hash and pos in the dirent struct in the item value so that any item has all the fields to reference all the other item keys. We store the same values in the dentry_info so that deletion (unlink and rename) can find all the entries. The ino_path ioctl can now much more clearly iterate over parent directories and entry positions instead of oh so cleverly iterating over null terminated names in the parent directories. The ioctl interface structs and implementation become simpler. Signed-off-by: Zach Brown <zab@versity.com>
36 lines
964 B
C
36 lines
964 B
C
#ifndef _SCOUTFS_DIR_H_
|
|
#define _SCOUTFS_DIR_H_
|
|
|
|
#include "format.h"
|
|
#include "lock.h"
|
|
|
|
extern const struct file_operations scoutfs_dir_fops;
|
|
extern const struct inode_operations scoutfs_dir_iops;
|
|
extern const struct inode_operations scoutfs_symlink_iops;
|
|
|
|
struct scoutfs_link_backref_entry {
|
|
struct list_head head;
|
|
u64 dir_ino;
|
|
u64 dir_pos;
|
|
u16 name_len;
|
|
struct scoutfs_dirent dent;
|
|
/* the full name is allocated and stored in dent.name[0] */
|
|
};
|
|
|
|
int scoutfs_dir_get_backref_path(struct super_block *sb, u64 ino, u64 dir_ino,
|
|
u64 dir_pos, struct list_head *list);
|
|
void scoutfs_dir_free_backref_path(struct super_block *sb,
|
|
struct list_head *list);
|
|
|
|
int scoutfs_dir_add_next_linkref(struct super_block *sb, u64 ino,
|
|
u64 dir_ino, u64 dir_pos,
|
|
struct list_head *list);
|
|
|
|
int scoutfs_symlink_drop(struct super_block *sb, u64 ino,
|
|
struct scoutfs_lock *lock, u64 i_size);
|
|
|
|
int scoutfs_dir_init(void);
|
|
void scoutfs_dir_exit(void);
|
|
|
|
#endif
|