summaryrefslogtreecommitdiffstats
path: root/include/linux/adfs_fs_fs.h
blob: 7fff6be19fb67926f958d6598a62c06b785c2938 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef _ADFS_FS_H
#define _ADFS_FS_H

#include <linux/types.h>
/*
 * Structures of data on the disk
 */

/*
 * Disc Record at disc address 0xc00
 */
struct adfs_discrecord {
    unsigned char  log2secsize;
    unsigned char  secspertrack;
    unsigned char  heads;
    unsigned char  density;
    unsigned char  idlen;
    unsigned char  log2bpmb;
    unsigned char  skew;
    unsigned char  bootoption;
    unsigned char  lowsector;
    unsigned char  nzones;
    unsigned short zone_spare;
    unsigned long  root;
    unsigned long  disc_size;
    unsigned short disc_id;
    unsigned char  disc_name[10];
    unsigned long  disc_type;
    unsigned long  disc_size_high;
    unsigned char  log2sharesize:4;
    unsigned char  unused:4;
    unsigned char  big_flag:1;
};

#define ADFS_DISCRECORD		(0xc00)
#define ADFS_DR_OFFSET		(0x1c0)
#define ADFS_DR_SIZE		 60
#define ADFS_SUPER_MAGIC	 0xadf5
#define ADFS_FREE_FRAG		 0
#define ADFS_BAD_FRAG		 1
#define ADFS_ROOT_FRAG		 2

/*
 * Directory header
 */
struct adfs_dirheader {
	unsigned char startmasseq;
	unsigned char startname[4];
};

#define ADFS_NEWDIR_SIZE	2048
#define ADFS_OLDDIR_SIZE	1024
#define ADFS_NUM_DIR_ENTRIES	77

/*
 * Directory entries
 */
struct adfs_direntry {
	char dirobname[10];
#define ADFS_NAME_LEN 10
	__u8 dirload[4];
	__u8 direxec[4];
	__u8 dirlen[4];
	__u8 dirinddiscadd[3];
	__u8 newdiratts;
#define ADFS_NDA_OWNER_READ	(1 << 0)
#define ADFS_NDA_OWNER_WRITE	(1 << 1)
#define ADFS_NDA_LOCKED		(1 << 2)
#define ADFS_NDA_DIRECTORY	(1 << 3)
#define ADFS_NDA_EXECUTE	(1 << 4)
#define ADFS_NDA_PUBLIC_READ	(1 << 5)
#define ADFS_NDA_PUBLIC_WRITE	(1 << 6)
};

#define ADFS_MAX_NAME_LEN	255
struct adfs_idir_entry {
	__u32		inode_no;			/* Address		*/
	__u32		file_id;			/* file id		*/
	__u32		name_len;			/* name length		*/
	__u32		size;				/* size			*/
	__u32		mtime;				/* modification time	*/
	__u32		filetype;			/* RiscOS file type	*/
	__u8		mode;				/* internal mode	*/
	char		name[ADFS_MAX_NAME_LEN];	/* file name		*/
};

/*
 * Directory tail
 */
union adfs_dirtail {
	struct {
		unsigned char dirlastmask;
		char dirname[10];
		unsigned char dirparent[3];
		char dirtitle[19];
		unsigned char reserved[14];
		unsigned char endmasseq;
		unsigned char endname[4];
		unsigned char dircheckbyte;
	} old;
	struct {
		unsigned char dirlastmask;
		unsigned char reserved[2];
		unsigned char dirparent[3];
		char dirtitle[19];
		char dirname[10];
		unsigned char endmasseq;
		unsigned char endname[4];
		unsigned char dircheckbyte;
	} new;
};

#ifdef __KERNEL__
/*
 * Calculate the boot block checksum on an ADFS drive.  Note that this will
 * appear to be correct if the sector contains all zeros, so also check that
 * the disk size is non-zero!!!
 */
extern inline int adfs_checkbblk (unsigned char *ptr)
{
    unsigned int result = 0;
    unsigned char *p = ptr + 511;

    do {
	result = (result & 0xff) + (result >> 8);
	result = result + *--p;
    } while (p != ptr);

    return (result & 0xff) != ptr[511];
}

/* dir.c */
extern unsigned int adfs_val (unsigned char *p, int len);
extern int adfs_dir_read_parent (struct inode *inode, struct buffer_head **bhp);
extern int adfs_dir_read (struct inode *inode, struct buffer_head **bhp);
extern int adfs_dir_check (struct inode *inode, struct buffer_head **bhp,
			   int buffers, union adfs_dirtail *dtp);
extern void adfs_dir_free (struct buffer_head **bhp, int buffers);
extern int adfs_dir_get (struct super_block *sb, struct buffer_head **bhp,
			 int buffers, int pos, unsigned long parent_object_id,
			 struct adfs_idir_entry *ide);
extern int adfs_dir_find_entry (struct super_block *sb, struct buffer_head **bhp,
				int buffers, unsigned int index,
				struct adfs_idir_entry *ide);

/* inode.c */
extern int adfs_inode_validate (struct inode *inode);
extern unsigned long adfs_inode_generate (unsigned long parent_id, int diridx);
extern unsigned long adfs_inode_objid (struct inode *inode);
extern unsigned int adfs_parent_bmap (struct inode *inode, int block);
extern int adfs_bmap (struct inode *inode, int block);
extern void adfs_read_inode (struct inode *inode);

/* map.c */
extern int adfs_map_lookup (struct super_block *sb, int frag_id, int offset);

/* namei.c */
extern int adfs_lookup (struct inode * dir, const char * name, int len,
			struct inode ** result);

/* super.c */
extern int init_adfs_fs (void);
extern void adfs_error (struct super_block *, const char *, const char *, ...);

/*
 * Inodes and file operations
 */

/* dir.c */
extern struct inode_operations adfs_dir_inode_operations;

/* file.c */
extern struct inode_operations adfs_file_inode_operations;
#endif

#endif