Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/fs/affs/affs.h
26278 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifdef pr_fmt
3
#undef pr_fmt
4
#endif
5
6
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7
8
#include <linux/types.h>
9
#include <linux/fs.h>
10
#include <linux/buffer_head.h>
11
#include "amigaffs.h"
12
#include <linux/mutex.h>
13
#include <linux/workqueue.h>
14
15
/* Ugly macros make the code more pretty. */
16
17
#define AFFS_BLOCK(sb, bh, blk) (AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)])
18
19
#define AFFS_HEAD(bh) ((struct affs_head *)(bh)->b_data)
20
#define AFFS_TAIL(sb, bh) ((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail)))
21
#define AFFS_ROOT_HEAD(bh) ((struct affs_root_head *)(bh)->b_data)
22
#define AFFS_ROOT_TAIL(sb, bh) ((struct affs_root_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_root_tail)))
23
#define AFFS_DATA_HEAD(bh) ((struct affs_data_head *)(bh)->b_data)
24
#define AFFS_DATA(bh) (((struct affs_data_head *)(bh)->b_data)->data)
25
26
#define AFFS_CACHE_SIZE PAGE_SIZE
27
28
#define AFFS_LC_SIZE (AFFS_CACHE_SIZE/sizeof(u32)/2)
29
#define AFFS_AC_SIZE (AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2)
30
#define AFFS_AC_MASK (AFFS_AC_SIZE-1)
31
32
#define AFFSNAMEMAX 30U
33
34
struct affs_ext_key {
35
u32 ext; /* idx of the extended block */
36
u32 key; /* block number */
37
};
38
39
/*
40
* affs fs inode data in memory
41
*/
42
struct affs_inode_info {
43
atomic_t i_opencnt;
44
struct mutex i_link_lock; /* Protects internal inode access. */
45
struct mutex i_ext_lock; /* Protects internal inode access. */
46
#define i_hash_lock i_ext_lock
47
u32 i_blkcnt; /* block count */
48
u32 i_extcnt; /* extended block count */
49
u32 *i_lc; /* linear cache of extended blocks */
50
u32 i_lc_size;
51
u32 i_lc_shift;
52
u32 i_lc_mask;
53
struct affs_ext_key *i_ac; /* associative cache of extended blocks */
54
u32 i_ext_last; /* last accessed extended block */
55
struct buffer_head *i_ext_bh; /* bh of last extended block */
56
loff_t mmu_private;
57
u32 i_protect; /* unused attribute bits */
58
u32 i_lastalloc; /* last allocated block */
59
int i_pa_cnt; /* number of preallocated blocks */
60
struct inode vfs_inode;
61
};
62
63
/* short cut to get to the affs specific inode data */
64
static inline struct affs_inode_info *AFFS_I(struct inode *inode)
65
{
66
return container_of(inode, struct affs_inode_info, vfs_inode);
67
}
68
69
/*
70
* super-block data in memory
71
*
72
* Block numbers are adjusted for their actual size
73
*
74
*/
75
76
struct affs_bm_info {
77
u32 bm_key; /* Disk block number */
78
u32 bm_free; /* Free blocks in here */
79
};
80
81
struct affs_sb_info {
82
int s_partition_size; /* Partition size in blocks. */
83
int s_reserved; /* Number of reserved blocks. */
84
//u32 s_blksize; /* Initial device blksize */
85
u32 s_data_blksize; /* size of the data block w/o header */
86
u32 s_root_block; /* FFS root block number. */
87
int s_hashsize; /* Size of hash table. */
88
unsigned long s_flags; /* See below. */
89
kuid_t s_uid; /* uid to override */
90
kgid_t s_gid; /* gid to override */
91
umode_t s_mode; /* mode to override */
92
struct buffer_head *s_root_bh; /* Cached root block. */
93
struct mutex s_bmlock; /* Protects bitmap access. */
94
struct affs_bm_info *s_bitmap; /* Bitmap infos. */
95
u32 s_bmap_count; /* # of bitmap blocks. */
96
u32 s_bmap_bits; /* # of bits in one bitmap blocks */
97
u32 s_last_bmap;
98
struct buffer_head *s_bmap_bh;
99
char *s_prefix; /* Prefix for volumes and assigns. */
100
char s_volume[32]; /* Volume prefix for absolute symlinks. */
101
spinlock_t symlink_lock; /* protects the previous two */
102
struct super_block *sb; /* the VFS superblock object */
103
int work_queued; /* non-zero delayed work is queued */
104
struct delayed_work sb_work; /* superblock flush delayed work */
105
spinlock_t work_lock; /* protects sb_work and work_queued */
106
struct rcu_head rcu;
107
};
108
109
#define AFFS_MOUNT_SF_INTL 0x0001 /* International filesystem. */
110
#define AFFS_MOUNT_SF_BM_VALID 0x0002 /* Bitmap is valid. */
111
#define AFFS_MOUNT_SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */
112
#define AFFS_MOUNT_SF_QUIET 0x0008 /* chmod errors will be not reported */
113
#define AFFS_MOUNT_SF_SETUID 0x0010 /* Ignore Amiga uid */
114
#define AFFS_MOUNT_SF_SETGID 0x0020 /* Ignore Amiga gid */
115
#define AFFS_MOUNT_SF_SETMODE 0x0040 /* Ignore Amiga protection bits */
116
#define AFFS_MOUNT_SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */
117
#define AFFS_MOUNT_SF_OFS 0x0200 /* Old filesystem */
118
#define AFFS_MOUNT_SF_PREFIX 0x0400 /* Buffer for prefix is allocated */
119
#define AFFS_MOUNT_SF_VERBOSE 0x0800 /* Talk about fs when mounting */
120
#define AFFS_MOUNT_SF_NO_TRUNCATE 0x1000 /* Don't truncate filenames */
121
122
#define affs_clear_opt(o, opt) (o &= ~AFFS_MOUNT_##opt)
123
#define affs_set_opt(o, opt) (o |= AFFS_MOUNT_##opt)
124
#define affs_test_opt(o, opt) ((o) & AFFS_MOUNT_##opt)
125
126
/* short cut to get to the affs specific sb data */
127
static inline struct affs_sb_info *AFFS_SB(struct super_block *sb)
128
{
129
return sb->s_fs_info;
130
}
131
132
void affs_mark_sb_dirty(struct super_block *sb);
133
134
/* amigaffs.c */
135
136
extern int affs_insert_hash(struct inode *inode, struct buffer_head *bh);
137
extern int affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh);
138
extern int affs_remove_header(struct dentry *dentry);
139
extern u32 affs_checksum_block(struct super_block *sb, struct buffer_head *bh);
140
extern void affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
141
extern void affs_secs_to_datestamp(time64_t secs, struct affs_date *ds);
142
extern umode_t affs_prot_to_mode(u32 prot);
143
extern void affs_mode_to_prot(struct inode *inode);
144
__printf(3, 4)
145
extern void affs_error(struct super_block *sb, const char *function,
146
const char *fmt, ...);
147
__printf(3, 4)
148
extern void affs_warning(struct super_block *sb, const char *function,
149
const char *fmt, ...);
150
extern bool affs_nofilenametruncate(const struct dentry *dentry);
151
extern int affs_check_name(const unsigned char *name, int len,
152
bool notruncate);
153
extern int affs_copy_name(unsigned char *bstr, struct dentry *dentry);
154
155
/* bitmap. c */
156
157
extern u32 affs_count_free_blocks(struct super_block *s);
158
extern void affs_free_block(struct super_block *sb, u32 block);
159
extern u32 affs_alloc_block(struct inode *inode, u32 goal);
160
extern int affs_init_bitmap(struct super_block *sb, int *flags);
161
extern void affs_free_bitmap(struct super_block *sb);
162
163
/* namei.c */
164
165
extern const struct export_operations affs_export_ops;
166
extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
167
extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int);
168
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
169
extern int affs_create(struct mnt_idmap *idmap, struct inode *dir,
170
struct dentry *dentry, umode_t mode, bool);
171
extern struct dentry *affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
172
struct dentry *dentry, umode_t mode);
173
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
174
extern int affs_link(struct dentry *olddentry, struct inode *dir,
175
struct dentry *dentry);
176
extern int affs_symlink(struct mnt_idmap *idmap,
177
struct inode *dir, struct dentry *dentry,
178
const char *symname);
179
extern int affs_rename2(struct mnt_idmap *idmap,
180
struct inode *old_dir, struct dentry *old_dentry,
181
struct inode *new_dir, struct dentry *new_dentry,
182
unsigned int flags);
183
184
/* inode.c */
185
186
extern struct inode *affs_new_inode(struct inode *dir);
187
extern int affs_notify_change(struct mnt_idmap *idmap,
188
struct dentry *dentry, struct iattr *attr);
189
extern void affs_evict_inode(struct inode *inode);
190
extern struct inode *affs_iget(struct super_block *sb,
191
unsigned long ino);
192
extern int affs_write_inode(struct inode *inode,
193
struct writeback_control *wbc);
194
extern int affs_add_entry(struct inode *dir, struct inode *inode,
195
struct dentry *dentry, s32 type);
196
197
/* file.c */
198
199
void affs_free_prealloc(struct inode *inode);
200
extern void affs_truncate(struct inode *);
201
int affs_file_fsync(struct file *, loff_t, loff_t, int);
202
203
/* dir.c */
204
205
extern void affs_dir_truncate(struct inode *);
206
207
/* jump tables */
208
209
extern const struct inode_operations affs_file_inode_operations;
210
extern const struct inode_operations affs_dir_inode_operations;
211
extern const struct inode_operations affs_symlink_inode_operations;
212
extern const struct file_operations affs_file_operations;
213
extern const struct file_operations affs_file_operations_ofs;
214
extern const struct file_operations affs_dir_operations;
215
extern const struct address_space_operations affs_symlink_aops;
216
extern const struct address_space_operations affs_aops;
217
extern const struct address_space_operations affs_aops_ofs;
218
219
extern const struct dentry_operations affs_dentry_operations;
220
extern const struct dentry_operations affs_intl_dentry_operations;
221
222
static inline bool affs_validblock(struct super_block *sb, int block)
223
{
224
return(block >= AFFS_SB(sb)->s_reserved &&
225
block < AFFS_SB(sb)->s_partition_size);
226
}
227
228
static inline void
229
affs_set_blocksize(struct super_block *sb, int size)
230
{
231
sb_set_blocksize(sb, size);
232
}
233
static inline struct buffer_head *
234
affs_bread(struct super_block *sb, int block)
235
{
236
pr_debug("%s: %d\n", __func__, block);
237
if (affs_validblock(sb, block))
238
return sb_bread(sb, block);
239
return NULL;
240
}
241
static inline struct buffer_head *
242
affs_getblk(struct super_block *sb, int block)
243
{
244
pr_debug("%s: %d\n", __func__, block);
245
if (affs_validblock(sb, block))
246
return sb_getblk(sb, block);
247
return NULL;
248
}
249
static inline struct buffer_head *
250
affs_getzeroblk(struct super_block *sb, int block)
251
{
252
struct buffer_head *bh;
253
pr_debug("%s: %d\n", __func__, block);
254
if (affs_validblock(sb, block)) {
255
bh = sb_getblk(sb, block);
256
lock_buffer(bh);
257
memset(bh->b_data, 0 , sb->s_blocksize);
258
set_buffer_uptodate(bh);
259
unlock_buffer(bh);
260
return bh;
261
}
262
return NULL;
263
}
264
static inline struct buffer_head *
265
affs_getemptyblk(struct super_block *sb, int block)
266
{
267
struct buffer_head *bh;
268
pr_debug("%s: %d\n", __func__, block);
269
if (affs_validblock(sb, block)) {
270
bh = sb_getblk(sb, block);
271
wait_on_buffer(bh);
272
set_buffer_uptodate(bh);
273
return bh;
274
}
275
return NULL;
276
}
277
static inline void
278
affs_brelse(struct buffer_head *bh)
279
{
280
if (bh)
281
pr_debug("%s: %lld\n", __func__, (long long) bh->b_blocknr);
282
brelse(bh);
283
}
284
285
static inline void
286
affs_adjust_checksum(struct buffer_head *bh, u32 val)
287
{
288
u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[5]);
289
((__be32 *)bh->b_data)[5] = cpu_to_be32(tmp - val);
290
}
291
static inline void
292
affs_adjust_bitmapchecksum(struct buffer_head *bh, u32 val)
293
{
294
u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[0]);
295
((__be32 *)bh->b_data)[0] = cpu_to_be32(tmp - val);
296
}
297
298
static inline void
299
affs_lock_link(struct inode *inode)
300
{
301
mutex_lock(&AFFS_I(inode)->i_link_lock);
302
}
303
static inline void
304
affs_unlock_link(struct inode *inode)
305
{
306
mutex_unlock(&AFFS_I(inode)->i_link_lock);
307
}
308
static inline void
309
affs_lock_dir(struct inode *inode)
310
{
311
mutex_lock_nested(&AFFS_I(inode)->i_hash_lock, SINGLE_DEPTH_NESTING);
312
}
313
static inline void
314
affs_unlock_dir(struct inode *inode)
315
{
316
mutex_unlock(&AFFS_I(inode)->i_hash_lock);
317
}
318
static inline void
319
affs_lock_ext(struct inode *inode)
320
{
321
mutex_lock(&AFFS_I(inode)->i_ext_lock);
322
}
323
static inline void
324
affs_unlock_ext(struct inode *inode)
325
{
326
mutex_unlock(&AFFS_I(inode)->i_ext_lock);
327
}
328
329