Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt
[sfrench/cifs-2.6.git] / fs / zonefs / zonefs.h
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
10 #include <linux/fs.h>
11 #include <linux/magic.h>
12 #include <linux/uuid.h>
13 #include <linux/mutex.h>
14 #include <linux/rwsem.h>
15 #include <linux/kobject.h>
16
17 /*
18  * Maximum length of file names: this only needs to be large enough to fit
19  * the zone group directory names and a decimal zone number for file names.
20  * 16 characters is plenty.
21  */
22 #define ZONEFS_NAME_MAX         16
23
24 /*
25  * Zone types: ZONEFS_ZTYPE_SEQ is used for all sequential zone types
26  * defined in linux/blkzoned.h, that is, BLK_ZONE_TYPE_SEQWRITE_REQ and
27  * BLK_ZONE_TYPE_SEQWRITE_PREF.
28  */
29 enum zonefs_ztype {
30         ZONEFS_ZTYPE_CNV,
31         ZONEFS_ZTYPE_SEQ,
32         ZONEFS_ZTYPE_MAX,
33 };
34
35 static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
36 {
37         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
38                 return ZONEFS_ZTYPE_CNV;
39         return ZONEFS_ZTYPE_SEQ;
40 }
41
42 #define ZONEFS_ZONE_OPEN        (1 << 0)
43 #define ZONEFS_ZONE_ACTIVE      (1 << 1)
44
45 /*
46  * In-memory inode data.
47  */
48 struct zonefs_inode_info {
49         struct inode            i_vnode;
50
51         /* File zone type */
52         enum zonefs_ztype       i_ztype;
53
54         /* File zone start sector (512B unit) */
55         sector_t                i_zsector;
56
57         /* File zone write pointer position (sequential zones only) */
58         loff_t                  i_wpoffset;
59
60         /* File maximum size */
61         loff_t                  i_max_size;
62
63         /* File zone size */
64         loff_t                  i_zone_size;
65
66         /*
67          * To serialise fully against both syscall and mmap based IO and
68          * sequential file truncation, two locks are used. For serializing
69          * zonefs_seq_file_truncate() against zonefs_iomap_begin(), that is,
70          * file truncate operations against block mapping, i_truncate_mutex is
71          * used. i_truncate_mutex also protects against concurrent accesses
72          * and changes to the inode private data, and in particular changes to
73          * a sequential file size on completion of direct IO writes.
74          * Serialization of mmap read IOs with truncate and syscall IO
75          * operations is done with invalidate_lock in addition to
76          * i_truncate_mutex.  Only zonefs_seq_file_truncate() takes both lock
77          * (invalidate_lock first, i_truncate_mutex second).
78          */
79         struct mutex            i_truncate_mutex;
80
81         /* guarded by i_truncate_mutex */
82         unsigned int            i_wr_refcnt;
83         unsigned int            i_flags;
84 };
85
86 static inline struct zonefs_inode_info *ZONEFS_I(struct inode *inode)
87 {
88         return container_of(inode, struct zonefs_inode_info, i_vnode);
89 }
90
91 /*
92  * On-disk super block (block 0).
93  */
94 #define ZONEFS_LABEL_LEN        64
95 #define ZONEFS_UUID_SIZE        16
96 #define ZONEFS_SUPER_SIZE       4096
97
98 struct zonefs_super {
99
100         /* Magic number */
101         __le32          s_magic;
102
103         /* Checksum */
104         __le32          s_crc;
105
106         /* Volume label */
107         char            s_label[ZONEFS_LABEL_LEN];
108
109         /* 128-bit uuid */
110         __u8            s_uuid[ZONEFS_UUID_SIZE];
111
112         /* Features */
113         __le64          s_features;
114
115         /* UID/GID to use for files */
116         __le32          s_uid;
117         __le32          s_gid;
118
119         /* File permissions */
120         __le32          s_perm;
121
122         /* Padding to ZONEFS_SUPER_SIZE bytes */
123         __u8            s_reserved[3988];
124
125 } __packed;
126
127 /*
128  * Feature flags: specified in the s_features field of the on-disk super
129  * block struct zonefs_super and in-memory in the s_feartures field of
130  * struct zonefs_sb_info.
131  */
132 enum zonefs_features {
133         /*
134          * Aggregate contiguous conventional zones into a single file.
135          */
136         ZONEFS_F_AGGRCNV = 1ULL << 0,
137         /*
138          * Use super block specified UID for files instead of default 0.
139          */
140         ZONEFS_F_UID = 1ULL << 1,
141         /*
142          * Use super block specified GID for files instead of default 0.
143          */
144         ZONEFS_F_GID = 1ULL << 2,
145         /*
146          * Use super block specified file permissions instead of default 640.
147          */
148         ZONEFS_F_PERM = 1ULL << 3,
149 };
150
151 #define ZONEFS_F_DEFINED_FEATURES \
152         (ZONEFS_F_AGGRCNV | ZONEFS_F_UID | ZONEFS_F_GID | ZONEFS_F_PERM)
153
154 /*
155  * Mount options for zone write pointer error handling.
156  */
157 #define ZONEFS_MNTOPT_ERRORS_RO         (1 << 0) /* Make zone file readonly */
158 #define ZONEFS_MNTOPT_ERRORS_ZRO        (1 << 1) /* Make zone file offline */
159 #define ZONEFS_MNTOPT_ERRORS_ZOL        (1 << 2) /* Make zone file offline */
160 #define ZONEFS_MNTOPT_ERRORS_REPAIR     (1 << 3) /* Remount read-only */
161 #define ZONEFS_MNTOPT_ERRORS_MASK       \
162         (ZONEFS_MNTOPT_ERRORS_RO | ZONEFS_MNTOPT_ERRORS_ZRO | \
163          ZONEFS_MNTOPT_ERRORS_ZOL | ZONEFS_MNTOPT_ERRORS_REPAIR)
164 #define ZONEFS_MNTOPT_EXPLICIT_OPEN     (1 << 4) /* Explicit open/close of zones on open/close */
165
166 /*
167  * In-memory Super block information.
168  */
169 struct zonefs_sb_info {
170
171         unsigned long           s_mount_opts;
172
173         spinlock_t              s_lock;
174
175         unsigned long long      s_features;
176         kuid_t                  s_uid;
177         kgid_t                  s_gid;
178         umode_t                 s_perm;
179         uuid_t                  s_uuid;
180         unsigned int            s_zone_sectors_shift;
181
182         unsigned int            s_nr_files[ZONEFS_ZTYPE_MAX];
183
184         loff_t                  s_blocks;
185         loff_t                  s_used_blocks;
186
187         unsigned int            s_max_wro_seq_files;
188         atomic_t                s_wro_seq_files;
189
190         unsigned int            s_max_active_seq_files;
191         atomic_t                s_active_seq_files;
192
193         bool                    s_sysfs_registered;
194         struct kobject          s_kobj;
195         struct completion       s_kobj_unregister;
196 };
197
198 static inline struct zonefs_sb_info *ZONEFS_SB(struct super_block *sb)
199 {
200         return sb->s_fs_info;
201 }
202
203 #define zonefs_info(sb, format, args...)        \
204         pr_info("zonefs (%s): " format, sb->s_id, ## args)
205 #define zonefs_err(sb, format, args...)         \
206         pr_err("zonefs (%s) ERROR: " format, sb->s_id, ## args)
207 #define zonefs_warn(sb, format, args...)        \
208         pr_warn("zonefs (%s) WARNING: " format, sb->s_id, ## args)
209
210 int zonefs_sysfs_register(struct super_block *sb);
211 void zonefs_sysfs_unregister(struct super_block *sb);
212 int zonefs_sysfs_init(void);
213 void zonefs_sysfs_exit(void);
214
215 #endif