ceph: renew auth tickets before they expire
[safe/jmp/linux-2.6] / fs / bfs / inode.c
1 /*
2  *      fs/bfs/inode.c
3  *      BFS superblock and inode operations.
4  *      Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5  *      From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
6  *
7  *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
8  */
9
10 #include <linux/module.h>
11 #include <linux/mm.h>
12 #include <linux/slab.h>
13 #include <linux/init.h>
14 #include <linux/fs.h>
15 #include <linux/smp_lock.h>
16 #include <linux/buffer_head.h>
17 #include <linux/vfs.h>
18 #include <linux/writeback.h>
19 #include <asm/uaccess.h>
20 #include "bfs.h"
21
22 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
23 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
24 MODULE_LICENSE("GPL");
25
26 #undef DEBUG
27
28 #ifdef DEBUG
29 #define dprintf(x...)   printf(x)
30 #else
31 #define dprintf(x...)
32 #endif
33
34 static void bfs_write_super(struct super_block *s);
35 void dump_imap(const char *prefix, struct super_block *s);
36
37 struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
38 {
39         struct bfs_inode *di;
40         struct inode *inode;
41         struct buffer_head *bh;
42         int block, off;
43
44         inode = iget_locked(sb, ino);
45         if (IS_ERR(inode))
46                 return ERR_PTR(-ENOMEM);
47         if (!(inode->i_state & I_NEW))
48                 return inode;
49
50         if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
51                 printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
52                 goto error;
53         }
54
55         block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
56         bh = sb_bread(inode->i_sb, block);
57         if (!bh) {
58                 printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id,
59                                                                         ino);
60                 goto error;
61         }
62
63         off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
64         di = (struct bfs_inode *)bh->b_data + off;
65
66         inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
67         if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
68                 inode->i_mode |= S_IFDIR;
69                 inode->i_op = &bfs_dir_inops;
70                 inode->i_fop = &bfs_dir_operations;
71         } else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
72                 inode->i_mode |= S_IFREG;
73                 inode->i_op = &bfs_file_inops;
74                 inode->i_fop = &bfs_file_operations;
75                 inode->i_mapping->a_ops = &bfs_aops;
76         }
77
78         BFS_I(inode)->i_sblock =  le32_to_cpu(di->i_sblock);
79         BFS_I(inode)->i_eblock =  le32_to_cpu(di->i_eblock);
80         BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino);
81         inode->i_uid =  le32_to_cpu(di->i_uid);
82         inode->i_gid =  le32_to_cpu(di->i_gid);
83         inode->i_nlink =  le32_to_cpu(di->i_nlink);
84         inode->i_size = BFS_FILESIZE(di);
85         inode->i_blocks = BFS_FILEBLOCKS(di);
86         inode->i_atime.tv_sec =  le32_to_cpu(di->i_atime);
87         inode->i_mtime.tv_sec =  le32_to_cpu(di->i_mtime);
88         inode->i_ctime.tv_sec =  le32_to_cpu(di->i_ctime);
89         inode->i_atime.tv_nsec = 0;
90         inode->i_mtime.tv_nsec = 0;
91         inode->i_ctime.tv_nsec = 0;
92
93         brelse(bh);
94         unlock_new_inode(inode);
95         return inode;
96
97 error:
98         iget_failed(inode);
99         return ERR_PTR(-EIO);
100 }
101
102 static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
103 {
104         struct bfs_sb_info *info = BFS_SB(inode->i_sb);
105         unsigned int ino = (u16)inode->i_ino;
106         unsigned long i_sblock;
107         struct bfs_inode *di;
108         struct buffer_head *bh;
109         int block, off;
110         int err = 0;
111
112         dprintf("ino=%08x\n", ino);
113
114         if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
115                 printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
116                 return -EIO;
117         }
118
119         mutex_lock(&info->bfs_lock);
120         block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
121         bh = sb_bread(inode->i_sb, block);
122         if (!bh) {
123                 printf("Unable to read inode %s:%08x\n",
124                                 inode->i_sb->s_id, ino);
125                 mutex_unlock(&info->bfs_lock);
126                 return -EIO;
127         }
128
129         off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
130         di = (struct bfs_inode *)bh->b_data + off;
131
132         if (ino == BFS_ROOT_INO)
133                 di->i_vtype = cpu_to_le32(BFS_VDIR);
134         else
135                 di->i_vtype = cpu_to_le32(BFS_VREG);
136
137         di->i_ino = cpu_to_le16(ino);
138         di->i_mode = cpu_to_le32(inode->i_mode);
139         di->i_uid = cpu_to_le32(inode->i_uid);
140         di->i_gid = cpu_to_le32(inode->i_gid);
141         di->i_nlink = cpu_to_le32(inode->i_nlink);
142         di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
143         di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
144         di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
145         i_sblock = BFS_I(inode)->i_sblock;
146         di->i_sblock = cpu_to_le32(i_sblock);
147         di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
148         di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
149
150         mark_buffer_dirty(bh);
151         if (wbc->sync_mode == WB_SYNC_ALL) {
152                 sync_dirty_buffer(bh);
153                 if (buffer_req(bh) && !buffer_uptodate(bh))
154                         err = -EIO;
155         }
156         brelse(bh);
157         mutex_unlock(&info->bfs_lock);
158         return err;
159 }
160
161 static void bfs_delete_inode(struct inode *inode)
162 {
163         unsigned long ino = inode->i_ino;
164         struct bfs_inode *di;
165         struct buffer_head *bh;
166         int block, off;
167         struct super_block *s = inode->i_sb;
168         struct bfs_sb_info *info = BFS_SB(s);
169         struct bfs_inode_info *bi = BFS_I(inode);
170
171         dprintf("ino=%08lx\n", ino);
172
173         truncate_inode_pages(&inode->i_data, 0);
174
175         if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) {
176                 printf("invalid ino=%08lx\n", ino);
177                 return;
178         }
179         
180         inode->i_size = 0;
181         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
182         mutex_lock(&info->bfs_lock);
183         mark_inode_dirty(inode);
184
185         block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
186         bh = sb_bread(s, block);
187         if (!bh) {
188                 printf("Unable to read inode %s:%08lx\n",
189                                         inode->i_sb->s_id, ino);
190                 mutex_unlock(&info->bfs_lock);
191                 return;
192         }
193         off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
194         di = (struct bfs_inode *)bh->b_data + off;
195         memset((void *)di, 0, sizeof(struct bfs_inode));
196         mark_buffer_dirty(bh);
197         brelse(bh);
198
199         if (bi->i_dsk_ino) {
200                 if (bi->i_sblock)
201                         info->si_freeb += bi->i_eblock + 1 - bi->i_sblock;
202                 info->si_freei++;
203                 clear_bit(ino, info->si_imap);
204                 dump_imap("delete_inode", s);
205         }
206
207         /*
208          * If this was the last file, make the previous block
209          * "last block of the last file" even if there is no
210          * real file there, saves us 1 gap.
211          */
212         if (info->si_lf_eblk == bi->i_eblock) {
213                 info->si_lf_eblk = bi->i_sblock - 1;
214                 mark_buffer_dirty(info->si_sbh);
215         }
216         mutex_unlock(&info->bfs_lock);
217         clear_inode(inode);
218 }
219
220 static int bfs_sync_fs(struct super_block *sb, int wait)
221 {
222         struct bfs_sb_info *info = BFS_SB(sb);
223
224         mutex_lock(&info->bfs_lock);
225         mark_buffer_dirty(info->si_sbh);
226         sb->s_dirt = 0;
227         mutex_unlock(&info->bfs_lock);
228
229         return 0;
230 }
231
232 static void bfs_write_super(struct super_block *sb)
233 {
234         if (!(sb->s_flags & MS_RDONLY))
235                 bfs_sync_fs(sb, 1);
236         else
237                 sb->s_dirt = 0;
238 }
239
240 static void bfs_put_super(struct super_block *s)
241 {
242         struct bfs_sb_info *info = BFS_SB(s);
243
244         if (!info)
245                 return;
246
247         lock_kernel();
248
249         if (s->s_dirt)
250                 bfs_write_super(s);
251
252         brelse(info->si_sbh);
253         mutex_destroy(&info->bfs_lock);
254         kfree(info->si_imap);
255         kfree(info);
256         s->s_fs_info = NULL;
257
258         unlock_kernel();
259 }
260
261 static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
262 {
263         struct super_block *s = dentry->d_sb;
264         struct bfs_sb_info *info = BFS_SB(s);
265         u64 id = huge_encode_dev(s->s_bdev->bd_dev);
266         buf->f_type = BFS_MAGIC;
267         buf->f_bsize = s->s_blocksize;
268         buf->f_blocks = info->si_blocks;
269         buf->f_bfree = buf->f_bavail = info->si_freeb;
270         buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
271         buf->f_ffree = info->si_freei;
272         buf->f_fsid.val[0] = (u32)id;
273         buf->f_fsid.val[1] = (u32)(id >> 32);
274         buf->f_namelen = BFS_NAMELEN;
275         return 0;
276 }
277
278 static struct kmem_cache *bfs_inode_cachep;
279
280 static struct inode *bfs_alloc_inode(struct super_block *sb)
281 {
282         struct bfs_inode_info *bi;
283         bi = kmem_cache_alloc(bfs_inode_cachep, GFP_KERNEL);
284         if (!bi)
285                 return NULL;
286         return &bi->vfs_inode;
287 }
288
289 static void bfs_destroy_inode(struct inode *inode)
290 {
291         kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
292 }
293
294 static void init_once(void *foo)
295 {
296         struct bfs_inode_info *bi = foo;
297
298         inode_init_once(&bi->vfs_inode);
299 }
300
301 static int init_inodecache(void)
302 {
303         bfs_inode_cachep = kmem_cache_create("bfs_inode_cache",
304                                              sizeof(struct bfs_inode_info),
305                                              0, (SLAB_RECLAIM_ACCOUNT|
306                                                 SLAB_MEM_SPREAD),
307                                              init_once);
308         if (bfs_inode_cachep == NULL)
309                 return -ENOMEM;
310         return 0;
311 }
312
313 static void destroy_inodecache(void)
314 {
315         kmem_cache_destroy(bfs_inode_cachep);
316 }
317
318 static const struct super_operations bfs_sops = {
319         .alloc_inode    = bfs_alloc_inode,
320         .destroy_inode  = bfs_destroy_inode,
321         .write_inode    = bfs_write_inode,
322         .delete_inode   = bfs_delete_inode,
323         .put_super      = bfs_put_super,
324         .write_super    = bfs_write_super,
325         .sync_fs        = bfs_sync_fs,
326         .statfs         = bfs_statfs,
327 };
328
329 void dump_imap(const char *prefix, struct super_block *s)
330 {
331 #ifdef DEBUG
332         int i;
333         char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
334
335         if (!tmpbuf)
336                 return;
337         for (i = BFS_SB(s)->si_lasti; i >= 0; i--) {
338                 if (i > PAGE_SIZE - 100) break;
339                 if (test_bit(i, BFS_SB(s)->si_imap))
340                         strcat(tmpbuf, "1");
341                 else
342                         strcat(tmpbuf, "0");
343         }
344         printf("BFS-fs: %s: lasti=%08lx <%s>\n",
345                                 prefix, BFS_SB(s)->si_lasti, tmpbuf);
346         free_page((unsigned long)tmpbuf);
347 #endif
348 }
349
350 static int bfs_fill_super(struct super_block *s, void *data, int silent)
351 {
352         struct buffer_head *bh;
353         struct bfs_super_block *bfs_sb;
354         struct inode *inode;
355         unsigned i, imap_len;
356         struct bfs_sb_info *info;
357         int ret = -EINVAL;
358         unsigned long i_sblock, i_eblock, i_eoff, s_size;
359
360         info = kzalloc(sizeof(*info), GFP_KERNEL);
361         if (!info)
362                 return -ENOMEM;
363         mutex_init(&info->bfs_lock);
364         s->s_fs_info = info;
365
366         sb_set_blocksize(s, BFS_BSIZE);
367
368         info->si_sbh = sb_bread(s, 0);
369         if (!info->si_sbh)
370                 goto out;
371         bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data;
372         if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
373                 if (!silent)
374                         printf("No BFS filesystem on %s (magic=%08x)\n", 
375                                 s->s_id,  le32_to_cpu(bfs_sb->s_magic));
376                 goto out1;
377         }
378         if (BFS_UNCLEAN(bfs_sb, s) && !silent)
379                 printf("%s is unclean, continuing\n", s->s_id);
380
381         s->s_magic = BFS_MAGIC;
382
383         if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
384                 printf("Superblock is corrupted\n");
385                 goto out1;
386         }
387
388         info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
389                                         sizeof(struct bfs_inode)
390                                         + BFS_ROOT_INO - 1;
391         imap_len = (info->si_lasti / 8) + 1;
392         info->si_imap = kzalloc(imap_len, GFP_KERNEL);
393         if (!info->si_imap)
394                 goto out1;
395         for (i = 0; i < BFS_ROOT_INO; i++)
396                 set_bit(i, info->si_imap);
397
398         s->s_op = &bfs_sops;
399         inode = bfs_iget(s, BFS_ROOT_INO);
400         if (IS_ERR(inode)) {
401                 ret = PTR_ERR(inode);
402                 goto out2;
403         }
404         s->s_root = d_alloc_root(inode);
405         if (!s->s_root) {
406                 iput(inode);
407                 ret = -ENOMEM;
408                 goto out2;
409         }
410
411         info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
412         info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1
413                         - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
414         info->si_freei = 0;
415         info->si_lf_eblk = 0;
416
417         /* can we read the last block? */
418         bh = sb_bread(s, info->si_blocks - 1);
419         if (!bh) {
420                 printf("Last block not available: %lu\n", info->si_blocks - 1);
421                 ret = -EIO;
422                 goto out3;
423         }
424         brelse(bh);
425
426         bh = NULL;
427         for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) {
428                 struct bfs_inode *di;
429                 int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
430                 int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
431                 unsigned long eblock;
432
433                 if (!off) {
434                         brelse(bh);
435                         bh = sb_bread(s, block);
436                 }
437
438                 if (!bh)
439                         continue;
440
441                 di = (struct bfs_inode *)bh->b_data + off;
442
443                 /* test if filesystem is not corrupted */
444
445                 i_eoff = le32_to_cpu(di->i_eoffset);
446                 i_sblock = le32_to_cpu(di->i_sblock);
447                 i_eblock = le32_to_cpu(di->i_eblock);
448                 s_size = le32_to_cpu(bfs_sb->s_end);
449
450                 if (i_sblock > info->si_blocks ||
451                         i_eblock > info->si_blocks ||
452                         i_sblock > i_eblock ||
453                         i_eoff > s_size ||
454                         i_sblock * BFS_BSIZE > i_eoff) {
455
456                         printf("Inode 0x%08x corrupted\n", i);
457
458                         brelse(bh);
459                         ret = -EIO;
460                         goto out3;
461                 }
462
463                 if (!di->i_ino) {
464                         info->si_freei++;
465                         continue;
466                 }
467                 set_bit(i, info->si_imap);
468                 info->si_freeb -= BFS_FILEBLOCKS(di);
469
470                 eblock =  le32_to_cpu(di->i_eblock);
471                 if (eblock > info->si_lf_eblk)
472                         info->si_lf_eblk = eblock;
473         }
474         brelse(bh);
475         if (!(s->s_flags & MS_RDONLY)) {
476                 mark_buffer_dirty(info->si_sbh);
477                 s->s_dirt = 1;
478         } 
479         dump_imap("read_super", s);
480         return 0;
481
482 out3:
483         dput(s->s_root);
484         s->s_root = NULL;
485 out2:
486         kfree(info->si_imap);
487 out1:
488         brelse(info->si_sbh);
489 out:
490         mutex_destroy(&info->bfs_lock);
491         kfree(info);
492         s->s_fs_info = NULL;
493         return ret;
494 }
495
496 static int bfs_get_sb(struct file_system_type *fs_type,
497         int flags, const char *dev_name, void *data, struct vfsmount *mnt)
498 {
499         return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt);
500 }
501
502 static struct file_system_type bfs_fs_type = {
503         .owner          = THIS_MODULE,
504         .name           = "bfs",
505         .get_sb         = bfs_get_sb,
506         .kill_sb        = kill_block_super,
507         .fs_flags       = FS_REQUIRES_DEV,
508 };
509
510 static int __init init_bfs_fs(void)
511 {
512         int err = init_inodecache();
513         if (err)
514                 goto out1;
515         err = register_filesystem(&bfs_fs_type);
516         if (err)
517                 goto out;
518         return 0;
519 out:
520         destroy_inodecache();
521 out1:
522         return err;
523 }
524
525 static void __exit exit_bfs_fs(void)
526 {
527         unregister_filesystem(&bfs_fs_type);
528         destroy_inodecache();
529 }
530
531 module_init(init_bfs_fs)
532 module_exit(exit_bfs_fs)