9 #include <lafs/layout.h>
10 #include <lafs/struct.h>
11 #include <lafs/endian.h>
13 #define LAFS_NOBLOCK 0xFFFFFFFFUL
15 struct lafs *lafs_alloc(void);
16 int lafs_new(struct lafs *, int block_bytes);
18 char *lafs_validate_geometry(long *block_bytes,
22 long long device_bytes);
23 struct lafs_device *lafs_add_device(struct lafs *, char *devname, int fd,
24 loff_t segblocks, loff_t strideblock,
25 int width, int usage_inum);
26 struct lafs_device *lafs_load(int fd, long long device_bytes, char **err);
27 int lafs_include_dev(struct lafs *fs, struct lafs_device *dev, char **err);
29 struct lafs_ino *lafs_get_itable(struct lafs *);
30 struct lafs_ino *lafs_add_inode(struct lafs_ino*, int inum, int type);
31 struct lafs_ino *lafs_get_inode(struct lafs_ino *fsys, int inum);
32 int lafs_imap_set(struct lafs_ino *, int inum);
34 int lafs_add_free_seg(struct lafs*, int dev, loff_t seg);
35 void lafs_find_free(struct lafs *fs);
37 void lafs_inode_init(struct lafs *, char *, int type);
38 struct lafs_ino *lafs_import_inode_buf(struct lafs *fs,
40 struct lafs_ino *parent);
41 void lafs_dirty_inode(struct lafs_ino *);
42 void lafs_inode_fillblock(struct lafs_ino *ino, char *buf);
43 void lafs_make_iblock(struct lafs_ino *ino);
45 struct lafs_dblk *lafs_dblk(struct lafs_ino *ino,
47 int lafs_load_dblk(struct lafs_dblk *);
48 int lafs_find_dblk(struct lafs_dblk *);
49 struct lafs_ino *lafs_import_inode(struct lafs_dblk *db);
50 int lafs_load_cluster(struct lafs *fs, u64 addr, struct cluster_head **chp);
52 int lafs_read_virtual(struct lafs *, char *, loff_t);
53 int lafs_sched_blk(struct lafs_blk *);
54 int lafs_dirty_blk(struct lafs_dblk *);
56 int lafs_write_dev(struct lafs_device *dev);
57 int lafs_write_state(struct lafs *fs);
58 int lafs_checkpoint(struct lafs *fs);
59 void lafs_incorporate(struct lafs_iblk *ib);
60 void lafs_cluster_allocate(struct lafs_blk *b, int cnum);
61 int lafs_calc_cluster_csum(struct cluster_head *head);
62 int lafs_load_cluster(struct lafs *fs, u64 addr, struct cluster_head **chp);
63 void lafs_cluster_flush(struct lafs *fs, int cnum);
64 void lafs_flush_inode(struct lafs_ino *inode);
65 void lafs_flush(struct lafs *lafs);
66 int lafs_new_segment(struct lafs *, int cnum);
67 struct lafs_device *lafs_dev_find(struct lafs *fs, loff_t virt);
68 void lafs_allocated_block(struct lafs_blk *b, loff_t addr);
69 void lafs_cluster_init(struct lafs *fs, int cnum,
70 loff_t addr, loff_t prev, loff_t seq);
71 void lafs_summary_update(struct lafs_ino *ino,
72 loff_t oldaddr, loff_t newaddr,
74 void lafs_segment_count(struct lafs *fs, loff_t addr, int diff);
76 void lafs_print_device(struct lafs_device *dev);
77 void lafs_print_devblock(struct lafs_dev *dev);
78 char *lafs_mount(struct lafs *fs, int force);
79 void lafs_print_state(struct lafs_state *state, int size);
80 void lafs_print_lafs(struct lafs *fs);
81 void lafs_print_inode(struct lafs_ino *ino);
82 void lafs_print_cluster(struct cluster_head *head, int blocksize,
83 int groups, int verbose);
84 u32 lafs_find_next(struct lafs_ino *ino, u32 bnum);
85 int lafs_hash_name(u32 seed, int len, const char *name);
86 void lafs_dir_init_block(char *block, int psz, const char *name, int len,
87 u32 target, int type, int chain_offset);
88 int lafs_dir_add_ent(char *block, int psz, const char *name, int len,
89 u32 target, int type, u32 seed, u32 hash, int hashoffset);
90 int lafs_dir_del_ent(char *block, int psz, u32 seed, u32 hash);
91 void lafs_dir_split(char *orig, int psz, char *new1, char *new2,
92 const char *name, u32 target, int type, u32 *newhash,
93 u32 seed, u32 hash, int chainoffset);
94 void lafs_dir_repack(char *block, int psz, char *new, u32 seed, int merge);
95 int lafs_dir_find(char *block, int psz, u32 seed, u32 hash, u8 *pp);
96 int lafs_dir_empty(char *block);
97 int lafs_dir_blk_size(char *block, int psz);
98 void lafs_dir_print(char *buf, int psz);
100 int lafs_dir_next(struct lafs_ino *dir, u32 *indexp, char *name,
101 u32 *inop, int *typep);
102 uint64_t lafs_leaf_lookup(unsigned char *buf, int len, u32 startaddr,
103 u32 target, u32 *nextp);
104 struct lafs_iblk *lafs_leaf_find(struct lafs_ino *inode,
105 u32 addr, int adopt, u32 *next);
106 u32 lafs_dir_lookup(struct lafs_ino *dir, char *name, int len);
107 struct lafs_ino *lafs_lookup_path(struct lafs_ino *root, struct lafs_ino *cwd,
108 char *path, char **remainder);
109 int lafs_imap_alloc(struct lafs_ino *imap);
110 int lafs_dir_add(struct lafs_ino *dir, char *name, u32 inum, int type);
115 static inline struct lafs_dblk *dblk(struct lafs_blk *b)
117 return container_of(b, struct lafs_dblk, b);
120 static inline struct lafs_iblk *iblk(struct lafs_blk *b)
122 return container_of(b, struct lafs_iblk, b);
125 static inline uint64_t lafs_encode_timeval(struct timeval *tm)
127 uint64_t nano = tm->tv_usec * 1000;
128 uint64_t sec = tm->tv_sec & (0x7FFFFFFFFULL);
130 return sec | (nano << 34);
132 static inline void lafs_decode_timeval(struct timeval *tm, uint64_t te)
134 /* low 35 bits are seconds (800 years)
135 * high 29 bits are 2nanoseconds
138 tm->tv_sec = (te & 0X7FFFFFFFFULL);
139 nano = (te >> 34) & ~(long)1;
140 tm->tv_usec = nano / 1000;
143 static inline struct lafs_device *dev_by_num(struct lafs *fs, int num)
145 struct lafs_device *dv;
146 for (dv = fs->devs ; dv ; dv = dv->next)
147 if (dv->devnum == num)
154 virttoseg(struct lafs *fs, loff_t virt, int *devp, loff_t *segp, loff_t *offsetp)
156 struct lafs_device *dv = lafs_dev_find(fs, virt);
159 if (dv->segment_size >= dv->width * dv->stride) {
160 *offsetp = virt % dv->segment_size;
161 *segp = virt / dv->segment_size;
163 int of = virt % dv->stride;
164 int strp =virt / (dv->width * dv->stride);
166 *segp = (strp * dv->stride + of) /
167 (dv->segment_size / dv->width);
168 *offsetp = virt - dv->segment_stride * *segp;
174 virttophys(struct lafs *fs, loff_t virt, int *devp, loff_t *sectp)
176 struct lafs_device *dv = lafs_dev_find(fs, virt);
183 virt *= fs->blocksize;
184 virt += dv->segment_offset;
190 static inline int lafs_dt_type(struct lafs_ino *ino)
192 if (ino->type < TypeBase)
196 case TypeFile: return DT_REG;
197 case TypeDir: return DT_DIR;
198 case TypeSymlink: return DT_LNK;
199 case TypeSpecial: return ino->md.file.mode >> 12;