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_inode_setaccess(struct v_inode* inode, unsigned int acl)
170 fsapi_inode_setowner(struct v_inode* inode, uid_t uid, gid_t gid)
177 fsapi_dnode_setdector(struct v_dnode* dnode,
180 dnode->destruct = free_cb;
183 static inline struct v_inode*
184 fsapi_dnode_parent(struct v_dnode* dnode)
186 assert(dnode->parent);
187 return dnode->parent->inode;
191 fsapi_dir_report(struct dir_context *dctx,
192 const char *name, const int len, const int dtype)
194 dctx->read_complete_callback(dctx, name, len, dtype);
198 * @brief Get a block with file-system defined block size
199 * from underlying storage medium at given block id
200 * (block address). Depending on the device attribute,
201 * it may or may not go through the block cache layer.
203 * @param vsb super-block
204 * @param block_id block address
208 fsblock_get(struct v_superblock* vsb, unsigned int block_id)
210 return blkbuf_take(vsb->blks, block_id);
214 * @brief put the block back into cache, must to pair with
215 * fsblock_get. Otherwise memory leakage will occur.
220 fsblock_put(bbuf_t blkbuf)
222 return blkbuf_put(blkbuf);
227 fsblock_take(bbuf_t blk)
229 return blkbuf_refonce(blk);
232 static inline unsigned int
233 fsblock_id(bbuf_t blkbuf)
235 return blkbuf_id(blkbuf);
239 * @brief Mark the block dirty and require scheduling a device
240 * write request to sync it with underlying medium. Lunaix
241 * will do the scheduling when it sees fit.
246 fsblock_dirty(bbuf_t blkbuf)
248 return blkbuf_dirty(blkbuf);
252 * @brief Manually trigger a sync cycle, regardless the
258 fsblock_sync(bbuf_t blkbuf)
261 XXX delay the sync for better write aggregation
262 scheduled sync event may happened immediately (i.e., blkio queue is
263 empty or nearly empty), any susequent write to the same blkbuf must
264 schedule another write. Which could thrash the disk IO when intensive
267 return blkbuf_schedule_sync(blkbuf);
271 fsapi_handle_pseudo_dirent(struct v_file* file, struct dir_context* dctx)
273 if (file->f_pos == 0) {
274 fsapi_dir_report(dctx, ".", 1, vfs_get_dtype(VFS_IFDIR));
278 if (file->f_pos == 1) {
279 fsapi_dir_report(dctx, "..", 2, vfs_get_dtype(VFS_IFDIR));
286 static inline struct filesystem*
287 fsapi_fs_declare(const char* name, unsigned int type)
289 struct filesystem* fs;
291 fs = fsm_new_fs(name, -1);
299 fsapi_fs_set_mntops(struct filesystem* fs,
300 mntops_mnt mnt, mntops_umnt umnt)
307 fsapi_fs_finalise(struct filesystem* fs)
309 assert_fs(fs->mount);
310 assert_fs(fs->unmount);
314 #endif /* __LUNAIX_FSAPI_H */