Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 27558 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.4.21/Documentation/Configure.help (+20 lines)
Lines 15959-15964 Link Here
15959
  say M here and read <file:Documentation/modules.txt>.  If unsure,
15959
  say M here and read <file:Documentation/modules.txt>.  If unsure,
15960
  say N.
15960
  say N.
15961
15961
15962
Amiga SFS file system support
15963
CONFIG_ASFS_FS
15964
  The Amiga Smart FileSystem (SFS) is the file system used on hard 
15965
  disks by Amiga(tm) and MorphOS(tm) systems.  Say Y if you want 
15966
  to be able to read files from an Amiga SFS partition on your hard 
15967
  drive.  
15968
15969
  This file system driver is in EXPERIMENTAL state. Use it with care. 
15970
  Although it CANNOT destroy your data (because it is a read-only 
15971
  driver) it MIGHT cause a crash in some circumstances.
15972
15973
  For more information read <file:Documentation/filesystems/asfs.txt>
15974
15975
  This file system is also available as a module ( = code which can be
15976
  inserted in and removed from the running kernel whenever you want).
15977
  The module is called affs.o.  If you want to compile it as a module,
15978
  say M here and read <file:Documentation/modules.txt>.  
15979
15980
  If unsure, say N.
15981
15962
Apple Macintosh file system support
15982
Apple Macintosh file system support
15963
CONFIG_HFS_FS
15983
CONFIG_HFS_FS
15964
  If you say Y here, you will be able to mount Macintosh-formatted
15984
  If you say Y here, you will be able to mount Macintosh-formatted
(-)linux-2.4.21/Documentation/filesystems/00-INDEX (+2 lines)
Lines 6-11 Link Here
6
	- info and mount options for the Acorn Advanced Disc Filing System.
6
	- info and mount options for the Acorn Advanced Disc Filing System.
7
affs.txt
7
affs.txt
8
	- info and mount options for the Amiga Fast File System.
8
	- info and mount options for the Amiga Fast File System.
9
asfs.txt
10
	- info and mount options for the Amiga Smart File System.
9
befs.txt
11
befs.txt
10
	- info for the BeOS file system (BFS)
12
	- info for the BeOS file system (BFS)
11
bfs.txt
13
bfs.txt
(-)linux-2.4.21/Documentation/filesystems/asfs.txt (+68 lines)
Line 0 Link Here
1
2
Amiga SmartFileSystem, Linux implementation
3
===========================================
4
5
This is a simple read-only driver. It support reading files and directories.
6
Symbolic links (in AmigaOS called soft links) are also supported. Read notes
7
below about symlinks support.
8
9
10
Mount options for the ASFS
11
==========================
12
13
setuid[=uid]	
14
		This sets the owner of all files and directories in the file
15
		system to uid or the uid of the current user, respectively.
16
17
setgid[=gid]	
18
		Same as above, but for gid.
19
20
mode=mode	
21
		Sets the mode flags to the given (octal) value. Directories 
22
		will get an x permission if the corresponding r bit is set.
23
		The default mode is 0444, which means all r bits are set
24
		(for directories this means also that all x bits are set).
25
26
prefix=path	Path will be prefixed to every absolute path name of
27
		symbolic links on an AFFS partition. Default = "/".
28
		(See below.)
29
30
31
Symbolic links
32
==============
33
34
Although the Amiga and Linux file systems resemble each other, there
35
are some, not always subtle, differences. One of them becomes apparent
36
with symbolic links. While Linux has a file system with exactly one
37
root directory, the Amiga has a separate root directory for each
38
file system (for example, partition, floppy disk, ...). With the Amiga,
39
these entities are called "volumes". They have symbolic names which
40
can be used to access them. Thus, symbolic links can point to a
41
different volume. ASFS turns the volume name into a directory name
42
and prepends the prefix path (see prefix option) to it.
43
44
Example:
45
You mount all your Amiga partitions under /amiga/<volume> (where
46
<volume> is the name of the volume), and you give the option
47
"prefix=/amiga/" when mounting all your ASFS or AFFS partitions. (They
48
might be "User", "WB" and "Graphics", the mount points /amiga/User,
49
/amiga/WB and /amiga/Graphics). A symbolic link referring to
50
"User:sc/include/dos/dos.h" will be followed to
51
"/amiga/User/sc/include/dos/dos.h".
52
53
54
Other information
55
=================
56
57
Supported block sizes are: 512, 1024, 2048 and 4096 bytes. Larger blocks
58
speed up almost everything at the expense of wasted disk space. The speed
59
gain above 4K seems not really worth the price, so you don't lose too
60
much here, either.
61
62
This file system hasn't been well tested yet. Athough it CANNOT destroy 
63
your data, it MIGHT cause a crash. Sorry.
64
65
This file system has been tested on Motorola PPC and 68k, as well as 
66
Intel x86 systems. I don't know, if it works on other Linux systems.
67
68
Some parts of this documentation has been adapted from AFFS driver docs.
(-)linux-2.4.21/fs/Config.in (+2 lines)
Lines 17-22 Link Here
17
17
18
dep_tristate 'Amiga FFS file system support (EXPERIMENTAL)' CONFIG_AFFS_FS $CONFIG_EXPERIMENTAL
18
dep_tristate 'Amiga FFS file system support (EXPERIMENTAL)' CONFIG_AFFS_FS $CONFIG_EXPERIMENTAL
19
19
20
dep_tristate 'Amiga SFS file system support (read-only) (EXPERIMENTAL)' CONFIG_ASFS_FS $CONFIG_EXPERIMENTAL
21
20
dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
22
dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
21
23
22
dep_tristate 'BeOS file systemv(BeFS) support (read only) (EXPERIMENTAL)' CONFIG_BEFS_FS $CONFIG_EXPERIMENTAL
24
dep_tristate 'BeOS file systemv(BeFS) support (read only) (EXPERIMENTAL)' CONFIG_BEFS_FS $CONFIG_EXPERIMENTAL
(-)linux-2.4.21/fs/Makefile (+1 lines)
Lines 57-62 Link Here
57
subdir-$(CONFIG_JFFS_FS)	+= jffs
57
subdir-$(CONFIG_JFFS_FS)	+= jffs
58
subdir-$(CONFIG_JFFS2_FS)	+= jffs2
58
subdir-$(CONFIG_JFFS2_FS)	+= jffs2
59
subdir-$(CONFIG_AFFS_FS)	+= affs
59
subdir-$(CONFIG_AFFS_FS)	+= affs
60
subdir-$(CONFIG_ASFS_FS)	+= asfs
60
subdir-$(CONFIG_ROMFS_FS)	+= romfs
61
subdir-$(CONFIG_ROMFS_FS)	+= romfs
61
subdir-$(CONFIG_QNX4FS_FS)	+= qnx4
62
subdir-$(CONFIG_QNX4FS_FS)	+= qnx4
62
subdir-$(CONFIG_UDF_FS)		+= udf
63
subdir-$(CONFIG_UDF_FS)		+= udf
(-)linux-2.4.21/fs/asfs/Makefile (+15 lines)
Line 0 Link Here
1
#
2
# Makefile for the linux asfs filesystem routines.
3
#
4
# Note! Dependencies are done automagically by 'make dep', which also
5
# removes any old dependencies. DON'T put your own dependencies here
6
# unless it's something special (not a .c file).
7
#
8
# Note 2! The CFLAGS definitions are now in the main makefile.
9
10
O_TARGET := asfs.o
11
12
obj-y  := inode.o
13
obj-m  := $(O_TARGET)
14
15
include $(TOPDIR)/Rules.make
(-)linux-2.4.21/fs/asfs/inode.c (+846 lines)
Line 0 Link Here
1
/*
2
 *
3
 * Amiga Smart File System, Linux implementation
4
 *
5
 * version: 0.6 (04.09.2003)
6
 *  
7
 * Copyright (C) 2003  Marek 'March' Szyprowski <marek@amiga.pl>
8
 *
9
 *
10
 * Thanks to Marcin Kurek (Morgoth/Dreamolers-CAPS) for help.
11
 *
12
 * Based on the Linux implementation of the ROMFS file system
13
 * Copyright (C) 1997-1999  Janos Farkas <chexum@shadow.banki.hu>
14
 *
15
 * Using parts of the Amiga FFS filesystem
16
 * Copyright (C) 1993  Ray Burr
17
 * Copyright (C) 1996  Hans-Joachim Widmaier
18
 *
19
 * and parts of the smbfs filesystem additionally
20
 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
21
 * Copyright (C) 1997 by Volker Lendecke
22
 *
23
 *
24
 * This program is free software; you can redistribute it and/or
25
 * modify it under the terms of the GNU General Public License
26
 * as published by the Free Software Foundation; either version
27
 * 2 of the License, or (at your option) any later version.
28
 *
29
 *
30
 * History:
31
 *
32
 * v0.6 (04.09.2003) - final read-only version
33
 * - added support for HashTables, directory scaning should be
34
 *   MUCH faster now
35
 * - added checking of block IDs before reading any data from block
36
 *
37
 * v0.5 (19.07.2003)
38
 * - added simple but effective extent cache - real speed-up 
39
 *   in reading large files
40
 * - added read support for symlinks - based on AFFS symlinks
41
 *
42
 * v0.4 (10.07.2003)
43
 * - third code clean-up (thanks to Roman Zippel for advice)
44
 * - now uses generic readpage and readinode routines
45
 *
46
 * v0.3beta (17.06.2003)
47
 * - second code clean-up
48
 *
49
 * v0.2beta2 (15.06.2003)
50
 * - fixed yet another stupid bug - driver can't read root block on little-endian systems
51
 * v0.2beta (15.06.2003)
52
 * - fixed stupid bug - now files have 'file' flag (S_IFREG) set...
53
 * - added mount options to set uid, gid and mode of files and dirs
54
 * - made hidden files & dirs really hidden (= not listed in directories)
55
 * - code clean-up
56
 *
57
 * v0.1beta (11.06.2003) 
58
 * - after many kernel crashes, finally got it! 
59
 * - first working read-only filesystem driver
60
 *
61
 */
62
63
/* todo:
64
 *	- remove bugs
65
 *	- considering write access...
66
 */
67
68
#include <linux/module.h>
69
#include <linux/types.h>
70
#include <linux/errno.h>
71
#include <linux/slab.h>
72
#include <linux/asfs_fs.h>
73
#include <linux/fs.h>
74
#include <linux/locks.h>
75
#include <linux/init.h>
76
#include <linux/smp_lock.h>
77
78
#include <asm/byteorder.h>
79
#include <asm/uaccess.h>
80
81
static u32 asfs_calcchecksum(struct fsBlockHeader *block, u32 blocksize)
82
{
83
	u32 *data=(void *)block, checksum = 1, tmpchecksum = block->checksum;
84
85
	block->checksum=0;
86
	while(blocksize > 0) {
87
		checksum+=be32_to_cpu(*data++);
88
		blocksize-=4;
89
	}
90
	block->checksum=tmpchecksum;
91
	return(-checksum);
92
}
93
94
static inline int 
95
asfs_check_block(struct fsBlockHeader *block, u32 blocksize, u32 n, u32 id)
96
{
97
	if (asfs_calcchecksum((struct fsBlockHeader *)block, blocksize) == 
98
		be32_to_cpu(((struct fsBlockHeader *)block)->checksum) && 
99
		n == be32_to_cpu(((struct fsBlockHeader *)block)->ownblock) &&
100
		id == be32_to_cpu(((struct fsBlockHeader *)block)->id))
101
		return 1;
102
	return 0;
103
}
104
105
/* get fs structure from block and do some checks... */
106
static int asfs_get_contblock(struct super_block *sb, u32 n, u32 type, void *dest)
107
{
108
	struct buffer_head *bh;
109
110
	bh = sb_bread(sb, n);
111
	if (!bh)
112
		return -1;		/* error */
113
	memcpy(dest, ((char *)bh->b_data), sb->s_blocksize);
114
	brelse(bh);
115
116
	if (asfs_check_block(dest, sb->s_blocksize, n, type)) {
117
		from32be(((struct fsBlockHeader *)dest)->ownblock);
118
		return 1; /* all okay */
119
	}
120
	return -1; /* error */
121
}
122
123
static inline struct inode *asfs_get_root_inode(struct super_block *sb)
124
{
125
	struct inode *result = NULL;
126
	struct fsObjectContainer *block;
127
	struct fsObject *obj;
128
129
	asfs_debug("asfs_get_root_inode\n");
130
131
	block = kmalloc(sb->s_blocksize, GFP_KERNEL);
132
	if (asfs_get_contblock(sb, ASFS_SB->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID, block) < 0)
133
		goto free_and_return;
134
135
	obj = &(block->object[0]);
136
	from32be(obj->objectnode);
137
	from32be(obj->object.dir.firstdirblock);
138
	from32be(obj->object.dir.hashtable);     
139
	from32be(obj->datemodified);
140
141
	if (obj->objectnode > 0)
142
		result = iget4(sb, obj->objectnode, NULL, obj);
143
144
free_and_return:
145
	kfree(block);
146
	return result;
147
}
148
149
static struct super_operations asfs_ops;
150
151
static int asfs_parse_options(char *options, struct super_block *sb)
152
{
153
	char *this_char, *value, *optn;
154
	int f;
155
156
	/* Fill in defaults */
157
	ASFS_SB->uid = ASFS_DEFAULT_UID;
158
	ASFS_SB->gid = ASFS_DEFAULT_GID;
159
	ASFS_SB->mode = ASFS_DEFAULT_MODE;
160
	ASFS_SB->prefix = NULL;
161
162
	if (!options)
163
		return 1;
164
	for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
165
		f = 0;
166
		if ((value = strchr(this_char,'=')) != NULL)
167
			*value++ = 0;
168
		if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
169
			if (value) {
170
				if (!*value) {
171
					printk("ASFS: Argument for set[ug]id option missing\n");
172
					return 0;
173
				} else {
174
					(f ? ASFS_SB->uid : ASFS_SB->gid) = simple_strtoul(value,&value,0);
175
					if (*value) {
176
						printk("ASFS: Bad set[ug]id argument\n");
177
						return 0;
178
					}
179
				}
180
			}
181
		} else if (!strcmp(this_char,"mode")) {
182
			optn = "mode";
183
			if (!value || !*value)
184
				goto out_no_arg;
185
			ASFS_SB->mode = simple_strtoul(value,&value,8) & 0777;
186
			if (*value)
187
				return 0;
188
		} else if (!strcmp(this_char,"prefix")) {
189
			optn = "prefix";
190
			if (!value || !*value)
191
				goto out_no_arg;
192
			ASFS_SB->prefix = kmalloc(strlen(value) + 1,GFP_KERNEL);
193
			if (!ASFS_SB->prefix)
194
				return 0;
195
			strcpy(ASFS_SB->prefix,value);
196
		} else {
197
			printk("ASFS: Unrecognized mount option %s\n", this_char);
198
			return 0;
199
		}
200
	}
201
	return 1;
202
203
out_no_arg:
204
	printk("ASFS: The %s option requires an argument\n", optn);
205
	return 0;
206
}
207
208
static struct super_block *
209
asfs_read_super(struct super_block *sb, void *data, int silent)
210
{
211
	struct buffer_head *bh;
212
	kdev_t dev = sb->s_dev;
213
	struct fsRootBlock *rootblock;
214
215
	if (!asfs_parse_options(data, sb)) {
216
		printk(KERN_ERR "ASFS: Error parsing options\n");
217
		return NULL;
218
	}
219
220
	if (!sb_set_blocksize(sb, 512))
221
		return NULL;
222
	sb->s_maxbytes = 0xFFFFFFFF;
223
224
	bh = sb_bread(sb, 0);
225
	if (!bh) {
226
		printk(KERN_ERR "ASFS: unable to read superblock\n");
227
		goto outnobh;
228
	}
229
230
	rootblock = (struct fsRootBlock *)bh->b_data;
231
232
	if (be32_to_cpu(rootblock->bheader.id) == ASFS_ROOTID && 
233
		be16_to_cpu(rootblock->version) == ASFS_STRUCTURE_VERISON) {
234
235
		sb->s_blocksize = be32_to_cpu(rootblock->blocksize);
236
		ASFS_SB->totalblocks = be32_to_cpu(rootblock->totalblocks);
237
		ASFS_SB->rootobjectcontainer = be32_to_cpu(rootblock->rootobjectcontainer);
238
		ASFS_SB->extentbnoderoot = be32_to_cpu(rootblock->extentbnoderoot);
239
		ASFS_SB->objectnoderoot = be32_to_cpu(rootblock->objectnoderoot);
240
		ASFS_SB->flags = rootblock->bits;
241
		brelse(bh);
242
243
		if (!sb_set_blocksize(sb, sb->s_blocksize)) {
244
			printk(KERN_ERR "ASFS: Found Amiga SFS RootBlock on dev %s, but blocksize %ld is not supported!\n", \
245
			       bdevname(dev), sb->s_blocksize);
246
			return NULL;
247
		}
248
249
		bh = sb_bread(sb, 0);
250
		if (!bh) {
251
			printk(KERN_ERR "ASFS: unable to read superblock\n");
252
			goto out;
253
		}
254
		rootblock = (struct fsRootBlock *)bh->b_data;
255
256
		if (asfs_check_block((void *)rootblock, sb->s_blocksize, 0, ASFS_ROOTID))
257
			printk(KERN_NOTICE "ASFS: Found Amiga SFS RootBlock on dev %s. Checksum okay. Mounting...\n", \
258
			       bdevname(dev));
259
		else {
260
			if (!silent)
261
				printk(KERN_ERR "ASFS: Found Amiga SFS RootBlock on dev %s, but it has checksum error!\n", \
262
				       bdevname(dev));
263
			goto out;
264
		}
265
	} else {
266
		if (!silent)
267
			printk(KERN_ERR "ASFS: Can't find a valid Amiga SFS filesystem on dev %s.\n", \
268
			       bdevname(dev));
269
		goto out;
270
	}
271
272
	brelse(bh);
273
274
	sb->s_magic = ASFS_MAGIC;
275
	sb->s_flags |= MS_RDONLY | MS_NODEV | MS_NOSUID;
276
	sb->s_op = &asfs_ops;
277
	sb->s_root = d_alloc_root(asfs_get_root_inode(sb));
278
	if (!sb->s_root)
279
		goto outnobh;
280
281
	/* Ehrhm; sorry.. :) */
282
	if (0) {
283
out:
284
		brelse(bh);
285
outnobh:
286
		sb = NULL;
287
	}
288
	return sb;
289
}
290
291
static void asfs_put_super(struct super_block *sb)
292
{
293
	if (ASFS_SB->prefix)
294
		kfree(ASFS_SB->prefix);
295
	return;
296
}
297
298
/* That's simple too. */
299
300
static int asfs_statfs(struct super_block *sb, struct statfs *buf)
301
{
302
	buf->f_type = ASFS_MAGIC;
303
	buf->f_bsize = sb->s_blocksize;
304
	buf->f_bfree = buf->f_bavail = buf->f_ffree;
305
	buf->f_blocks = ASFS_SB->totalblocks;
306
	buf->f_namelen = ASFS_MAXFN;
307
	return 0;
308
}
309
310
static int asfs_get_fsObject_varlen(struct fsObject *obj)
311
{
312
	int len, i;
313
	u8 *p = obj->name;
314
	for (i=2; i > 0; p++)
315
		if (*p == '\0')
316
			i--;
317
	len = (p - (u8 *)obj);
318
	if (len & 1)
319
		len++;
320
	return len;
321
}
322
323
static int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
324
{
325
	struct inode *dir = filp->f_dentry->d_inode;
326
	struct super_block *sb = dir->i_sb;
327
	unsigned long f_pos;
328
	int stored = 0;
329
	int obj_skip;
330
331
	struct fsObjectContainer *objcont;
332
	struct fsObject *obj;
333
	int i;
334
	u32 block;
335
336
	asfs_debug("asfs_readdir:\n");
337
338
	if (filp->f_pos == ASFS_SB->totalblocks)
339
		return stored;
340
341
	f_pos = filp->f_pos;
342
343
	if (f_pos == 0) {
344
		filp->private_data = (void *)0;
345
		if (filldir(dirent, ".", 1, f_pos, dir->i_ino, DT_DIR) < 0)
346
			return 0;
347
		filp->f_pos = f_pos = 1;
348
		stored++;
349
	}
350
	if (f_pos == 1) {
351
		if (filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
352
			return stored;
353
		filp->f_pos = f_pos = 2;
354
		stored++;
355
	}
356
357
	if (ASFS_DIR->firstblock == 0) {	/* empty directory */
358
		filp->f_pos = ASFS_SB->totalblocks;
359
		return stored;
360
	}
361
362
	objcont = kmalloc(sb->s_blocksize, GFP_KERNEL);
363
364
	if (f_pos == 2) {	/* reading directory from its beginning */
365
		block = ASFS_DIR->firstblock;
366
		do {
367
			if (asfs_get_contblock(sb, block, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
368
				goto free_and_end;
369
			block = be32_to_cpu(objcont->previous);
370
		} while (block != 0);
371
		obj_skip = 0;
372
	} else {
373
		block = f_pos;
374
		if (asfs_get_contblock(sb, block, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
375
			goto free_and_end;
376
		obj_skip = (int)filp->private_data;
377
	}
378
379
	i=0;
380
	block = objcont->bheader.ownblock;
381
382
	do {
383
		if (i != 0) {
384
			if (asfs_get_contblock(sb, block, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
385
				goto free_and_end;
386
		}
387
388
		i = 0;
389
		obj = &(objcont->object[0]);
390
391
		while (be32_to_cpu(obj->objectnode) > 0 && 
392
		      ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < sb->s_blocksize) {
393
			from32be(obj->objectnode);
394
395
			if (obj_skip > 0) 
396
				obj_skip--;	
397
			else if (!(obj->bits & OTYPE_HIDDEN)) {
398
				unsigned int type;
399
				asfs_debug("ASFS: DirFilling: entry #%d (in_cont: %d) \"%s\" (node %u offset %u), type %d\n", \
400
				           stored, i, obj->name, obj->objectnode, block, obj->bits);
401
				filp->f_pos = block;
402
				if (obj->bits & OTYPE_DIR)
403
					type = DT_DIR;
404
				else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK))
405
					type = DT_LNK;
406
				else
407
					type = DT_REG;
408
				if (filldir(dirent, obj->name, strlen(obj->name), block, obj->objectnode, type) < 0) {
409
					filp->private_data = (void *)i;
410
					asfs_debug("ASFS: DirFilling: to be continued...\n");
411
					goto free_and_end;
412
				}
413
				stored++;
414
			}
415
			obj = (struct fsObject *)((char *)(obj) + asfs_get_fsObject_varlen(obj));
416
			i++;
417
		}
418
		block = be32_to_cpu(objcont->next);
419
420
	} while (block != 0);
421
422
	filp->f_pos = ASFS_SB->totalblocks;
423
424
free_and_end:
425
	kfree(objcont);
426
	return stored;
427
}
428
429
static inline u8 upperchar(u8 c)
430
{
431
	if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z'))
432
		c-=32;
433
	return(c);
434
}
435
436
static int namecmp(u8 *s, u8 *ct, int casesensitive)
437
{
438
	if (casesensitive) {
439
		while (*s == *ct && *ct != '\0' && *ct != '/') {
440
			s++; ct++;
441
		}
442
	} else {
443
		while (upperchar(*s) == upperchar(*ct) && *ct != '\0' && *ct != '/') {
444
			s++; ct++;
445
		}
446
	}
447
	return (*s == '\0' && (*ct == '\0' || *ct == '/')) ? 0 : *ct - *s;
448
}
449
450
#define HASHCHAIN(x) (u16)(x % (u16)(((sb->s_blocksize) - sizeof(struct fsHashTable))>>2))
451
452
static inline u16 hash(u8 *name, int casesensitive)
453
{
454
	u16 hashval=0;
455
	while (name[hashval] != 0 && name[hashval] != '/')
456
		hashval++;
457
	if (casesensitive) {
458
		u8 c = *name;
459
		while (c != 0 && c != '/') {
460
			hashval = hashval*13 + c;
461
			c = *++name;
462
		}
463
	} else {
464
		u8 c = *name;
465
		while (c != 0 && c != '/') {
466
			hashval = hashval*13 + upperchar(c);
467
			c = *++name;
468
		}
469
	}
470
	return hashval;
471
}
472
473
/* Finds a specific node by number. */
474
static struct fsObjectNode *
475
asfs_get_Node(struct super_block *sb, u32 nodeindex, u16 nodesize, u32 nodeno,
476
              struct fsObjectNode *dest_node)
477
{
478
	struct fsNodeContainer *nodecont;
479
	nodecont = kmalloc(sb->s_blocksize, GFP_KERNEL);
480
481
	while (asfs_get_contblock(sb, nodeindex, ASFS_NODECONTAINER_ID, nodecont) > 0) {
482
		if (be32_to_cpu(nodecont->nodes) == 1) {
483
			*dest_node = *((struct fsObjectNode *) ((u8 *) nodecont->node + nodesize * \
484
			             (nodeno - be32_to_cpu(nodecont->nodenumber))));
485
			kfree(nodecont);
486
			from32be(dest_node->node.data);
487
			from32be(dest_node->next);
488
			from16be(dest_node->hash16);
489
			return dest_node;
490
		} else {
491
			u16 containerentry = (nodeno - be32_to_cpu(nodecont->nodenumber)) / 
492
			                     be32_to_cpu(nodecont->nodes);
493
			nodeindex = be32_to_cpu(nodecont->node[containerentry]) >> 
494
			            (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
495
		}
496
	}
497
	kfree(nodecont);
498
	return NULL;
499
}
500
501
struct fsObject *
502
asfs_find_obj_in_cont(struct super_block *sb, struct fsObjectContainer *objcont,
503
                      u8 *name)
504
{
505
	struct fsObject *obj;
506
507
	obj = &(objcont->object[0]);
508
	while (be32_to_cpu(obj->objectnode) > 0 && 
509
	      ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < sb->s_blocksize) {
510
		if (namecmp(obj->name, name, ASFS_SB->flags & ASFS_ROOTBITS_CASESENSITIVE) == 0) {
511
			from32be(obj->objectnode);
512
			/* these two below also convert file.size and file.firstdatablock */
513
			from32be(obj->object.dir.firstdirblock); 
514
			from32be(obj->object.dir.hashtable);     
515
			from32be(obj->datemodified);
516
			asfs_debug("Object found! Node %u, Name %s, Type: %d, inCont %u\n", \
517
			           obj->objectnode, obj->name, obj->bits, objcont->bheader.ownblock);
518
			return obj;
519
		}
520
		obj = (struct fsObject *)((u8 *)(obj) + asfs_get_fsObject_varlen(obj));
521
	}
522
	return NULL;
523
}
524
525
static struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry)
526
{
527
	int res = -EACCES;       /* placeholder for "no data here" */
528
	struct inode *inode;
529
	struct super_block *sb = dir->i_sb;
530
	u8 *name = (u8 *) dentry->d_name.name;
531
	struct fsObjectContainer *objcont;
532
	struct fsObject *obj;
533
	struct fsObjectNode obj_node;
534
	u32 block, node;
535
	u16 hash16;
536
537
	asfs_debug("asfs_lookup: (searching \"%s\"...) ", name);
538
	objcont = kmalloc(dir->i_sb->s_blocksize, GFP_KERNEL);
539
540
	if (ASFS_DIR->hashtable != 0) {	/* hashtable block is available, quick search */
541
542
		if (asfs_get_contblock(sb, ASFS_DIR->hashtable, ASFS_HASHTABLE_ID, objcont) < 0)
543
			goto free_and_error;
544
		hash16 = hash(name, ASFS_SB->flags & ASFS_ROOTBITS_CASESENSITIVE); 
545
		node = be32_to_cpu(((struct fsHashTable *)objcont)->hashentry[HASHCHAIN(hash16)]);
546
547
		while (node != 0) {
548
			if (asfs_get_Node(sb, ASFS_SB->objectnoderoot, sizeof(struct fsObjectNode), 
549
				 node, &obj_node) == NULL)
550
				goto not_found;
551
			if (obj_node.hash16 == hash16) {
552
				if (asfs_get_contblock(sb, obj_node.node.data, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
553
					goto free_and_error;
554
				if ((obj = asfs_find_obj_in_cont(sb, objcont, name)) != NULL)
555
					goto found_inode;
556
			}
557
			node = obj_node.next;
558
		}
559
	} else { /* hashtable not available, long search */
560
561
		block = ASFS_DIR->firstblock;
562
		do {
563
			if (asfs_get_contblock(sb, block, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
564
				goto free_and_error;
565
			block = be32_to_cpu(objcont->previous);
566
		} while (block != 0);
567
		block = objcont->bheader.ownblock;
568
569
		do {
570
			if (block != objcont->bheader.ownblock)
571
				if (asfs_get_contblock(sb, block, ASFS_OBJECTCONTAINER_ID, objcont) < 0)
572
					goto free_and_error;		
573
			if ((obj = asfs_find_obj_in_cont(sb, objcont, name)) != NULL)
574
				goto found_inode;
575
			block = be32_to_cpu(objcont->next);
576
		} while (block != 0);
577
	}
578
579
not_found:
580
	inode = NULL;
581
	asfs_debug("object not found.\n");
582
	if (0) {
583
found_inode:
584
		if (!(inode = iget4(sb, obj->objectnode, NULL, obj))) {
585
			asfs_debug("ASFS: Strange - no inode allocated.\n");
586
			goto free_and_error;
587
		}
588
	}
589
	res = 0;
590
	d_add(dentry, inode);
591
free_and_error:
592
	kfree(objcont);
593
	return ERR_PTR(res);
594
}
595
596
static struct fsExtentBNode *
597
asfs_search_BNodeTree(struct super_block *sb, u32 key, struct fsExtentBNode *dest)
598
{
599
	struct fsBNodeContainer *bnodecont;
600
	struct fsExtentBNode *result = dest;
601
	unsigned long block = ASFS_SB->extentbnoderoot;
602
603
	bnodecont = kmalloc(sb->s_blocksize, GFP_KERNEL);
604
	while (asfs_get_contblock(sb, block, ASFS_BNODECONTAINER_ID, bnodecont) > 0) {
605
		from16be(bnodecont->btc.nodecount);
606
		if (bnodecont->btc.isleaf) {
607
			int i;
608
			struct fsExtentBNode *exbnode;
609
			exbnode = (void *)bnodecont->btc.bnode;
610
			for (i=0; i < bnodecont->btc.nodecount; i++) {
611
				from32be(exbnode->key);
612
				if (exbnode->key == key) {
613
					from32be(exbnode->next);
614
					from32be(exbnode->prev);
615
					from16be(exbnode->blocks);
616
					*dest = *exbnode;
617
					goto found;
618
				}
619
				exbnode = (void *)exbnode + bnodecont->btc.nodesize;
620
			}
621
		} else {
622
			int i;
623
			struct BNode *bnode;
624
			bnode = (void *)bnodecont->btc.bnode;
625
			for (i=0; i < bnodecont->btc.nodecount && key >= be32_to_cpu(bnode->key); i++)
626
				bnode = (void *)bnode + bnodecont->btc.nodesize;
627
628
			bnode = (void *)bnode - bnodecont->btc.nodesize;
629
			block = be32_to_cpu(bnode->data);
630
		}
631
	}
632
	/* read error or key not found */
633
	result = NULL;
634
found:
635
	kfree(bnodecont);
636
	return result;
637
}
638
639
static int
640
asfs_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create)
641
{
642
	struct fsExtentBNode extend;
643
	u32 filedata;
644
	unsigned long pos;
645
646
	asfs_debug("ASFS: get_block(%lu, %ld)\n", inode->i_ino, block);
647
648
	if (block < 0) {
649
		printk(KERN_ERR "ASFS: asfsget_block: requested block (%ld) < 0!\n", block);
650
		return -EIO;
651
	}
652
653
	if (block >= inode->i_blocks) {
654
		printk(KERN_ERR "ASFS: asfsget_block: strange block request %ld!\n", block);
655
		return -EIO;
656
	}
657
658
	if (ASFS_INODE->ext_cache.key > 0 && ASFS_INODE->ext_cache.startblock <= block) {
659
		extend.key = ASFS_INODE->ext_cache.key;
660
		extend.next = ASFS_INODE->ext_cache.next;
661
		extend.blocks = ASFS_INODE->ext_cache.blocks;
662
		pos = ASFS_INODE->ext_cache.startblock;
663
	} else {
664
		if (asfs_search_BNodeTree(inode->i_sb, ASFS_INODE->firstblock, &extend) == NULL)
665
			return -EIO;
666
		pos = 0;
667
	}
668
	filedata = extend.next;
669
670
	while (pos + extend.blocks <= block && extend.next != 0 && pos < inode->i_blocks) {
671
		pos += extend.blocks;
672
		if (asfs_search_BNodeTree(inode->i_sb, filedata, &extend) == NULL)
673
			return -EIO;
674
		filedata = extend.next;
675
	}
676
677
	bh_result->b_blocknr = extend.key + block - pos;
678
	bh_result->b_dev = inode->i_dev;
679
	bh_result->b_state |= (1UL << BH_Mapped);
680
681
	ASFS_INODE->ext_cache.startblock = pos;
682
	ASFS_INODE->ext_cache.key = extend.key;
683
	ASFS_INODE->ext_cache.next = extend.next;
684
	ASFS_INODE->ext_cache.blocks = extend.blocks;
685
686
	return 0;
687
}
688
689
static int asfs_readpage(struct file *file, struct page *page)
690
{
691
	return block_read_full_page(page, asfs_get_block);
692
}
693
static int asfs_bmap(struct address_space *mapping, long block)
694
{
695
	return generic_block_bmap(mapping,block,asfs_get_block);
696
}
697
698
/* Mapping from our types to the kernel */
699
700
static struct address_space_operations asfs_aops = {
701
	.readpage	= asfs_readpage,
702
	.sync_page	= block_sync_page,
703
	.bmap		= asfs_bmap,
704
};
705
706
struct file_operations asfs_file_operations = {
707
	.llseek		= generic_file_llseek,
708
	.read		= generic_file_read,
709
	.mmap		= generic_file_mmap,
710
};
711
712
static struct file_operations asfs_dir_operations = {
713
	.read		= generic_read_dir,
714
	.readdir	= asfs_readdir,
715
};
716
717
static struct inode_operations asfs_dir_inode_operations = {
718
	.lookup		= asfs_lookup,
719
};
720
721
static int asfs_symlink_readpage(struct file *file, struct page *page)
722
{
723
	struct fsSoftLink *slinkcont;
724
	struct inode *inode = page->mapping->host;
725
	struct super_block *sb = inode->i_sb;
726
	char *link = kmap(page);
727
	int i = 0, j = 0;
728
	char c, lc = 0, *pf, *lf;
729
730
	slinkcont = kmalloc(sb->s_blocksize, GFP_KERNEL);
731
732
	if (asfs_get_contblock(sb, ASFS_INODE->firstblock, ASFS_SOFTLINK_ID, slinkcont) < 0)
733
		goto free_and_error;
734
735
	lf = slinkcont->string;
736
	pf = ASFS_SB->prefix ? ASFS_SB->prefix : "/";
737
738
	if (strchr(lf,':')) {	/* Handle assign or volume name */
739
		while (i < 1023 && (c = pf[i]))
740
			link[i++] = c;
741
		while (i < 1023 && lf[j] != ':')
742
			link[i++] = lf[j++];
743
		if (i < 1023)
744
			link[i++] = '/';
745
		j++;
746
		lc = '/';
747
	}
748
	while (i < 1023 && (c = lf[j])) {
749
		if (c == '/' && lc == '/' && i < 1020) {	/* parent dir */
750
			link[i++] = '.';
751
			link[i++] = '.';
752
		}
753
		link[i++] = c;
754
		lc = c;
755
		j++;
756
	}
757
	link[i] = '\0';
758
	SetPageUptodate(page);
759
	kunmap(page);
760
	UnlockPage(page);
761
	kfree(slinkcont);
762
	return 0;
763
free_and_error:
764
	kfree(slinkcont);
765
	SetPageError(page);
766
	kunmap(page);
767
	UnlockPage(page);
768
	return -EIO;
769
}
770
771
static struct address_space_operations asfs_symlink_aops = {
772
	.readpage	= asfs_symlink_readpage,
773
};
774
775
static void asfs_read_inode2(struct inode *inode, void *arg)
776
{
777
	struct super_block *sb = inode->i_sb;
778
	struct fsObject *obj = arg;
779
780
	inode->i_mode = ASFS_SB->mode;
781
	inode->i_mtime = inode->i_atime = inode->i_ctime = obj->datemodified + (365*8+2)*24*60*60;  
782
	/* Linux: seconds since 01-01-1970, AmigaSFS: seconds since 01-01-1978 */
783
	inode->i_uid = ASFS_SB->uid;
784
	inode->i_gid = ASFS_SB->gid;
785
786
	asfs_debug("asfs_read_inode2: Setting-up node %lu... ", inode->i_ino);
787
788
	if (obj->bits & OTYPE_DIR) {
789
		asfs_debug("dir (FirstdirBlock: %u, HashTable %u)\n", \
790
		           obj->object.dir.firstdirblock, obj->object.dir.hashtable);
791
792
		inode->i_size = 0;
793
		inode->i_op = &asfs_dir_inode_operations;
794
		inode->i_fop = &asfs_dir_operations;
795
		inode->i_mode |= S_IFDIR | ((inode->i_mode & 0400) ? 0100 : 0) | 
796
		              ((inode->i_mode & 0040) ? 0010 : 0) | ((inode->i_mode & 0004) ? 0001 : 0);
797
		ASFS_INODE->firstblock = obj->object.dir.firstdirblock;
798
		ASFS_INODE->hashtable = obj->object.dir.hashtable;
799
	} else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK)) {
800
		asfs_debug("symlink\n");
801
		inode->i_size = 0;
802
		inode->i_op = &page_symlink_inode_operations;
803
		inode->i_mapping->a_ops = &asfs_symlink_aops;
804
		inode->i_mode |= S_IFLNK | S_IRWXUGO;
805
		ASFS_INODE->firstblock = obj->object.file.data;
806
	} else {
807
		asfs_debug("file (Size: %u, FirstBlock: %u)\n", obj->object.file.size, obj->object.file.data);
808
809
		inode->i_size = obj->object.file.size;
810
		inode->i_blocks = (obj->object.file.size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
811
		inode->i_fop = &asfs_file_operations;
812
		inode->i_mapping->a_ops = &asfs_aops;
813
		inode->i_mode |= S_IFREG;
814
		ASFS_INODE->firstblock = obj->object.file.data;
815
		ASFS_INODE->ext_cache.startblock = 0;
816
		ASFS_INODE->ext_cache.key = 0;
817
	}
818
	return;	
819
}
820
821
static struct super_operations asfs_ops = {
822
	.read_inode2	= asfs_read_inode2,
823
	.put_super		= asfs_put_super,
824
	.statfs		= asfs_statfs,
825
};
826
827
static DECLARE_FSTYPE_DEV(asfs_fs_type, "asfs", asfs_read_super);
828
829
static int __init init_asfs_fs(void)
830
{
831
	return register_filesystem(&asfs_fs_type);
832
}
833
834
static void __exit exit_asfs_fs(void)
835
{
836
	unregister_filesystem(&asfs_fs_type);
837
}
838
839
/* Yes, works even as a module... :) */
840
841
EXPORT_NO_SYMBOLS;
842
MODULE_DESCRIPTION("Amiga Smart File System support for Linux v0.6 (04.09.2003)");
843
MODULE_LICENSE("GPL");
844
845
module_init(init_asfs_fs)
846
module_exit(exit_asfs_fs)
(-)linux-2.4.21/include/linux/asfs_fs.h (+213 lines)
Line 0 Link Here
1
#ifndef __LINUX_ASFS_FS_H
2
#define __LINUX_ASFS_FS_H
3
4
#include <linux/types.h>
5
#include <asm/byteorder.h>
6
7
#define asfs_debug(fmt,arg...) pr_debug(fmt,##arg)
8
//#define asfs_debug(fmt,arg...) printk(fmt,##arg)
9
10
/* some helper macros... */
11
12
#define from32be(t) ((t)=be32_to_cpu(t))
13
#define from16be(t) ((t)=be16_to_cpu(t))
14
15
#define ASFS_MAKE_ID(a,b,c,d) (((a)&0xff)<<24|((b)&0xff)<<16|((c)&0xff)<<8|((d)&0xff))
16
17
/* Amiga SFS block IDs */
18
19
#define ASFS_ROOTID	ASFS_MAKE_ID('S','F','S','\0')
20
#define ASFS_OBJECTCONTAINER_ID	ASFS_MAKE_ID('O','B','J','C')
21
#define ASFS_BNODECONTAINER_ID	ASFS_MAKE_ID('B','N','D','C')
22
#define ASFS_NODECONTAINER_ID	ASFS_MAKE_ID('N','D','C',' ')
23
#define ASFS_HASHTABLE_ID	ASFS_MAKE_ID('H','T','A','B')
24
#define ASFS_SOFTLINK_ID	ASFS_MAKE_ID('S','L','N','K')
25
26
/* Amiga SFS defines */
27
28
#define ASFS_MAGIC 0xa0ff
29
#define ASFS_MAXFN 105
30
31
#define ASFS_DEFAULT_UID 0 
32
#define ASFS_DEFAULT_GID 0
33
#define ASFS_DEFAULT_MODE 0444 /* default permission bits for files, dirs have same permission, but with "x" set */ 
34
35
#define ASFS_STRUCTURE_VERISON (3)
36
37
#define ASFS_BLCKFACCURACY	(5)
38
39
#define ASFS_ROOTBITS_CASESENSITIVE (128)
40
41
#define OTYPE_HIDDEN      (1)
42
#define OTYPE_HARDLINK    (32)
43
#define OTYPE_LINK        (64)
44
#define OTYPE_DIR         (128)
45
46
#define MSB_MASK (1ul << 31)
47
48
/* Each block has its own header with checksum and id, its called fsBlockHeader */
49
50
struct fsBlockHeader {
51
  u32 id;         /* 4 character id string of this block */
52
  u32 checksum;   /* The checksum */
53
  u32  ownblock;   /* The blocknumber of the block this block is stored at */
54
};
55
56
/* On-disk "super block", called fsRootBlock */
57
58
struct fsRootBlock {
59
  struct fsBlockHeader bheader;
60
61
  u16 version;              /* Version number of the filesystem block structure */
62
  u16 sequencenumber;       /* The Root with the highest sequencenumber is valid */
63
64
  u32 datecreated;          /* Creation date (when first formatted).  Cannot be changed. */
65
  u8 bits;                 /* various settings, see defines below. */
66
  u8 pad1;
67
  u16 pad2;
68
69
  u32 reserved1[2];
70
71
  u32 firstbyteh;           /* The first byte of our partition from the start of the */
72
  u32 firstbyte;            /* disk.  firstbyteh = upper 32 bits, firstbyte = lower 32 bits. */
73
74
  u32 lastbyteh;            /* The last byte of our partition, excluding this one. */
75
  u32 lastbyte;
76
77
  u32  totalblocks;          /* size of this partition in blocks */
78
  u32 blocksize;            /* blocksize used */
79
80
  u32 reserved2[2];
81
  u32 reserved3[8];
82
83
  u32  bitmapbase;           /* location of the bitmap */
84
  u32  adminspacecontainer;  /* location of first adminspace container */
85
  u32  rootobjectcontainer;  /* location of the root objectcontainer */
86
  u32  extentbnoderoot;      /* location of the root of the extentbnode B-tree */
87
  u32  objectnoderoot;       /* location of the root of the objectnode tree */
88
89
  u32 reserved4[3];
90
};
91
92
/* On disk inode, called fsObject */
93
94
struct fsObject {
95
  u16 owneruid;
96
  u16 ownergid;
97
  u32  objectnode;
98
  u32 protection;
99
100
  union {
101
    struct {
102
      u32  data;
103
      u32 size;
104
    } file;
105
106
    struct {
107
      u32  hashtable;   /* for directories & root, 0 means no hashblock */
108
      u32  firstdirblock;
109
    } dir;
110
  } object;
111
112
  u32 datemodified;
113
  u8 bits;
114
115
  u8 name[0];
116
  u8 comment[0];
117
};
118
119
/* On disk block containging a number of fsObjects */
120
121
struct fsObjectContainer {
122
  struct fsBlockHeader bheader;
123
124
  u32 parent;
125
  u32 next;
126
  u32 previous;   /* 0 for the first block in the directory chain */
127
128
  struct fsObject object[0];
129
};
130
131
/* BTree structures, used to collect file data position on disk */
132
133
struct fsExtentBNode {
134
  u32 key;     /* data! */
135
  u32 next;
136
  u32 prev;
137
  u16 blocks;  /* The size in blocks of the region this Extent controls */
138
};
139
140
struct BNode {
141
  u32 key;
142
  u32 data;
143
};
144
145
struct BTreeContainer {
146
  u16 nodecount;
147
  u8 isleaf;
148
  u8 nodesize;   /* Must be a multiple of 2 */
149
150
  struct BNode bnode[0];
151
};
152
153
/* On disk block with BTreeContainer */
154
155
struct fsBNodeContainer {
156
  struct fsBlockHeader bheader;
157
  struct BTreeContainer btc;
158
};
159
160
/* On disk block  with soft link data */
161
162
struct fsSoftLink {
163
	struct fsBlockHeader bheader;
164
	u32 parent;
165
	u32 next;
166
	u32 previous;
167
	u8 string[0];
168
};
169
170
/* */
171
172
struct fsHashTable {
173
  struct fsBlockHeader bheader;
174
  u32 parent;
175
  u32 hashentry[0];
176
};
177
178
/* On disk block with node index and some helper structures */
179
180
struct fsNodeContainer {
181
	struct fsBlockHeader bheader;
182
	u32 nodenumber;
183
	u32 nodes;
184
	u32 node[0];
185
};
186
187
struct fsNode {
188
	u32 data;
189
};
190
191
struct fsObjectNode {
192
	struct fsNode node;
193
	u32 next;
194
	u16 hash16;
195
}
196
__attribute__((packed));
197
198
/* Extent structure located in RAM (e.g. inside inode structure), 
199
   currently used to store last used extent */
200
201
struct inramExtent {
202
	u32 startblock;	/* Block from begginig of the file */
203
	u32 key;
204
	u32 next;
205
	u16 blocks;
206
};
207
208
#ifdef __KERNEL__
209
210
/* Not much now */
211
212
#endif /* __KERNEL__ */
213
#endif
(-)linux-2.4.21/include/linux/asfs_fs_i.h (+16 lines)
Line 0 Link Here
1
#ifndef __ASFS_FS_I
2
#define __ASFS_FS_I
3
4
#include <linux/asfs_fs.h>
5
6
/* inode in-kernel data */
7
8
struct asfs_inode_info {
9
	u32 firstblock;
10
	u32 hashtable;
11
	struct inramExtent ext_cache;
12
};
13
14
#define ASFS_INODE	(&inode->u.asfs_i)
15
#define ASFS_DIR	(&dir->u.asfs_i)
16
#endif
(-)linux-2.4.21/include/linux/asfs_fs_sb.h (+20 lines)
Line 0 Link Here
1
#ifndef __ASFS_FS_SB
2
#define __ASFS_FS_SB
3
4
/* Amiga SFS superblock in-core data */
5
6
struct asfs_sb_info {
7
	u32 totalblocks;
8
	u32 rootobjectcontainer;
9
	u32 extentbnoderoot;
10
	u32 objectnoderoot;
11
	uid_t uid;
12
	gid_t gid;
13
	umode_t mode;
14
	char *prefix;
15
	u8 flags;
16
};
17
18
#define ASFS_SB	(&sb->u.asfs_sb)
19
20
#endif
(-)linux-2.4.21/include/linux/fs.h (+4 lines)
Lines 303-308 Link Here
303
#include <linux/nfs_fs_i.h>
303
#include <linux/nfs_fs_i.h>
304
#include <linux/sysv_fs_i.h>
304
#include <linux/sysv_fs_i.h>
305
#include <linux/affs_fs_i.h>
305
#include <linux/affs_fs_i.h>
306
#include <linux/asfs_fs_i.h>
306
#include <linux/ufs_fs_i.h>
307
#include <linux/ufs_fs_i.h>
307
#include <linux/efs_fs_i.h>
308
#include <linux/efs_fs_i.h>
308
#include <linux/coda_fs_i.h>
309
#include <linux/coda_fs_i.h>
Lines 494-499 Link Here
494
		struct nfs_inode_info		nfs_i;
495
		struct nfs_inode_info		nfs_i;
495
		struct sysv_inode_info		sysv_i;
496
		struct sysv_inode_info		sysv_i;
496
		struct affs_inode_info		affs_i;
497
		struct affs_inode_info		affs_i;
498
		struct asfs_inode_info		asfs_i;
497
		struct ufs_inode_info		ufs_i;
499
		struct ufs_inode_info		ufs_i;
498
		struct efs_inode_info		efs_i;
500
		struct efs_inode_info		efs_i;
499
		struct romfs_inode_info		romfs_i;
501
		struct romfs_inode_info		romfs_i;
Lines 691-696 Link Here
691
#include <linux/nfs_fs_sb.h>
693
#include <linux/nfs_fs_sb.h>
692
#include <linux/sysv_fs_sb.h>
694
#include <linux/sysv_fs_sb.h>
693
#include <linux/affs_fs_sb.h>
695
#include <linux/affs_fs_sb.h>
696
#include <linux/asfs_fs_sb.h>
694
#include <linux/ufs_fs_sb.h>
697
#include <linux/ufs_fs_sb.h>
695
#include <linux/efs_fs_sb.h>
698
#include <linux/efs_fs_sb.h>
696
#include <linux/romfs_fs_sb.h>
699
#include <linux/romfs_fs_sb.h>
Lines 748-753 Link Here
748
		struct nfs_sb_info	nfs_sb;
751
		struct nfs_sb_info	nfs_sb;
749
		struct sysv_sb_info	sysv_sb;
752
		struct sysv_sb_info	sysv_sb;
750
		struct affs_sb_info	affs_sb;
753
		struct affs_sb_info	affs_sb;
754
		struct asfs_sb_info	asfs_sb;
751
		struct ufs_sb_info	ufs_sb;
755
		struct ufs_sb_info	ufs_sb;
752
		struct efs_sb_info	efs_sb;
756
		struct efs_sb_info	efs_sb;
753
		struct shmem_sb_info	shmem_sb;
757
		struct shmem_sb_info	shmem_sb;

Return to bug 27558