aboutsummaryrefslogtreecommitdiff
path: root/core/fs/ufs/ufs.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/fs/ufs/ufs.h')
-rw-r--r--core/fs/ufs/ufs.h254
1 files changed, 254 insertions, 0 deletions
diff --git a/core/fs/ufs/ufs.h b/core/fs/ufs/ufs.h
new file mode 100644
index 0000000..04e9f84
--- /dev/null
+++ b/core/fs/ufs/ufs.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2013 Raphael S. Carvalho <raphael.scarv@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _UFS_H_
+#define _UFS_H_
+
+#include <stdint.h>
+
+/* Sector addresses */
+#define UFS1_SBLOCK_OFFSET 8192
+#define UFS2_SBLOCK_OFFSET 65536
+#define UFS2_SBLOCK2_OFFSET 262144
+
+#define UFS1_ADDR_SHIFT 2
+#define UFS2_ADDR_SHIFT 3
+
+/* Super magic numbers */
+#define UFS1_SUPER_MAGIC (0x011954)
+#define UFS2_SUPER_MAGIC (0x19540119)
+
+#define UFS_ROOT_INODE 2
+
+#define UFS_DIRECT_BLOCKS 12
+#define UFS_INDIRECT_BLOCK 1
+#define UFS_DOUBLE_INDIRECT_BLOCK 1
+#define UFS_TRIPLE_INDIRECT_BLOCK 1
+/* Total number of block addr hold by inodes */
+#define UFS_NBLOCKS 15
+
+/* Blocks span 8 fragments */
+#define FRAGMENTS_PER_BLK 8
+
+/* UFS types */
+typedef enum {
+ NONE,
+ UFS1,
+ UFS2,
+ UFS2_PIGGY,
+} ufs_t;
+
+/*
+ * UFS1/UFS2 SUPERBLOCK structure
+ * CG stands for Cylinder Group.
+ *
+ * Variables prepended with off store offsets relative to
+ * base address of a Cylinder Group (CG).
+ */
+struct ufs_super_block { // supporting either ufs1 or ufs2
+ uint8_t unused[8];
+ /* Offset values */
+ uint32_t off_backup_sb; // Backup super block
+ uint32_t off_group_desc; // Group Descriptor
+ uint32_t off_inode_tbl; // Inode table
+ uint32_t off_data_block; // First data block
+ union {
+ struct { /* Used for UFS1 */
+ uint32_t delta_value; // For calc staggering offset
+ uint32_t cycle_mask; // Mask for staggering offset
+ uint32_t last_written; // Last written time
+ uint32_t nr_frags; // Number of frags in FS
+ uint32_t storable_frags_nr; // Nr of frags that can store data
+ } ufs1;
+ uint8_t unused1[20];
+ };
+ uint32_t nr_cyl_groups; // Number of cylinder groups.
+ uint32_t block_size; // Block size in bytes.
+ uint32_t fragment_size; // Fragment size in bytes.
+ uint8_t unused2[16];
+ uint32_t block_addr_mask; // to calculate the address
+ uint32_t frag_addr_mask;
+ uint32_t block_shift; // to calculate byte address
+ uint32_t frag_shift;
+ uint32_t nr_contiguous_blk; // max number of continuous blks to alloc
+ uint32_t nr_blks_per_cg; // max number of blks per cylinder group
+ uint32_t c_blk_frag_shift; // Bits to convert blk and frag address.
+ uint32_t c_frag_sect_shift; // Bits to convert frag and sect address.
+ uint32_t superblk_size; // Superblock size.
+ uint8_t unused3[76];
+ uint32_t inodes_per_cg; // Inodes per cylinder group
+ uint32_t frags_per_cg; // Fragments per cylinder group
+ union {
+ struct { /* Used for UFS2 */
+ uint8_t unused[888];
+ uint64_t nr_frags; // Number of fragments in FS
+ uint8_t unused1[232];
+ } ufs2;
+ uint8_t unused4[1128];
+ };
+ uint32_t maxlen_isymlink; // Max length of internal symlink
+ uint32_t inodes_format; // Format of inodes
+ uint8_t unused5[44];
+ uint32_t magic; // Magic value
+ uint8_t pad[160]; // padding up to sector (512 bytes) boundary
+} __attribute__((__packed__));
+
+/*
+ * Info about UFS1/2 super block.
+ */
+struct ufs_sb_info {
+ uint32_t blocks_per_cg; // Blocks per cylinder group
+ uint32_t inodes_per_cg; // Inodes per cylinder group
+ uint32_t inode_size;
+ uint32_t inodes_per_block; // Inodes per block
+ struct { /* UFS1 only! */
+ /* Values for calculating staggering offset */
+ uint32_t delta_value;
+ uint32_t cycle_mask;
+ } ufs1;
+ uint32_t off_inode_tbl; // Inode table offset.
+ uint32_t groups_count; // Number of groups in the fs
+ uint32_t addr_shift; // 2 ^ addr_shift = size in bytes of default addr.
+ uint32_t c_blk_frag_shift; // Convert blk/frag addr (vice-versa)
+ uint32_t maxlen_isymlink; // Max length of internal symlink
+ struct inode *(*ufs_iget_by_inr)(struct fs_info *, uint32_t);
+ void (*ufs_read_blkaddrs)(struct inode *, char *);
+ ufs_t fs_type; // { UFS1, UFS2, UFS2_PIGGY }
+};
+
+/*
+ * Get super block info struct
+ */
+static inline struct ufs_sb_info *UFS_SB(struct fs_info *fs)
+{
+ return fs->fs_info;
+}
+
+/*
+ * Convert frag addr to blk addr
+ */
+static inline block_t frag_to_blk(struct fs_info *fs, uint64_t frag)
+{
+ return frag >> UFS_SB(fs)->c_blk_frag_shift;
+}
+
+/*
+ * UFS1 inode structures
+ */
+struct ufs1_inode {
+ uint16_t file_mode;
+ uint16_t link_count;
+ uint8_t unused[4];
+ uint64_t size;
+ uint32_t a_time; // Access time
+ uint32_t a_time_nanosec;
+ uint32_t m_time; // Modified time
+ uint32_t m_time_nanosec;
+ uint32_t ch_time; // Change time
+ uint32_t ch_time_nanosec;
+ uint32_t direct_blk_ptr[12];
+ uint32_t indirect_blk_ptr;
+ uint32_t double_indirect_blk_ptr;
+ uint32_t triple_indirect_blk_ptr;
+ uint32_t flags; // Status flags
+ uint32_t blocks_held; // Blocks held
+ uint32_t generation_nrb; // (NFS)
+ uint32_t used_id;
+ uint32_t group_id;
+ uint8_t unused1[8];
+} __attribute__((__packed__));
+
+/*
+ * UFS2 inode structures
+ */
+struct ufs2_inode {
+ uint16_t file_mode;
+ uint16_t link_count;
+ uint32_t user_id;
+ uint32_t group_id;
+ uint32_t inode_blocksize;
+ uint64_t size;
+ uint64_t bytes_held;
+ uint64_t a_time; // Access time
+ uint64_t m_time; // Modified time
+ uint64_t ch_time; // Change time
+ uint64_t creat_time; // Creation time
+ uint32_t a_time_nanosec;
+ uint32_t m_time_nanosec;
+ uint32_t ch_time_nanosec;
+ uint32_t creat_time_nanosec;
+ uint32_t generation_nrb; // (NFS)
+ uint32_t kernel_flags;
+ uint32_t flags;
+ uint32_t ext_attr_size; // Extended attrib size.
+ uint64_t ext_direct_blk_ptrs[2]; // Ext. attrib blk pointers.
+ uint64_t direct_blk_ptr[12];
+ uint64_t indirect_blk_ptr;
+ uint64_t double_indirect_blk_ptr;
+ uint64_t triple_indirect_blk_ptr;
+ uint8_t unused[24];
+} __attribute__((__packed__));
+
+#define PVT(p) ((struct ufs_inode_pvt *) p->pvt)
+
+struct ufs_inode_pvt {
+ uint64_t direct_blk_ptr[12];
+ uint64_t indirect_blk_ptr;
+ uint64_t double_indirect_blk_ptr;
+ uint64_t triple_indirect_blk_ptr;
+};
+
+struct ufs_dir_entry {
+ uint32_t inode_value;
+ uint16_t dir_entry_len;
+ uint8_t file_type;
+ uint8_t name_length;
+ uint8_t name[1]; // Dir names are null terminated!!!
+} __attribute__((__packed__));
+
+enum inode_type_flags {
+ UFS_INO_FIFO = 0x1000,
+ UFS_INO_CHARDEV = 0x2000,
+ UFS_INO_DIRECTORY = 0x4000,
+ UFS_INO_BLOCKDEV = 0x6000,
+ UFS_INO_RFILE = 0x8000,
+ UFS_INO_SYMLINK = 0xA000,
+ UFS_INO_UNIXSOCKET = 0xC000,
+};
+
+enum dir_type_flags {
+ UFS_DTYPE_UNKNOWN = 0,
+ UFS_DTYPE_FIFO = 1,
+ UFS_DTYPE_CHARDEV = 2,
+ UFS_DTYPE_DIR = 4,
+ UFS_DTYPE_BLOCK = 6,
+ UFS_DTYPE_RFILE = 8,
+ UFS_DTYPE_SYMLINK = 10,
+ UFS_DTYPE_SOCKET = 12,
+ UFS_DTYPE_WHITEOUT = 14,
+};
+
+/* Functions from bmap.c */
+extern uint64_t ufs_bmap (struct inode *, block_t, size_t *);
+extern int ufs_next_extent(struct inode *, uint32_t);
+
+#define ufs_debug dprintf
+//extern void ufs_checking (struct fs_info *);
+
+#endif /* _UFS_H_ */