Blame view

fs/bfs/inode.c 11.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   *	fs/bfs/inode.c
   *	BFS superblock and inode operations.
69688262f   Tigran Aivazian   [PATCH] update Ti...
4
   *	Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   *	From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
6
7
   *
   *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
15
16
17
18
19
   */
  
  #include <linux/module.h>
  #include <linux/mm.h>
  #include <linux/slab.h>
  #include <linux/init.h>
  #include <linux/fs.h>
  #include <linux/smp_lock.h>
  #include <linux/buffer_head.h>
  #include <linux/vfs.h>
  #include <asm/uaccess.h>
  #include "bfs.h"
69688262f   Tigran Aivazian   [PATCH] update Ti...
20
  MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
  MODULE_LICENSE("GPL");
  
  #undef DEBUG
  
  #ifdef DEBUG
  #define dprintf(x...)	printf(x)
  #else
  #define dprintf(x...)
  #endif
  
  void dump_imap(const char *prefix, struct super_block * s);
  
  static void bfs_read_inode(struct inode * inode)
  {
  	unsigned long ino = inode->i_ino;
  	struct bfs_inode * di;
  	struct buffer_head * bh;
  	int block, off;
  
  	if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
  		printf("Bad inode number %s:%08lx
  ", inode->i_sb->s_id, ino);
  		make_bad_inode(inode);
  		return;
  	}
  
  	block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
  	bh = sb_bread(inode->i_sb, block);
  	if (!bh) {
  		printf("Unable to read inode %s:%08lx
  ", inode->i_sb->s_id, ino);
  		make_bad_inode(inode);
  		return;
  	}
  
  	off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
  	di = (struct bfs_inode *)bh->b_data + off;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
59
60
  	inode->i_mode = 0x0000FFFF &  le32_to_cpu(di->i_mode);
  	if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
  		inode->i_mode |= S_IFDIR;
  		inode->i_op = &bfs_dir_inops;
  		inode->i_fop = &bfs_dir_operations;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
64
  	} else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
68
69
  		inode->i_mode |= S_IFREG;
  		inode->i_op = &bfs_file_inops;
  		inode->i_fop = &bfs_file_operations;
  		inode->i_mapping->a_ops = &bfs_aops;
  	}
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
70
71
72
73
74
  	BFS_I(inode)->i_sblock =  le32_to_cpu(di->i_sblock);
  	BFS_I(inode)->i_eblock =  le32_to_cpu(di->i_eblock);
  	inode->i_uid =  le32_to_cpu(di->i_uid);
  	inode->i_gid =  le32_to_cpu(di->i_gid);
  	inode->i_nlink =  le32_to_cpu(di->i_nlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
  	inode->i_size = BFS_FILESIZE(di);
  	inode->i_blocks = BFS_FILEBLOCKS(di);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
77
78
          if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks
  ", inode->i_size, inode->i_blocks);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
79
80
81
  	inode->i_atime.tv_sec =  le32_to_cpu(di->i_atime);
  	inode->i_mtime.tv_sec =  le32_to_cpu(di->i_mtime);
  	inode->i_ctime.tv_sec =  le32_to_cpu(di->i_ctime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
  	inode->i_atime.tv_nsec = 0;
  	inode->i_mtime.tv_nsec = 0;
  	inode->i_ctime.tv_nsec = 0;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
85
  	BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
  
  	brelse(bh);
  }
  
  static int bfs_write_inode(struct inode * inode, int unused)
  {
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
92
93
  	unsigned int ino = (u16)inode->i_ino;
          unsigned long i_sblock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
  	struct bfs_inode * di;
  	struct buffer_head * bh;
  	int block, off;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
97
98
          dprintf("ino=%08x
  ", ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
  	if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
100
101
  		printf("Bad inode number %s:%08x
  ", inode->i_sb->s_id, ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
  		return -EIO;
  	}
  
  	lock_kernel();
  	block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
  	bh = sb_bread(inode->i_sb, block);
  	if (!bh) {
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
109
110
  		printf("Unable to read inode %s:%08x
  ", inode->i_sb->s_id, ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
115
116
  		unlock_kernel();
  		return -EIO;
  	}
  
  	off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
  	di = (struct bfs_inode *)bh->b_data + off;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
117
118
  	if (ino == BFS_ROOT_INO)
  		di->i_vtype = cpu_to_le32(BFS_VDIR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  	else
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  		di->i_vtype = cpu_to_le32(BFS_VREG);
  
  	di->i_ino = cpu_to_le16(ino);
  	di->i_mode = cpu_to_le32(inode->i_mode);
  	di->i_uid = cpu_to_le32(inode->i_uid);
  	di->i_gid = cpu_to_le32(inode->i_gid);
  	di->i_nlink = cpu_to_le32(inode->i_nlink);
  	di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
  	di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
  	di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
          i_sblock = BFS_I(inode)->i_sblock;
  	di->i_sblock = cpu_to_le32(i_sblock);
  	di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
  	di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
  
  	mark_buffer_dirty(bh);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
136
137
          dprintf("Written ino=%d into %d:%d
  ",le16_to_cpu(di->i_ino),block,off);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
141
142
143
144
145
146
147
148
149
150
  	brelse(bh);
  	unlock_kernel();
  	return 0;
  }
  
  static void bfs_delete_inode(struct inode * inode)
  {
  	unsigned long ino = inode->i_ino;
  	struct bfs_inode * di;
  	struct buffer_head * bh;
  	int block, off;
  	struct super_block * s = inode->i_sb;
  	struct bfs_sb_info * info = BFS_SB(s);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
151
  	struct bfs_inode_info * bi = BFS_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152

fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
153
154
  	dprintf("ino=%08lx
  ", ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155

fef266580   Mark Fasheh   [PATCH] update fi...
156
  	truncate_inode_pages(&inode->i_data, 0);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
157
158
159
  	if (ino < BFS_ROOT_INO || ino > info->si_lasti) {
  		printf("invalid ino=%08lx
  ", ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  		return;
  	}
  	
  	inode->i_size = 0;
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
  	lock_kernel();
  	mark_inode_dirty(inode);
  	block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
  	bh = sb_bread(s, block);
  	if (!bh) {
  		printf("Unable to read inode %s:%08lx
  ", inode->i_sb->s_id, ino);
  		unlock_kernel();
  		return;
  	}
  	off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
176
177
178
  	di = (struct bfs_inode *) bh->b_data + off;
          if (bi->i_dsk_ino) {
  		info->si_freeb += 1 + bi->i_eblock - bi->i_sblock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  		info->si_freei++;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
180
  		clear_bit(ino, info->si_imap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  		dump_imap("delete_inode", s);
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
182
          }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  	di->i_ino = 0;
  	di->i_sblock = 0;
  	mark_buffer_dirty(bh);
  	brelse(bh);
  
  	/* if this was the last file, make the previous 
  	   block "last files last block" even if there is no real file there,
  	   saves us 1 gap */
  	if (info->si_lf_eblk == BFS_I(inode)->i_eblock) {
  		info->si_lf_eblk = BFS_I(inode)->i_sblock - 1;
  		mark_buffer_dirty(info->si_sbh);
  	}
  	unlock_kernel();
  	clear_inode(inode);
  }
  
  static void bfs_put_super(struct super_block *s)
  {
  	struct bfs_sb_info *info = BFS_SB(s);
  	brelse(info->si_sbh);
  	kfree(info->si_imap);
  	kfree(info);
  	s->s_fs_info = NULL;
  }
726c33422   David Howells   [PATCH] VFS: Perm...
207
  static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  {
726c33422   David Howells   [PATCH] VFS: Perm...
209
  	struct super_block *s = dentry->d_sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  	struct bfs_sb_info *info = BFS_SB(s);
  	u64 id = huge_encode_dev(s->s_bdev->bd_dev);
  	buf->f_type = BFS_MAGIC;
  	buf->f_bsize = s->s_blocksize;
  	buf->f_blocks = info->si_blocks;
  	buf->f_bfree = buf->f_bavail = info->si_freeb;
  	buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
  	buf->f_ffree = info->si_freei;
  	buf->f_fsid.val[0] = (u32)id;
  	buf->f_fsid.val[1] = (u32)(id >> 32);
  	buf->f_namelen = BFS_NAMELEN;
  	return 0;
  }
  
  static void bfs_write_super(struct super_block *s)
  {
  	lock_kernel();
  	if (!(s->s_flags & MS_RDONLY))
  		mark_buffer_dirty(BFS_SB(s)->si_sbh);
  	s->s_dirt = 0;
  	unlock_kernel();
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
232
  static struct kmem_cache * bfs_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
  
  static struct inode *bfs_alloc_inode(struct super_block *sb)
  {
  	struct bfs_inode_info *bi;
e94b17660   Christoph Lameter   [PATCH] slab: rem...
237
  	bi = kmem_cache_alloc(bfs_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
240
241
242
243
244
245
246
  	if (!bi)
  		return NULL;
  	return &bi->vfs_inode;
  }
  
  static void bfs_destroy_inode(struct inode *inode)
  {
  	kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
247
  static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
  {
  	struct bfs_inode_info *bi = foo;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
250
  	inode_init_once(&bi->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  }
20c2df83d   Paul Mundt   mm: Remove slab d...
252

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
256
  static int init_inodecache(void)
  {
  	bfs_inode_cachep = kmem_cache_create("bfs_inode_cache",
  					     sizeof(struct bfs_inode_info),
fffb60f93   Paul Jackson   [PATCH] cpuset me...
257
258
  					     0, (SLAB_RECLAIM_ACCOUNT|
  						SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
259
  					     init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
262
263
264
265
266
  	if (bfs_inode_cachep == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  static void destroy_inodecache(void)
  {
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
267
  	kmem_cache_destroy(bfs_inode_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  }
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
269
  static const struct super_operations bfs_sops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
272
273
274
275
276
277
278
279
280
281
  	.alloc_inode	= bfs_alloc_inode,
  	.destroy_inode	= bfs_destroy_inode,
  	.read_inode	= bfs_read_inode,
  	.write_inode	= bfs_write_inode,
  	.delete_inode	= bfs_delete_inode,
  	.put_super	= bfs_put_super,
  	.write_super	= bfs_write_super,
  	.statfs		= bfs_statfs,
  };
  
  void dump_imap(const char *prefix, struct super_block * s)
  {
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
282
  #ifdef DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
287
288
  	int i;
  	char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
  
  	if (!tmpbuf)
  		return;
  	for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
289
  		if (i > PAGE_SIZE-100) break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  		if (test_bit(i, BFS_SB(s)->si_imap))
  			strcat(tmpbuf, "1");
  		else
  			strcat(tmpbuf, "0");
  	}
  	printk(KERN_ERR "BFS-fs: %s: lasti=%08lx <%s>
  ", prefix, BFS_SB(s)->si_lasti, tmpbuf);
  	free_page((unsigned long)tmpbuf);
  #endif
  }
  
  static int bfs_fill_super(struct super_block *s, void *data, int silent)
  {
  	struct buffer_head * bh;
  	struct bfs_super_block * bfs_sb;
  	struct inode * inode;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
306
  	unsigned i, imap_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  	struct bfs_sb_info * info;
f8314dc60   Panagiotis Issaris   [PATCH] fs: Conve...
308
  	info = kzalloc(sizeof(*info), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
  	if (!info)
  		return -ENOMEM;
  	s->s_fs_info = info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
315
316
317
318
  
  	sb_set_blocksize(s, BFS_BSIZE);
  
  	bh = sb_bread(s, 0);
  	if(!bh)
  		goto out;
  	bfs_sb = (struct bfs_super_block *)bh->b_data;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
319
  	if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
  		if (!silent)
  			printf("No BFS filesystem on %s (magic=%08x)
  ", 
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
323
  				s->s_id,  le32_to_cpu(bfs_sb->s_magic));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
326
327
328
329
330
  		goto out;
  	}
  	if (BFS_UNCLEAN(bfs_sb, s) && !silent)
  		printf("%s is unclean, continuing
  ", s->s_id);
  
  	s->s_magic = BFS_MAGIC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
  	info->si_sbh = bh;
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
332
  	info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
335
  			+ BFS_ROOT_INO - 1;
  
  	imap_len = info->si_lasti/8 + 1;
f8314dc60   Panagiotis Issaris   [PATCH] fs: Conve...
336
  	info->si_imap = kzalloc(imap_len, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
338
  	if (!info->si_imap)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
  	for (i=0; i<BFS_ROOT_INO; i++) 
  		set_bit(i, info->si_imap);
  
  	s->s_op = &bfs_sops;
  	inode = iget(s, BFS_ROOT_INO);
  	if (!inode) {
  		kfree(info->si_imap);
  		goto out;
  	}
  	s->s_root = d_alloc_root(inode);
  	if (!s->s_root) {
  		iput(inode);
  		kfree(info->si_imap);
  		goto out;
  	}
fac92becd   Andrew Stribblehill   [PATCH] bfs: fix ...
354
  	info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
ce0fe7e70   Alexey Dobriyan   [PATCH] bfs endia...
355
  	info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 -  le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
358
359
  	info->si_freei = 0;
  	info->si_lf_eblk = 0;
  	info->si_lf_sblk = 0;
  	info->si_lf_ioff = 0;
c2b513dfb   Al Viro   [PATCH] bfs iget(...
360
  	bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  	for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
c2b513dfb   Al Viro   [PATCH] bfs iget(...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  		struct bfs_inode *di;
  		int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
  		int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
  		unsigned long sblock, eblock;
  
  		if (!off) {
  			brelse(bh);
  			bh = sb_bread(s, block);
  		}
  
  		if (!bh)
  			continue;
  
  		di = (struct bfs_inode *)bh->b_data + off;
  
  		if (!di->i_ino) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  			info->si_freei++;
c2b513dfb   Al Viro   [PATCH] bfs iget(...
379
380
381
382
383
384
385
386
387
388
389
  			continue;
  		}
  		set_bit(i, info->si_imap);
  		info->si_freeb -= BFS_FILEBLOCKS(di);
  
  		sblock =  le32_to_cpu(di->i_sblock);
  		eblock =  le32_to_cpu(di->i_eblock);
  		if (eblock > info->si_lf_eblk) {
  			info->si_lf_eblk = eblock;
  			info->si_lf_sblk = sblock;
  			info->si_lf_ioff = BFS_INO2OFF(i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  	}
c2b513dfb   Al Viro   [PATCH] bfs iget(...
392
  	brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  	if (!(s->s_flags & MS_RDONLY)) {
c2b513dfb   Al Viro   [PATCH] bfs iget(...
394
  		mark_buffer_dirty(info->si_sbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
401
402
403
404
405
  		s->s_dirt = 1;
  	} 
  	dump_imap("read_super", s);
  	return 0;
  
  out:
  	brelse(bh);
  	kfree(info);
  	s->s_fs_info = NULL;
  	return -EINVAL;
  }
454e2398b   David Howells   [PATCH] VFS: Perm...
406
407
  static int bfs_get_sb(struct file_system_type *fs_type,
  	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  {
454e2398b   David Howells   [PATCH] VFS: Perm...
409
  	return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
  }
  
  static struct file_system_type bfs_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "bfs",
  	.get_sb		= bfs_get_sb,
  	.kill_sb	= kill_block_super,
  	.fs_flags	= FS_REQUIRES_DEV,
  };
  
  static int __init init_bfs_fs(void)
  {
  	int err = init_inodecache();
  	if (err)
  		goto out1;
          err = register_filesystem(&bfs_fs_type);
  	if (err)
  		goto out;
  	return 0;
  out:
  	destroy_inodecache();
  out1:
  	return err;
  }
  
  static void __exit exit_bfs_fs(void)
  {
  	unregister_filesystem(&bfs_fs_type);
  	destroy_inodecache();
  }
  
  module_init(init_bfs_fs)
  module_exit(exit_bfs_fs)