1 #ifndef __LUNAIX_FSAPI_H
2 #define __LUNAIX_FSAPI_H
5 #include <lunaix/fcntl_defs.h>
6 #include <lunaix/blkbuf.h>
7 #include <klibc/string.h>
9 #include <usr/lunaix/dirent_defs.h>
13 size_t (*read_capacity)(struct v_superblock* vsb);
14 size_t (*read_usage)(struct v_superblock* vsb);
15 void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
16 void (*release)(struct v_superblock* vsb);
19 static inline struct device*
20 fsapi_blockdev(struct v_superblock* vsb)
22 if (!(vsb->fs->types & FSTYPE_PSEUDO)) {
29 typedef void (*inode_init)(struct v_superblock* vsb, struct v_inode* inode) ;
30 typedef void (*inode_free)(struct v_inode* inode) ;
31 typedef void (*dnode_free)(struct v_dnode* dnode) ;
34 fsapi_set_inode_initiator(struct v_superblock* vsb, inode_init inode_initiator)
36 vsb->ops.init_inode = inode_initiator;
40 fsapi_block_size(struct v_superblock* vsb)
46 fsapi_set_vsb_ops(struct v_superblock* vsb, struct fsapi_vsb_ops* basic_ops)
48 vsb->ops.read_capacity = basic_ops->read_capacity;
49 vsb->ops.read_usage = basic_ops->read_usage;
50 vsb->ops.release = basic_ops->release;
51 vsb->ops.init_inode = basic_ops->init_inode;
55 fsapi_complete_vsb_setup(struct v_superblock* vsb, void* cfs_sb)
57 assert_fs(vsb->ops.init_inode);
58 assert_fs(vsb->ops.read_capacity);
59 assert_fs(vsb->blksize);
66 fsapi_begin_vsb_setup(struct v_superblock* vsb, size_t blksz)
72 vsb->blks = blkbuf_create(block_dev(vsb->dev), blksz);
76 fsapi_reset_vsb(struct v_superblock* vsb)
79 blkbuf_release(vsb->blks);
84 vsb->root->mnt->flags = 0;
85 memset(&vsb->ops, 0, sizeof(vsb->ops));
89 fsapi_readonly_mount(struct v_superblock* vsb)
91 return (vsb->root->mnt->flags & MNT_RO);
95 fsapi_set_readonly_mount(struct v_superblock* vsb)
97 vsb->root->mnt->flags |= MNT_RO;
100 #define fsapi_impl_data(vfs_obj, type) (type*)((vfs_obj)->data)
103 fsapi_inode_setid(struct v_inode* inode,
104 inode_t i_id, unsigned int blk_addr)
107 inode->lb_addr = blk_addr;
111 fsapi_inode_settype(struct v_inode* inode, unsigned int type)
117 fsapi_inode_setsize(struct v_inode* inode, unsigned int fsize)
119 inode->lb_usage = ICEIL(fsize, inode->sb->blksize);
120 inode->fsize = fsize;
124 fsapi_inode_setops(struct v_inode* inode,
125 struct v_inode_ops* ops)
131 fsapi_inode_setfops(struct v_inode* inode,
132 struct v_file_ops* fops)
134 inode->default_fops = fops;
138 fsapi_inode_setdector(struct v_inode* inode,
141 inode->destruct = free_cb;
145 fsapi_inode_complete(struct v_inode* inode, void* data)
147 assert_fs(inode->ops);
148 assert_fs(inode->default_fops);
149 assert_fs(inode->default_fops);
155 fsapi_inode_settime(struct v_inode* inode,
156 time_t ctime, time_t mtime, time_t atime)
158 inode->ctime = ctime;
159 inode->mtime = mtime;
160 inode->atime = atime;
164 fsapi_dnode_setdector(struct v_dnode* dnode,
167 dnode->destruct = free_cb;
170 static inline struct v_inode*
171 fsapi_dnode_parent(struct v_dnode* dnode)
173 assert(dnode->parent);
174 return dnode->parent->inode;
178 fsapi_dir_report(struct dir_context *dctx,
179 const char *name, const int len, const int dtype)
181 dctx->read_complete_callback(dctx, name, len, dtype);
185 * @brief Get a block with file-system defined block size
186 * from underlying storage medium at given block id
187 * (block address). Depending on the device attribute,
188 * it may or may not go through the block cache layer.
190 * @param vsb super-block
191 * @param block_id block address
195 fsblock_get(struct v_superblock* vsb, unsigned int block_id)
197 return blkbuf_take(vsb->blks, block_id);
201 * @brief put the block back into cache, must to pair with
202 * fsblock_get. Otherwise memory leakage will occur.
207 fsblock_put(bbuf_t blkbuf)
209 return blkbuf_put(blkbuf);
214 fsblock_take(bbuf_t blk)
216 return blkbuf_refonce(blk);
219 static inline unsigned int
220 fsblock_id(bbuf_t blkbuf)
222 return blkbuf_id(blkbuf);
226 * @brief Mark the block dirty and require scheduling a device
227 * write request to sync it with underlying medium. Lunaix
228 * will do the scheduling when it sees fit.
233 fsblock_dirty(bbuf_t blkbuf)
235 return blkbuf_dirty(blkbuf);
239 * @brief Manually trigger a sync cycle, regardless the
245 fsblock_sync(bbuf_t blkbuf)
248 XXX delay the sync for better write aggregation
249 scheduled sync event may happened immediately (i.e., blkio queue is
250 empty or nearly empty), any susequent write to the same blkbuf must
251 schedule another write. Which could thrash the disk IO when intensive
254 return blkbuf_schedule_sync(blkbuf);
258 fsapi_handle_pseudo_dirent(struct v_file* file, struct dir_context* dctx)
260 if (file->f_pos == 0) {
261 fsapi_dir_report(dctx, ".", 1, vfs_get_dtype(VFS_IFDIR));
265 if (file->f_pos == 1) {
266 fsapi_dir_report(dctx, "..", 2, vfs_get_dtype(VFS_IFDIR));
273 static inline struct filesystem*
274 fsapi_fs_declare(const char* name, unsigned int type)
276 struct filesystem* fs;
278 fs = fsm_new_fs(name, -1);
286 fsapi_fs_set_mntops(struct filesystem* fs,
287 mntops_mnt mnt, mntops_umnt umnt)
294 fsapi_fs_finalise(struct filesystem* fs)
296 assert_fs(fs->mount);
297 assert_fs(fs->unmount);
302 fsapi_check_readdir_pos_pseduo(struct v_file* file)
304 return file->f_pos < 2;
308 fsapi_readdir_pos_entries_at(struct v_file* file, unsigned int pos)
310 return file->f_pos == pos + 2;
313 #endif /* __LUNAIX_FSAPI_H */