OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [ext/] [inode.c] - Blame information for rev 1628

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/ext/inode.c
3
 *
4
 *  Copyright (C) 1992  Remy Card (card@masi.ibp.fr)
5
 *
6
 *  from
7
 *
8
 *  linux/fs/minix/inode.c
9
 *
10
 *  Copyright (C) 1991, 1992  Linus Torvalds
11
 */
12
 
13
#include <linux/module.h>
14
 
15
#include <linux/sched.h>
16
#include <linux/ext_fs.h>
17
#include <linux/kernel.h>
18
#include <linux/mm.h>
19
#include <linux/string.h>
20
#include <linux/stat.h>
21
#include <linux/locks.h>
22
 
23
#include <asm/system.h>
24
#include <asm/segment.h>
25
 
26
void ext_put_inode(struct inode *inode)
27
{
28
        if (inode->i_nlink)
29
                return;
30
        inode->i_size = 0;
31
        ext_truncate(inode);
32
        ext_free_inode(inode);
33
}
34
 
35
void ext_put_super(struct super_block *sb)
36
{
37
 
38
        lock_super(sb);
39
        sb->s_dev = 0;
40
        if (sb->u.ext_sb.s_firstfreeinodeblock)
41
                brelse (sb->u.ext_sb.s_firstfreeinodeblock);
42
        if (sb->u.ext_sb.s_firstfreeblock)
43
                brelse (sb->u.ext_sb.s_firstfreeblock);
44
        unlock_super(sb);
45
        MOD_DEC_USE_COUNT;
46
        return;
47
}
48
 
49
static struct super_operations ext_sops = {
50
        ext_read_inode,
51
        NULL,
52
        ext_write_inode,
53
        ext_put_inode,
54
        ext_put_super,
55
        ext_write_super,
56
        ext_statfs,
57
        NULL
58
};
59
 
60
struct super_block *ext_read_super(struct super_block *s,void *data,
61
                                   int silent)
62
{
63
        struct buffer_head *bh;
64
        struct ext_super_block *es;
65
        kdev_t dev = s->s_dev;
66
        int block;
67
 
68
        MOD_INC_USE_COUNT;
69
        lock_super(s);
70
        set_blocksize(dev, BLOCK_SIZE);
71
        if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
72
                s->s_dev = 0;
73
                unlock_super(s);
74
                printk("EXT-fs: unable to read superblock\n");
75
                MOD_DEC_USE_COUNT;
76
                return NULL;
77
        }
78
        es = (struct ext_super_block *) bh->b_data;
79
        s->s_blocksize = 1024;
80
        s->s_blocksize_bits = 10;
81
        s->u.ext_sb.s_ninodes = es->s_ninodes;
82
        s->u.ext_sb.s_nzones = es->s_nzones;
83
        s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
84
        s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
85
        s->u.ext_sb.s_max_size = es->s_max_size;
86
        s->s_magic = es->s_magic;
87
        s->u.ext_sb.s_firstfreeblocknumber = es->s_firstfreeblock;
88
        s->u.ext_sb.s_freeblockscount = es->s_freeblockscount;
89
        s->u.ext_sb.s_firstfreeinodenumber = es->s_firstfreeinode;
90
        s->u.ext_sb.s_freeinodescount = es->s_freeinodescount;
91
        brelse(bh);
92
        if (s->s_magic != EXT_SUPER_MAGIC) {
93
                s->s_dev = 0;
94
                unlock_super(s);
95
                if (!silent)
96
                        printk("VFS: Can't find an extfs filesystem on dev "
97
                               "%s.\n", kdevname(dev));
98
                MOD_DEC_USE_COUNT;
99
                return NULL;
100
        }
101
        if (!s->u.ext_sb.s_firstfreeblocknumber)
102
                s->u.ext_sb.s_firstfreeblock = NULL;
103
        else
104
                if (!(s->u.ext_sb.s_firstfreeblock = bread(dev,
105
                        s->u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE))) {
106
                        printk("ext_read_super: unable to read first free block\n");
107
                        s->s_dev = 0;
108
                        unlock_super(s);
109
                        MOD_DEC_USE_COUNT;
110
                        return NULL;
111
                }
112
        if (!s->u.ext_sb.s_firstfreeinodenumber)
113
                s->u.ext_sb.s_firstfreeinodeblock = NULL;
114
        else {
115
                block = 2 + (s->u.ext_sb.s_firstfreeinodenumber - 1) / EXT_INODES_PER_BLOCK;
116
                if (!(s->u.ext_sb.s_firstfreeinodeblock = bread(dev, block, BLOCK_SIZE))) {
117
                        printk("ext_read_super: unable to read first free inode block\n");
118
                        brelse(s->u.ext_sb.s_firstfreeblock);
119
                        s->s_dev = 0;
120
                        unlock_super (s);
121
                        MOD_DEC_USE_COUNT;
122
                        return NULL;
123
                }
124
        }
125
        unlock_super(s);
126
        /* set up enough so that it can read an inode */
127
        s->s_dev = dev;
128
        s->s_op = &ext_sops;
129
        if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) {
130
                s->s_dev = 0;
131
                printk("EXT-fs: get root inode failed\n");
132
                MOD_DEC_USE_COUNT;
133
                return NULL;
134
        }
135
        return s;
136
}
137
 
138
void ext_write_super (struct super_block *sb)
139
{
140
        struct buffer_head * bh;
141
        struct ext_super_block * es;
142
 
143
        if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
144
                printk ("ext_write_super: bread failed\n");
145
                return;
146
        }
147
        es = (struct ext_super_block *) bh->b_data;
148
        es->s_firstfreeblock = sb->u.ext_sb.s_firstfreeblocknumber;
149
        es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount;
150
        es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber;
151
        es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount;
152
        mark_buffer_dirty(bh, 1);
153
        brelse (bh);
154
        sb->s_dirt = 0;
155
}
156
 
157
void ext_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
158
{
159
        struct statfs tmp;
160
 
161
        tmp.f_type = EXT_SUPER_MAGIC;
162
        tmp.f_bsize = 1024;
163
        tmp.f_blocks = sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size;
164
        tmp.f_bfree = ext_count_free_blocks(sb);
165
        tmp.f_bavail = tmp.f_bfree;
166
        tmp.f_files = sb->u.ext_sb.s_ninodes;
167
        tmp.f_ffree = ext_count_free_inodes(sb);
168
        tmp.f_namelen = EXT_NAME_LEN;
169
        memcpy_tofs(buf, &tmp, bufsiz);
170
}
171
 
172
#define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
173
 
174
static inline int block_bmap(struct buffer_head * bh, int nr)
175
{
176
        int tmp;
177
 
178
        if (!bh)
179
                return 0;
180
        tmp = ((unsigned long *) bh->b_data)[nr];
181
        brelse(bh);
182
        return tmp;
183
}
184
 
185
int ext_bmap(struct inode * inode,int block)
186
{
187
        int i;
188
 
189
        if (block<0) {
190
                printk("ext_bmap: block<0");
191
                return 0;
192
        }
193
        if (block >= 9+256+256*256+256*256*256) {
194
                printk("ext_bmap: block>big");
195
                return 0;
196
        }
197
        if (block<9)
198
                return inode_bmap(inode,block);
199
        block -= 9;
200
        if (block<256) {
201
                i = inode_bmap(inode,9);
202
                if (!i)
203
                        return 0;
204
                return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
205
        }
206
        block -= 256;
207
        if (block<256*256) {
208
                i = inode_bmap(inode,10);
209
                if (!i)
210
                        return 0;
211
                i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
212
                if (!i)
213
                        return 0;
214
                return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
215
        }
216
        block -= 256*256;
217
        i = inode_bmap(inode,11);
218
        if (!i)
219
                return 0;
220
        i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
221
        if (!i)
222
                return 0;
223
        i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
224
        if (!i)
225
                return 0;
226
        return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
227
}
228
 
229
static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
230
{
231
        int tmp;
232
        unsigned long * p;
233
        struct buffer_head * result;
234
 
235
        p = inode->u.ext_i.i_data + nr;
236
repeat:
237
        tmp = *p;
238
        if (tmp) {
239
                result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
240
                if (tmp == *p)
241
                        return result;
242
                brelse(result);
243
                goto repeat;
244
        }
245
        if (!create)
246
                return NULL;
247
        tmp = ext_new_block(inode->i_sb);
248
        if (!tmp)
249
                return NULL;
250
        result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
251
        if (*p) {
252
                ext_free_block(inode->i_sb,tmp);
253
                brelse(result);
254
                goto repeat;
255
        }
256
        *p = tmp;
257
        inode->i_ctime = CURRENT_TIME;
258
        inode->i_dirt = 1;
259
        return result;
260
}
261
 
262
static struct buffer_head * block_getblk(struct inode * inode,
263
        struct buffer_head * bh, int nr, int create)
264
{
265
        int tmp;
266
        unsigned long * p;
267
        struct buffer_head * result;
268
 
269
        if (!bh)
270
                return NULL;
271
        if (!buffer_uptodate(bh)) {
272
                ll_rw_block(READ, 1, &bh);
273
                wait_on_buffer(bh);
274
                if (!buffer_uptodate(bh)) {
275
                        brelse(bh);
276
                        return NULL;
277
                }
278
        }
279
        p = nr + (unsigned long *) bh->b_data;
280
repeat:
281
        tmp = *p;
282
        if (tmp) {
283
                result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
284
                if (tmp == *p) {
285
                        brelse(bh);
286
                        return result;
287
                }
288
                brelse(result);
289
                goto repeat;
290
        }
291
        if (!create) {
292
                brelse(bh);
293
                return NULL;
294
        }
295
        tmp = ext_new_block(inode->i_sb);
296
        if (!tmp) {
297
                brelse(bh);
298
                return NULL;
299
        }
300
        result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
301
        if (*p) {
302
                ext_free_block(inode->i_sb,tmp);
303
                brelse(result);
304
                goto repeat;
305
        }
306
        *p = tmp;
307
        mark_buffer_dirty(bh, 1);
308
        brelse(bh);
309
        return result;
310
}
311
 
312
struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
313
{
314
        struct buffer_head * bh;
315
 
316
        if (block<0) {
317
                printk("ext_getblk: block<0\n");
318
                return NULL;
319
        }
320
        if (block >= 9+256+256*256+256*256*256) {
321
                printk("ext_getblk: block>big\n");
322
                return NULL;
323
        }
324
        if (block<9)
325
                return inode_getblk(inode,block,create);
326
        block -= 9;
327
        if (block<256) {
328
                bh = inode_getblk(inode,9,create);
329
                return block_getblk(inode,bh,block,create);
330
        }
331
        block -= 256;
332
        if (block<256*256) {
333
                bh = inode_getblk(inode,10,create);
334
                bh = block_getblk(inode,bh,block>>8,create);
335
                return block_getblk(inode,bh,block & 255,create);
336
        }
337
        block -= 256*256;
338
        bh = inode_getblk(inode,11,create);
339
        bh = block_getblk(inode,bh,block>>16,create);
340
        bh = block_getblk(inode,bh,(block>>8) & 255,create);
341
        return block_getblk(inode,bh,block & 255,create);
342
}
343
 
344
struct buffer_head * ext_bread(struct inode * inode, int block, int create)
345
{
346
        struct buffer_head * bh;
347
 
348
        bh = ext_getblk(inode,block,create);
349
        if (!bh || buffer_uptodate(bh))
350
                return bh;
351
        ll_rw_block(READ, 1, &bh);
352
        wait_on_buffer(bh);
353
        if (buffer_uptodate(bh))
354
                return bh;
355
        brelse(bh);
356
        return NULL;
357
}
358
 
359
void ext_read_inode(struct inode * inode)
360
{
361
        struct buffer_head * bh;
362
        struct ext_inode * raw_inode;
363
        int block;
364
 
365
        block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
366
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
367
                panic("unable to read i-node block");
368
        raw_inode = ((struct ext_inode *) bh->b_data) +
369
                (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
370
        inode->i_mode = raw_inode->i_mode;
371
        inode->i_uid = raw_inode->i_uid;
372
        inode->i_gid = raw_inode->i_gid;
373
        inode->i_nlink = raw_inode->i_nlinks;
374
        inode->i_size = raw_inode->i_size;
375
        inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
376
        inode->i_blocks = inode->i_blksize = 0;
377
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
378
                inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]);
379
        else for (block = 0; block < 12; block++)
380
                inode->u.ext_i.i_data[block] = raw_inode->i_zone[block];
381
        brelse(bh);
382
        inode->i_op = NULL;
383
        if (S_ISREG(inode->i_mode))
384
                inode->i_op = &ext_file_inode_operations;
385
        else if (S_ISDIR(inode->i_mode))
386
                inode->i_op = &ext_dir_inode_operations;
387
        else if (S_ISLNK(inode->i_mode))
388
                inode->i_op = &ext_symlink_inode_operations;
389
        else if (S_ISCHR(inode->i_mode))
390
                inode->i_op = &chrdev_inode_operations;
391
        else if (S_ISBLK(inode->i_mode))
392
                inode->i_op = &blkdev_inode_operations;
393
        else if (S_ISFIFO(inode->i_mode))
394
                init_fifo(inode);
395
}
396
 
397
static struct buffer_head * ext_update_inode(struct inode * inode)
398
{
399
        struct buffer_head * bh;
400
        struct ext_inode * raw_inode;
401
        int block;
402
 
403
        block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
404
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
405
                panic("unable to read i-node block");
406
        raw_inode = ((struct ext_inode *)bh->b_data) +
407
                (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
408
        raw_inode->i_mode = inode->i_mode;
409
        raw_inode->i_uid = inode->i_uid;
410
        raw_inode->i_gid = inode->i_gid;
411
        raw_inode->i_nlinks = inode->i_nlink;
412
        raw_inode->i_size = inode->i_size;
413
        raw_inode->i_time = inode->i_mtime;
414
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
415
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
416
        else for (block = 0; block < 12; block++)
417
                raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
418
        mark_buffer_dirty(bh, 1);
419
        inode->i_dirt=0;
420
        return bh;
421
}
422
 
423
void ext_write_inode(struct inode * inode)
424
{
425
        struct buffer_head *bh;
426
        bh = ext_update_inode (inode);
427
        brelse(bh);
428
}
429
 
430
int ext_sync_inode (struct inode *inode)
431
{
432
        int err = 0;
433
        struct buffer_head *bh;
434
 
435
        bh = ext_update_inode(inode);
436
        if (bh && buffer_dirty(bh))
437
        {
438
                ll_rw_block(WRITE, 1, &bh);
439
                wait_on_buffer(bh);
440
                if (buffer_req(bh) && !buffer_uptodate(bh))
441
                {
442
                        printk ("IO error syncing ext inode ["
443
                                "%s:%08lx]\n",
444
                                kdevname(inode->i_dev), inode->i_ino);
445
                        err = -1;
446
                }
447
        }
448
        else if (!bh)
449
                err = -1;
450
        brelse (bh);
451
        return err;
452
}
453
 
454
 
455
static struct file_system_type ext_fs_type = {
456
        ext_read_super, "ext", 1, NULL
457
};
458
 
459
int init_ext_fs(void)
460
{
461
        return register_filesystem(&ext_fs_type);
462
}
463
 
464
#ifdef MODULE
465
int init_module(void)
466
{
467
        int status;
468
 
469
        if ((status = init_ext_fs()) == 0)
470
                register_symtab(0);
471
        return status;
472
}
473
 
474
void cleanup_module(void)
475
{
476
        unregister_filesystem(&ext_fs_type);
477
}
478
 
479
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.