shim_fs.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 OSCAR lab, Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * shim_fs.h
  17. *
  18. * Definitions of types and functions for file system bookkeeping.
  19. */
  20. #ifndef _SHIM_FS_H_
  21. #define _SHIM_FS_H_
  22. #include <shim_types.h>
  23. #include <shim_defs.h>
  24. #include <shim_handle.h>
  25. #include <shim_utils.h>
  26. #include <pal.h>
  27. #include <linux_list.h>
  28. #include <sys/stat.h>
  29. struct shim_handle;
  30. #define FS_POLL_RD 0x01
  31. #define FS_POLL_WR 0x02
  32. #define FS_POLL_ER 0x04
  33. #define FS_POLL_SZ 0x08
  34. struct shim_fs_ops {
  35. /* mount: moun an uri to the certain location */
  36. int (*mount) (const char * uri, const char * root, void ** mount_data);
  37. int (*unmount) (void * mount_data);
  38. /* close: clean up the file state inside the handle */
  39. int (*close) (struct shim_handle * hdl);
  40. /* read: the content from the file opened as handle */
  41. int (*read) (struct shim_handle * hdl, void * buf, size_t count);
  42. /* write: the content from the file opened as handle */
  43. int (*write) (struct shim_handle * hdl, const void * buf, size_t count);
  44. /* mmap: mmap handle to address */
  45. int (*mmap) (struct shim_handle * hdl, void ** addr, size_t size,
  46. int prot, int flags, off_t offset);
  47. /* flush: flush out user buffer */
  48. int (*flush) (struct shim_handle * hdl);
  49. /* seek: the content from the file opened as handle */
  50. int (*seek) (struct shim_handle * hdl, off_t offset, int wence);
  51. /* move, copy: rename or duplicate the file */
  52. int (*move) (const char * trim_old_name, const char * trim_new_name);
  53. int (*copy) (const char * trim_old_name, const char * trim_new_name);
  54. int (*truncate) (struct shim_handle * hdl, int len);
  55. /* stat: get status of the file */
  56. int (*hstat) (struct shim_handle * hdl, struct stat * buf);
  57. /* setflags: set flags of the file */
  58. int (*setflags) (struct shim_handle * hdl, int flags);
  59. /* hput: delete the handle and close the PAL handle. */
  60. void (*hput) (struct shim_handle * hdl);
  61. /* lock and unlock the file */
  62. int (*lock) (const char * trim_name);
  63. int (*unlock) (const char * trim_name);
  64. /* lock and unlock the file system */
  65. int (*lockfs) (void);
  66. int (*unlockfs) (void);
  67. /* checkout/reowned/checkin a single handle for migration */
  68. int (*checkout) (struct shim_handle * hdl);
  69. int (*checkin) (struct shim_handle * hdl);
  70. /* poll a single handle */
  71. /* POLL_RD|POLL_WR: return POLL_RD|POLL_WR for readable|writeable,
  72. POLL_ER for failure, -EAGAIN for unknown. */
  73. /* POLL_SZ: return total size */
  74. int (*poll) (struct shim_handle * hdl, int poll_type);
  75. /* checkpoint/migrate the filesystem */
  76. int (*checkpoint) (void ** checkpoint, void * mount_data);
  77. int (*migrate) (void * checkpoint, void ** mount_data);
  78. };
  79. #define DENTRY_VALID 0x0001 /* this dentry is verified to be valid */
  80. #define DENTRY_NEGATIVE 0x0002 /* negative, recently deleted */
  81. #define DENTRY_RECENTLY 0x0004 /* recently used */
  82. #define DENTRY_PERSIST 0x0008 /* added as a persistent dentry */
  83. #define DENTRY_HASHED 0x0010 /* added in the dcache */
  84. #define DENTRY_MOUNTPOINT 0x0040 /* this dentry is a mount point */
  85. #define DENTRY_ISLINK 0x0080 /* this dentry is a link */
  86. #define DENTRY_ISDIRECTORY 0x0100 /* this dentry is a directory */
  87. #define DENTRY_LOCKED 0x0200 /* locked by mountpoints at children */
  88. #define DENTRY_REACHABLE 0x0400 /* permission checked to be reachable */
  89. #define DENTRY_UNREACHABLE 0x0800 /* permission checked to be unreachable */
  90. #define DENTRY_LISTED 0x1000 /* children in directory listed */
  91. #define DENTRY_INO_UPDATED 0x2000 /* ino updated */
  92. #define DENTRY_ANCESTER 0x4000
  93. #define DCACHE_HASH_SIZE 1024
  94. #define DCACHE_HASH(hash) ((hash) & (DCACHE_HASH_SIZE - 1))
  95. struct shim_dentry {
  96. int state; /* flags for managing state */
  97. struct shim_mount * fs; /* this dentry's mounted fs */
  98. struct shim_qstr rel_path; /* the path is relative to
  99. its mount point */
  100. struct shim_qstr name; /* caching the file's name. */
  101. struct hlist_node hlist; /* to resolve collisions in
  102. the hash table */
  103. struct list_head list; /* put dentry to different list
  104. according to its availability,
  105. persistent or freeable */
  106. struct shim_dentry * parent;
  107. int nchildren;
  108. struct list_head children;
  109. struct list_head siblings;
  110. struct shim_dentry * symlink; /* point to symlink target, or
  111. sources (aliases) of linking */
  112. struct list_head alias;
  113. struct shim_mount * mounted;
  114. void * data;
  115. unsigned long ino;
  116. mode_t type;
  117. mode_t mode;
  118. LOCKTYPE lock;
  119. REFTYPE ref_count;
  120. };
  121. struct shim_d_ops {
  122. /* open: provide a filename relative to the mount point and flags,
  123. modify the shim handle, file_data is "inode" equivalent */
  124. int (*open) (struct shim_handle * hdl, struct shim_dentry * dent,
  125. int flags);
  126. /* look up dentry and allocate internal data */
  127. int (*lookup) (struct shim_dentry * dent, bool force);
  128. /* this is to check file type and access, returning the stat.st_mode */
  129. int (*mode) (struct shim_dentry * dent, mode_t * mode, bool force);
  130. /* detach internal data from dentry */
  131. int (*dput) (struct shim_dentry * dent);
  132. /* create a dentry inside a directory */
  133. int (*creat) (struct shim_handle * hdl, struct shim_dentry * dir,
  134. struct shim_dentry * dent, int flags, mode_t mode);
  135. /* unlink a dentry inside a directory */
  136. int (*unlink) (struct shim_dentry * dir, struct shim_dentry * dent);
  137. /* create a directory inside a directory */
  138. int (*mkdir) (struct shim_dentry * dir, struct shim_dentry * dent,
  139. mode_t mode);
  140. /* stat: get status of the file */
  141. int (*stat) (struct shim_dentry * dent, struct stat * buf);
  142. /* extracts the symlink name and saves in link */
  143. int (*follow_link) (struct shim_dentry * dent, struct shim_qstr * link);
  144. /* set up symlink name to a dentry */
  145. int (*set_link) (struct shim_dentry * dent, const char * link);
  146. /* change the mode or owner of a dentry */
  147. int (*chmod) (struct shim_dentry * dent, mode_t mode);
  148. int (*chown) (struct shim_dentry * dent, int uid, int gid);
  149. /* change the name of a dentry */
  150. int (*rename) (struct shim_dentry * old, struct shim_dentry * new);
  151. /* readdir: given the path relative to the mount point, read the childs
  152. into the the buffer */
  153. int (*readdir) (struct shim_dentry * dent, struct shim_dirent ** dirent);
  154. };
  155. #define MAX_PATH 4096
  156. struct shim_mount {
  157. char type[8];
  158. struct shim_dentry * mount_point;
  159. struct shim_qstr path;
  160. struct shim_qstr uri;
  161. struct shim_fs_ops * fs_ops;
  162. struct shim_d_ops * d_ops;
  163. struct shim_dentry * root;
  164. void * data;
  165. void * cpdata;
  166. size_t cpsize;
  167. REFTYPE ref_count;
  168. struct hlist_node hlist;
  169. struct list_head list;
  170. };
  171. extern struct shim_dentry * dentry_root;
  172. #define LOOKUP_FOLLOW 001
  173. #define LOOKUP_DIRECTORY 002
  174. #define LOOKUP_CONTINUE 004
  175. #define LOOKUP_PARENT 010
  176. #define MAY_EXEC 001
  177. #define MAY_WRITE 002
  178. #define MAY_READ 004
  179. #if 0
  180. #define MAY_APPEND 010
  181. #endif
  182. #define NO_MODE ((mode_t) -1)
  183. #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
  184. #define ACC_MODE(x) ((((x) == O_RDONLY || (x) == O_RDWR) ? MAY_READ : 0) | \
  185. (((x) == O_WRONLY || (x) == O_RDWR) ? MAY_WRITE : 0))
  186. #define LOOKUP_OPEN 0100
  187. #define LOOKUP_CREATE 0200
  188. #define LOOKUP_ACCESS 0400
  189. #define LOOKUP_SYNC (LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_ACCESS)
  190. enum lookup_type {
  191. LAST_NORM,
  192. LAST_ROOT,
  193. LAST_DOT,
  194. LAST_DOTDOT,
  195. LAST_BIND
  196. };
  197. struct lookup {
  198. struct shim_dentry * dentry;
  199. struct shim_mount * mount;
  200. const char * last;
  201. int depth;
  202. int flags;
  203. enum lookup_type last_type;
  204. };
  205. long get_dcache_stats (const char * name);
  206. void path_acquire (struct lookup * look);
  207. void path_release (struct lookup * look);
  208. /* initialization for fs and mounts */
  209. int init_config (const char ** envp);
  210. int init_fs (void);
  211. int reinit_fs (void);
  212. int init_mount_root (void);
  213. int init_mount (void);
  214. /* path utilities */
  215. const char * get_file_name (const char * path, size_t len);
  216. int get_abs_path (const char * cwd, const char * path, char * buf,
  217. int size);
  218. int get_norm_path (const char * path, char * buf, int size);
  219. /* file system operations */
  220. int mount_fs (const char * mount_type, const char * mount_uri,
  221. const char * mount_point);
  222. int unmount_fs (const char * mount_point);
  223. int readdir_fs (HASHTYPE hash, struct shim_dirent ** dirent);
  224. int search_builtin_fs (const char * type, struct shim_mount ** fs);
  225. void get_mount (struct shim_mount * mount);
  226. void put_mount (struct shim_mount * mount);
  227. #include <shim_utils.h>
  228. static inline void set_handle_fs (struct shim_handle * hdl,
  229. struct shim_mount * fs)
  230. {
  231. get_mount(fs);
  232. hdl->fs = fs;
  233. memcpy(hdl->fs_type, fs->type, sizeof(hdl->fs_type));
  234. }
  235. int walk_mounts (int (*walk) (struct shim_mount * mount, void * arg),
  236. void * arg);
  237. /* functions for dcache supports */
  238. int init_dcache (void);
  239. int reinit_dcache (void);
  240. extern LOCKTYPE dcache_lock;
  241. int permission (struct shim_dentry * dent, int mask, bool force);
  242. int lookup_dentry (struct shim_dentry * base, const char * name, int namelen,
  243. bool force, struct shim_dentry ** new);
  244. int __path_lookupat (struct shim_dentry * start, const char * path, int flags,
  245. struct shim_dentry ** dent);
  246. int path_lookupat (struct shim_dentry * start, const char * name, int flags,
  247. struct shim_dentry ** dent);
  248. int path_startat (int dfd, struct shim_dentry ** dir);
  249. int open_namei (struct shim_handle * hdl, struct shim_dentry * start,
  250. const char * path, int flags, int mode,
  251. struct shim_dentry ** dent);
  252. int dentry_open (struct shim_handle * hdl, struct shim_dentry * dent,
  253. int flags);
  254. int directory_open (struct shim_handle * hdl, struct shim_dentry * dent,
  255. int flags);
  256. void get_dentry (struct shim_dentry * dent);
  257. void put_dentry (struct shim_dentry * dent);
  258. static inline __attribute__((always_inline))
  259. char * dentry_get_path (struct shim_dentry * dent, bool on_stack,
  260. int * sizeptr)
  261. {
  262. struct shim_mount * fs = dent->fs;
  263. int bufsize = (fs ? fs->path.len + 1 : 0) + dent->rel_path.len;
  264. char * buffer = on_stack ? __alloca(bufsize) : malloc(bufsize);
  265. char * c = buffer;
  266. if (!buffer)
  267. return NULL;
  268. if (fs && !qstrempty(&fs->path)) {
  269. memcpy(c, qstrgetstr(&fs->path), fs->path.len);
  270. c += fs->path.len;
  271. }
  272. if (dent->rel_path.len) {
  273. if (c == buffer || *(c - 1) != '/')
  274. *(c++) = '/';
  275. memcpy(c, qstrgetstr(&dent->rel_path), dent->rel_path.len);
  276. c += dent->rel_path.len;
  277. } else {
  278. if (c != buffer && *(c - 1) == '/')
  279. c--;
  280. if (c == buffer)
  281. *(c++) = '/';
  282. }
  283. *c = 0;
  284. if (sizeptr)
  285. *sizeptr = c - buffer;
  286. return buffer;
  287. }
  288. static inline __attribute__((always_inline))
  289. const char * dentry_get_name (struct shim_dentry * dent)
  290. {
  291. return qstrgetstr(&dent->name);
  292. }
  293. struct shim_dentry * get_new_dentry (struct shim_dentry * parent,
  294. const char * name, int namelen);
  295. void __set_parent_dentry (struct shim_dentry * child,
  296. struct shim_dentry * parent);
  297. void __unset_parent_dentry (struct shim_dentry * child,
  298. struct shim_dentry * parent);
  299. void __add_dcache (struct shim_dentry * dent, HASHTYPE * hashptr);
  300. void add_dcache (struct shim_dentry * dent, HASHTYPE * hashptr);
  301. void __del_dcache (struct shim_dentry * dent);
  302. void del_dcache (struct shim_dentry * dent);
  303. struct shim_dentry *
  304. __lookup_dcache (struct shim_dentry * start, const char * name, int namelen,
  305. const char * path, int pathlen, HASHTYPE * hashptr);
  306. struct shim_dentry *
  307. lookup_dcache (struct shim_dentry * start, const char * name, int namelen,
  308. const char * path, int pathlen, HASHTYPE * hashptr);
  309. int __del_dentry_tree(struct shim_dentry * root);
  310. /* hashing utilities */
  311. #define MOUNT_HASH_BYTE 1
  312. #define MOUNT_HASH_WIDTH 8
  313. #define MOUNT_HASH_SIZE 256
  314. #define MOUNT_HASH(hash) ((hash) & (MOUNT_HASH_SIZE - 1))
  315. HASHTYPE hash_path (const char * path, int size,
  316. const char * sep);
  317. HASHTYPE hash_parent_path (HASHTYPE hbuf, const char * name,
  318. int * size, const char * sep);
  319. HASHTYPE rehash_name (HASHTYPE parent_hbuf,
  320. const char * name, int size);
  321. HASHTYPE rehash_path (HASHTYPE ancester_hbuf,
  322. const char * path, int size, const char * sep);
  323. extern struct shim_fs_ops chroot_fs_ops;
  324. extern struct shim_d_ops chroot_d_ops;
  325. extern struct shim_fs_ops str_fs_ops;
  326. extern struct shim_d_ops str_d_ops;
  327. extern struct shim_fs_ops dev_fs_ops;
  328. extern struct shim_d_ops dev_d_ops;
  329. extern struct shim_fs_ops config_fs_ops;
  330. extern struct shim_d_ops config_d_ops;
  331. extern struct shim_fs_ops proc_fs_ops;
  332. extern struct shim_d_ops proc_d_ops;
  333. extern struct shim_mount chroot_builtin_fs;
  334. extern struct shim_mount pipe_builtin_fs;
  335. extern struct shim_mount socket_builtin_fs;
  336. extern struct shim_mount epoll_builtin_fs;
  337. /* proc file system */
  338. struct proc_nm_ops {
  339. int (*match_name) (const char * name);
  340. int (*list_name) (const char * name, struct shim_dirent ** buf,
  341. int count);
  342. };
  343. struct proc_fs_ops {
  344. int (*open) (struct shim_handle * hdl, const char * name, int flags);
  345. int (*mode) (const char * name, mode_t * mode);
  346. int (*stat) (const char * name, struct stat * buf);
  347. int (*follow_link) (const char * name, struct shim_qstr * link);
  348. };
  349. struct proc_dir;
  350. struct proc_ent {
  351. const char * name; /* a proc_callback should at least
  352. have a name or nm_ops.
  353. Otherwise, it is a NULL-end. */
  354. const struct proc_nm_ops * nm_ops;
  355. const struct proc_fs_ops * fs_ops;
  356. const struct proc_dir * dir;
  357. };
  358. struct proc_dir {
  359. int size;
  360. const struct proc_ent ent[];
  361. };
  362. /* string-type file system */
  363. int str_add_dir (const char * path, mode_t mode, struct shim_dentry ** dent);
  364. int str_add_file (const char * path, mode_t mode, struct shim_dentry ** dent);
  365. int str_open (struct shim_handle * hdl, struct shim_dentry * dent, int flags);
  366. int str_dput (struct shim_dentry * dent);
  367. int str_close (struct shim_handle * hdl);
  368. int str_read (struct shim_handle * hdl, void * buf, size_t count);
  369. int str_write (struct shim_handle * hdl, const void * buf, size_t count);
  370. int str_seek (struct shim_handle * hdl, off_t offset, int whence);
  371. int str_flush (struct shim_handle * hdl);
  372. #endif /* _SHIM_FS_H_ */