zonefs.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Simple zone file system for zoned block devices.
  4. *
  5. * Copyright (C) 2019 Western Digital Corporation or its affiliates.
  6. */
  7. #ifndef __ZONEFS_H__
  8. #define __ZONEFS_H__
  9. #include <linux/fs.h>
  10. #include <linux/magic.h>
  11. #include <linux/uuid.h>
  12. #include <linux/mutex.h>
  13. #include <linux/rwsem.h>
  14. #include <linux/kobject.h>
  15. /*
  16. * Maximum length of file names: this only needs to be large enough to fit
  17. * the zone group directory names and a decimal zone number for file names.
  18. * 16 characters is plenty.
  19. */
  20. #define ZONEFS_NAME_MAX 16
  21. /*
  22. * Zone types: ZONEFS_ZTYPE_SEQ is used for all sequential zone types
  23. * defined in linux/blkzoned.h, that is, BLK_ZONE_TYPE_SEQWRITE_REQ and
  24. * BLK_ZONE_TYPE_SEQWRITE_PREF.
  25. */
  26. enum zonefs_ztype {
  27. ZONEFS_ZTYPE_CNV,
  28. ZONEFS_ZTYPE_SEQ,
  29. ZONEFS_ZTYPE_MAX,
  30. };
  31. static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
  32. {
  33. if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
  34. return ZONEFS_ZTYPE_CNV;
  35. return ZONEFS_ZTYPE_SEQ;
  36. }
  37. #define ZONEFS_ZONE_INIT_MODE (1U << 0)
  38. #define ZONEFS_ZONE_OPEN (1U << 1)
  39. #define ZONEFS_ZONE_ACTIVE (1U << 2)
  40. #define ZONEFS_ZONE_OFFLINE (1U << 3)
  41. #define ZONEFS_ZONE_READONLY (1U << 4)
  42. #define ZONEFS_ZONE_CNV (1U << 31)
  43. /*
  44. * In-memory per-file inode zone data.
  45. */
  46. struct zonefs_zone {
  47. /* Zone state flags */
  48. unsigned int z_flags;
  49. /* Zone start sector (512B unit) */
  50. sector_t z_sector;
  51. /* Zone size (bytes) */
  52. loff_t z_size;
  53. /* Zone capacity (file maximum size, bytes) */
  54. loff_t z_capacity;
  55. /* Write pointer offset in the zone (sequential zones only, bytes) */
  56. loff_t z_wpoffset;
  57. /* Saved inode uid, gid and access rights */
  58. umode_t z_mode;
  59. kuid_t z_uid;
  60. kgid_t z_gid;
  61. };
  62. /*
  63. * In memory zone group information: all zones of a group are exposed
  64. * as files, one file per zone.
  65. */
  66. struct zonefs_zone_group {
  67. struct inode *g_inode;
  68. unsigned int g_nr_zones;
  69. struct zonefs_zone *g_zones;
  70. };
  71. /*
  72. * In-memory inode data.
  73. */
  74. struct zonefs_inode_info {
  75. struct inode i_vnode;
  76. /*
  77. * To serialise fully against both syscall and mmap based IO and
  78. * sequential file truncation, two locks are used. For serializing
  79. * zonefs_seq_file_truncate() against zonefs_iomap_begin(), that is,
  80. * file truncate operations against block mapping, i_truncate_mutex is
  81. * used. i_truncate_mutex also protects against concurrent accesses
  82. * and changes to the inode private data, and in particular changes to
  83. * a sequential file size on completion of direct IO writes.
  84. * Serialization of mmap read IOs with truncate and syscall IO
  85. * operations is done with invalidate_lock in addition to
  86. * i_truncate_mutex. Only zonefs_seq_file_truncate() takes both lock
  87. * (invalidate_lock first, i_truncate_mutex second).
  88. */
  89. struct mutex i_truncate_mutex;
  90. /* guarded by i_truncate_mutex */
  91. unsigned int i_wr_refcnt;
  92. };
  93. static inline struct zonefs_inode_info *ZONEFS_I(struct inode *inode)
  94. {
  95. return container_of(inode, struct zonefs_inode_info, i_vnode);
  96. }
  97. static inline bool zonefs_zone_is_cnv(struct zonefs_zone *z)
  98. {
  99. return z->z_flags & ZONEFS_ZONE_CNV;
  100. }
  101. static inline bool zonefs_zone_is_seq(struct zonefs_zone *z)
  102. {
  103. return !zonefs_zone_is_cnv(z);
  104. }
  105. static inline struct zonefs_zone *zonefs_inode_zone(struct inode *inode)
  106. {
  107. return inode->i_private;
  108. }
  109. static inline bool zonefs_inode_is_cnv(struct inode *inode)
  110. {
  111. return zonefs_zone_is_cnv(zonefs_inode_zone(inode));
  112. }
  113. static inline bool zonefs_inode_is_seq(struct inode *inode)
  114. {
  115. return zonefs_zone_is_seq(zonefs_inode_zone(inode));
  116. }
  117. /*
  118. * On-disk super block (block 0).
  119. */
  120. #define ZONEFS_LABEL_LEN 64
  121. #define ZONEFS_UUID_SIZE 16
  122. #define ZONEFS_SUPER_SIZE 4096
  123. struct zonefs_super {
  124. /* Magic number */
  125. __le32 s_magic;
  126. /* Checksum */
  127. __le32 s_crc;
  128. /* Volume label */
  129. char s_label[ZONEFS_LABEL_LEN];
  130. /* 128-bit uuid */
  131. __u8 s_uuid[ZONEFS_UUID_SIZE];
  132. /* Features */
  133. __le64 s_features;
  134. /* UID/GID to use for files */
  135. __le32 s_uid;
  136. __le32 s_gid;
  137. /* File permissions */
  138. __le32 s_perm;
  139. /* Padding to ZONEFS_SUPER_SIZE bytes */
  140. __u8 s_reserved[3988];
  141. } __packed;
  142. /*
  143. * Feature flags: specified in the s_features field of the on-disk super
  144. * block struct zonefs_super and in-memory in the s_feartures field of
  145. * struct zonefs_sb_info.
  146. */
  147. enum zonefs_features {
  148. /*
  149. * Aggregate contiguous conventional zones into a single file.
  150. */
  151. ZONEFS_F_AGGRCNV = 1ULL << 0,
  152. /*
  153. * Use super block specified UID for files instead of default 0.
  154. */
  155. ZONEFS_F_UID = 1ULL << 1,
  156. /*
  157. * Use super block specified GID for files instead of default 0.
  158. */
  159. ZONEFS_F_GID = 1ULL << 2,
  160. /*
  161. * Use super block specified file permissions instead of default 640.
  162. */
  163. ZONEFS_F_PERM = 1ULL << 3,
  164. };
  165. #define ZONEFS_F_DEFINED_FEATURES \
  166. (ZONEFS_F_AGGRCNV | ZONEFS_F_UID | ZONEFS_F_GID | ZONEFS_F_PERM)
  167. /*
  168. * Mount options for zone write pointer error handling.
  169. */
  170. #define ZONEFS_MNTOPT_ERRORS_RO (1 << 0) /* Make zone file readonly */
  171. #define ZONEFS_MNTOPT_ERRORS_ZRO (1 << 1) /* Make zone file offline */
  172. #define ZONEFS_MNTOPT_ERRORS_ZOL (1 << 2) /* Make zone file offline */
  173. #define ZONEFS_MNTOPT_ERRORS_REPAIR (1 << 3) /* Remount read-only */
  174. #define ZONEFS_MNTOPT_ERRORS_MASK \
  175. (ZONEFS_MNTOPT_ERRORS_RO | ZONEFS_MNTOPT_ERRORS_ZRO | \
  176. ZONEFS_MNTOPT_ERRORS_ZOL | ZONEFS_MNTOPT_ERRORS_REPAIR)
  177. #define ZONEFS_MNTOPT_EXPLICIT_OPEN (1 << 4) /* Explicit open/close of zones on open/close */
  178. /*
  179. * In-memory Super block information.
  180. */
  181. struct zonefs_sb_info {
  182. unsigned long s_mount_opts;
  183. spinlock_t s_lock;
  184. unsigned long long s_features;
  185. kuid_t s_uid;
  186. kgid_t s_gid;
  187. umode_t s_perm;
  188. uuid_t s_uuid;
  189. unsigned int s_zone_sectors_shift;
  190. struct zonefs_zone_group s_zgroup[ZONEFS_ZTYPE_MAX];
  191. loff_t s_blocks;
  192. loff_t s_used_blocks;
  193. unsigned int s_max_wro_seq_files;
  194. atomic_t s_wro_seq_files;
  195. unsigned int s_max_active_seq_files;
  196. atomic_t s_active_seq_files;
  197. bool s_sysfs_registered;
  198. struct kobject s_kobj;
  199. struct completion s_kobj_unregister;
  200. };
  201. static inline struct zonefs_sb_info *ZONEFS_SB(struct super_block *sb)
  202. {
  203. return sb->s_fs_info;
  204. }
  205. #define zonefs_info(sb, format, args...) \
  206. pr_info("zonefs (%s): " format, sb->s_id, ## args)
  207. #define zonefs_err(sb, format, args...) \
  208. pr_err("zonefs (%s) ERROR: " format, sb->s_id, ## args)
  209. #define zonefs_warn(sb, format, args...) \
  210. pr_warn("zonefs (%s) WARNING: " format, sb->s_id, ## args)
  211. /* In super.c */
  212. void zonefs_inode_account_active(struct inode *inode);
  213. int zonefs_inode_zone_mgmt(struct inode *inode, enum req_op op);
  214. void zonefs_i_size_write(struct inode *inode, loff_t isize);
  215. void zonefs_update_stats(struct inode *inode, loff_t new_isize);
  216. void __zonefs_io_error(struct inode *inode, bool write);
  217. static inline void zonefs_io_error(struct inode *inode, bool write)
  218. {
  219. struct zonefs_inode_info *zi = ZONEFS_I(inode);
  220. mutex_lock(&zi->i_truncate_mutex);
  221. __zonefs_io_error(inode, write);
  222. mutex_unlock(&zi->i_truncate_mutex);
  223. }
  224. /* In super.c */
  225. extern const struct inode_operations zonefs_dir_inode_operations;
  226. extern const struct file_operations zonefs_dir_operations;
  227. /* In file.c */
  228. extern const struct address_space_operations zonefs_file_aops;
  229. extern const struct file_operations zonefs_file_operations;
  230. int zonefs_file_truncate(struct inode *inode, loff_t isize);
  231. /* In sysfs.c */
  232. int zonefs_sysfs_register(struct super_block *sb);
  233. void zonefs_sysfs_unregister(struct super_block *sb);
  234. int zonefs_sysfs_init(void);
  235. void zonefs_sysfs_exit(void);
  236. #endif