Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Simple zone file system for zoned block devices.
0004  *
0005  * Copyright (C) 2019 Western Digital Corporation or its affiliates.
0006  */
0007 #ifndef __ZONEFS_H__
0008 #define __ZONEFS_H__
0009 
0010 #include <linux/fs.h>
0011 #include <linux/magic.h>
0012 #include <linux/uuid.h>
0013 #include <linux/mutex.h>
0014 #include <linux/rwsem.h>
0015 #include <linux/kobject.h>
0016 
0017 /*
0018  * Maximum length of file names: this only needs to be large enough to fit
0019  * the zone group directory names and a decimal zone number for file names.
0020  * 16 characters is plenty.
0021  */
0022 #define ZONEFS_NAME_MAX     16
0023 
0024 /*
0025  * Zone types: ZONEFS_ZTYPE_SEQ is used for all sequential zone types
0026  * defined in linux/blkzoned.h, that is, BLK_ZONE_TYPE_SEQWRITE_REQ and
0027  * BLK_ZONE_TYPE_SEQWRITE_PREF.
0028  */
0029 enum zonefs_ztype {
0030     ZONEFS_ZTYPE_CNV,
0031     ZONEFS_ZTYPE_SEQ,
0032     ZONEFS_ZTYPE_MAX,
0033 };
0034 
0035 static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
0036 {
0037     if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
0038         return ZONEFS_ZTYPE_CNV;
0039     return ZONEFS_ZTYPE_SEQ;
0040 }
0041 
0042 #define ZONEFS_ZONE_OPEN    (1 << 0)
0043 #define ZONEFS_ZONE_ACTIVE  (1 << 1)
0044 
0045 /*
0046  * In-memory inode data.
0047  */
0048 struct zonefs_inode_info {
0049     struct inode        i_vnode;
0050 
0051     /* File zone type */
0052     enum zonefs_ztype   i_ztype;
0053 
0054     /* File zone start sector (512B unit) */
0055     sector_t        i_zsector;
0056 
0057     /* File zone write pointer position (sequential zones only) */
0058     loff_t          i_wpoffset;
0059 
0060     /* File maximum size */
0061     loff_t          i_max_size;
0062 
0063     /* File zone size */
0064     loff_t          i_zone_size;
0065 
0066     /*
0067      * To serialise fully against both syscall and mmap based IO and
0068      * sequential file truncation, two locks are used. For serializing
0069      * zonefs_seq_file_truncate() against zonefs_iomap_begin(), that is,
0070      * file truncate operations against block mapping, i_truncate_mutex is
0071      * used. i_truncate_mutex also protects against concurrent accesses
0072      * and changes to the inode private data, and in particular changes to
0073      * a sequential file size on completion of direct IO writes.
0074      * Serialization of mmap read IOs with truncate and syscall IO
0075      * operations is done with invalidate_lock in addition to
0076      * i_truncate_mutex.  Only zonefs_seq_file_truncate() takes both lock
0077      * (invalidate_lock first, i_truncate_mutex second).
0078      */
0079     struct mutex        i_truncate_mutex;
0080 
0081     /* guarded by i_truncate_mutex */
0082     unsigned int        i_wr_refcnt;
0083     unsigned int        i_flags;
0084 };
0085 
0086 static inline struct zonefs_inode_info *ZONEFS_I(struct inode *inode)
0087 {
0088     return container_of(inode, struct zonefs_inode_info, i_vnode);
0089 }
0090 
0091 /*
0092  * On-disk super block (block 0).
0093  */
0094 #define ZONEFS_LABEL_LEN    64
0095 #define ZONEFS_UUID_SIZE    16
0096 #define ZONEFS_SUPER_SIZE   4096
0097 
0098 struct zonefs_super {
0099 
0100     /* Magic number */
0101     __le32      s_magic;
0102 
0103     /* Checksum */
0104     __le32      s_crc;
0105 
0106     /* Volume label */
0107     char        s_label[ZONEFS_LABEL_LEN];
0108 
0109     /* 128-bit uuid */
0110     __u8        s_uuid[ZONEFS_UUID_SIZE];
0111 
0112     /* Features */
0113     __le64      s_features;
0114 
0115     /* UID/GID to use for files */
0116     __le32      s_uid;
0117     __le32      s_gid;
0118 
0119     /* File permissions */
0120     __le32      s_perm;
0121 
0122     /* Padding to ZONEFS_SUPER_SIZE bytes */
0123     __u8        s_reserved[3988];
0124 
0125 } __packed;
0126 
0127 /*
0128  * Feature flags: specified in the s_features field of the on-disk super
0129  * block struct zonefs_super and in-memory in the s_feartures field of
0130  * struct zonefs_sb_info.
0131  */
0132 enum zonefs_features {
0133     /*
0134      * Aggregate contiguous conventional zones into a single file.
0135      */
0136     ZONEFS_F_AGGRCNV = 1ULL << 0,
0137     /*
0138      * Use super block specified UID for files instead of default 0.
0139      */
0140     ZONEFS_F_UID = 1ULL << 1,
0141     /*
0142      * Use super block specified GID for files instead of default 0.
0143      */
0144     ZONEFS_F_GID = 1ULL << 2,
0145     /*
0146      * Use super block specified file permissions instead of default 640.
0147      */
0148     ZONEFS_F_PERM = 1ULL << 3,
0149 };
0150 
0151 #define ZONEFS_F_DEFINED_FEATURES \
0152     (ZONEFS_F_AGGRCNV | ZONEFS_F_UID | ZONEFS_F_GID | ZONEFS_F_PERM)
0153 
0154 /*
0155  * Mount options for zone write pointer error handling.
0156  */
0157 #define ZONEFS_MNTOPT_ERRORS_RO     (1 << 0) /* Make zone file readonly */
0158 #define ZONEFS_MNTOPT_ERRORS_ZRO    (1 << 1) /* Make zone file offline */
0159 #define ZONEFS_MNTOPT_ERRORS_ZOL    (1 << 2) /* Make zone file offline */
0160 #define ZONEFS_MNTOPT_ERRORS_REPAIR (1 << 3) /* Remount read-only */
0161 #define ZONEFS_MNTOPT_ERRORS_MASK   \
0162     (ZONEFS_MNTOPT_ERRORS_RO | ZONEFS_MNTOPT_ERRORS_ZRO | \
0163      ZONEFS_MNTOPT_ERRORS_ZOL | ZONEFS_MNTOPT_ERRORS_REPAIR)
0164 #define ZONEFS_MNTOPT_EXPLICIT_OPEN (1 << 4) /* Explicit open/close of zones on open/close */
0165 
0166 /*
0167  * In-memory Super block information.
0168  */
0169 struct zonefs_sb_info {
0170 
0171     unsigned long       s_mount_opts;
0172 
0173     spinlock_t      s_lock;
0174 
0175     unsigned long long  s_features;
0176     kuid_t          s_uid;
0177     kgid_t          s_gid;
0178     umode_t         s_perm;
0179     uuid_t          s_uuid;
0180     unsigned int        s_zone_sectors_shift;
0181 
0182     unsigned int        s_nr_files[ZONEFS_ZTYPE_MAX];
0183 
0184     loff_t          s_blocks;
0185     loff_t          s_used_blocks;
0186 
0187     unsigned int        s_max_wro_seq_files;
0188     atomic_t        s_wro_seq_files;
0189 
0190     unsigned int        s_max_active_seq_files;
0191     atomic_t        s_active_seq_files;
0192 
0193     bool            s_sysfs_registered;
0194     struct kobject      s_kobj;
0195     struct completion   s_kobj_unregister;
0196 };
0197 
0198 static inline struct zonefs_sb_info *ZONEFS_SB(struct super_block *sb)
0199 {
0200     return sb->s_fs_info;
0201 }
0202 
0203 #define zonefs_info(sb, format, args...)    \
0204     pr_info("zonefs (%s): " format, sb->s_id, ## args)
0205 #define zonefs_err(sb, format, args...)     \
0206     pr_err("zonefs (%s) ERROR: " format, sb->s_id, ## args)
0207 #define zonefs_warn(sb, format, args...)    \
0208     pr_warn("zonefs (%s) WARNING: " format, sb->s_id, ## args)
0209 
0210 int zonefs_sysfs_register(struct super_block *sb);
0211 void zonefs_sysfs_unregister(struct super_block *sb);
0212 int zonefs_sysfs_init(void);
0213 void zonefs_sysfs_exit(void);
0214 
0215 #endif