adfs.h 4.9 KB
Newer Older
A
Al Viro 已提交
1 2 3
#include <linux/fs.h>
#include <linux/adfs_fs.h>

L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* Internal data structures for ADFS */

#define ADFS_FREE_FRAG		 0
#define ADFS_BAD_FRAG		 1
#define ADFS_ROOT_FRAG		 2

#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)

#include "dir_f.h"

struct buffer_head;

A
Al Viro 已提交
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
/*
 * adfs file system inode data in memory
 */
struct adfs_inode_info {
	loff_t		mmu_private;
	unsigned long	parent_id;	/* object id of parent		*/
	__u32		loadaddr;	/* RISC OS load address		*/
	__u32		execaddr;	/* RISC OS exec address		*/
	unsigned int	filetype;	/* RISC OS file type		*/
	unsigned int	attr;		/* RISC OS permissions		*/
	unsigned int	stamped:1;	/* RISC OS file has date/time	*/
	struct inode vfs_inode;
};

/*
 * Forward-declare this
 */
struct adfs_discmap;
struct adfs_dir_ops;

/*
 * ADFS file system superblock data in memory
 */
struct adfs_sb_info {
	struct adfs_discmap *s_map;	/* bh list containing map		 */
	struct adfs_dir_ops *s_dir;	/* directory operations			 */

	uid_t		s_uid;		/* owner uid				 */
	gid_t		s_gid;		/* owner gid				 */
	umode_t		s_owner_mask;	/* ADFS owner perm -> unix perm		 */
	umode_t		s_other_mask;	/* ADFS other perm -> unix perm		 */

	__u32		s_ids_per_zone;	/* max. no ids in one zone		 */
	__u32		s_idlen;	/* length of ID in map			 */
	__u32		s_map_size;	/* sector size of a map			 */
	unsigned long	s_size;		/* total size (in blocks) of this fs	 */
	signed int	s_map2blk;	/* shift left by this for map->sector	 */
	unsigned int	s_log2sharesize;/* log2 share size			 */
	__le32		s_version;	/* disc format version			 */
	unsigned int	s_namelen;	/* maximum number of characters in name	 */
};

static inline struct adfs_sb_info *ADFS_SB(struct super_block *sb)
{
	return sb->s_fs_info;
}

static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
{
	return container_of(inode, struct adfs_inode_info, vfs_inode);
}

L
Linus Torvalds 已提交
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
/*
 * Directory handling
 */
struct adfs_dir {
	struct super_block	*sb;

	int			nr_buffers;
	struct buffer_head	*bh[4];
	unsigned int		pos;
	unsigned int		parent_id;

	struct adfs_dirheader	dirhead;
	union  adfs_dirtail	dirtail;
};

/*
 * This is the overall maximum name length
 */
#define ADFS_MAX_NAME_LEN	256
struct object_info {
	__u32		parent_id;		/* parent object id	*/
	__u32		file_id;		/* object id		*/
	__u32		loadaddr;		/* load address		*/
	__u32		execaddr;		/* execution address	*/
	__u32		size;			/* size			*/
	__u8		attr;			/* RISC OS attributes	*/
	unsigned char	name_len;		/* name length		*/
	char		name[ADFS_MAX_NAME_LEN];/* file name		*/
};

struct adfs_dir_ops {
	int	(*read)(struct super_block *sb, unsigned int id, unsigned int sz, struct adfs_dir *dir);
	int	(*setpos)(struct adfs_dir *dir, unsigned int fpos);
	int	(*getnext)(struct adfs_dir *dir, struct object_info *obj);
	int	(*update)(struct adfs_dir *dir, struct object_info *obj);
	int	(*create)(struct adfs_dir *dir, struct object_info *obj);
	int	(*remove)(struct adfs_dir *dir, struct object_info *obj);
111
	int	(*sync)(struct adfs_dir *dir);
L
Linus Torvalds 已提交
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	void	(*free)(struct adfs_dir *dir);
};

struct adfs_discmap {
	struct buffer_head	*dm_bh;
	__u32			dm_startblk;
	unsigned int		dm_startbit;
	unsigned int		dm_endbit;
};

/* Inode stuff */
struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
int adfs_write_inode(struct inode *inode,int unused);
int adfs_notify_change(struct dentry *dentry, struct iattr *attr);

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

/* Misc */
void __adfs_error(struct super_block *sb, const char *function,
		  const char *fmt, ...);
134
#define adfs_error(sb, fmt...) __adfs_error(sb, __func__, fmt)
L
Linus Torvalds 已提交
135 136 137 138 139 140 141 142

/* super.c */

/*
 * Inodes and file operations
 */

/* dir_*.c */
143
extern const struct inode_operations adfs_dir_inode_operations;
144
extern const struct file_operations adfs_dir_operations;
145
extern const struct dentry_operations adfs_dentry_operations;
L
Linus Torvalds 已提交
146 147 148
extern struct adfs_dir_ops adfs_f_dir_ops;
extern struct adfs_dir_ops adfs_fplus_dir_ops;

149 150
extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
			   int wait);
L
Linus Torvalds 已提交
151 152

/* file.c */
153
extern const struct inode_operations adfs_file_inode_operations;
154
extern const struct file_operations adfs_file_operations;
L
Linus Torvalds 已提交
155

156
static inline __u32 signed_asl(__u32 val, signed int shift)
L
Linus Torvalds 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170
{
	if (shift >= 0)
		val <<= shift;
	else
		val >>= -shift;
	return val;
}

/*
 * Calculate the address of a block in an object given the block offset
 * and the object identity.
 *
 * The root directory ID should always be looked up in the map [3.4]
 */
171
static inline int
L
Linus Torvalds 已提交
172 173 174 175 176 177 178 179 180 181 182 183
__adfs_block_map(struct super_block *sb, unsigned int object_id,
		 unsigned int block)
{
	if (object_id & 255) {
		unsigned int off;

		off = (object_id & 255) - 1;
		block += off << ADFS_SB(sb)->s_log2sharesize;
	}

	return adfs_map_lookup(sb, object_id >> 8, block);
}