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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [ext2/] [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/ext2/inode.c
3
 *
4
 * Copyright (C) 1992, 1993, 1994, 1995
5
 * Remy Card (card@masi.ibp.fr)
6
 * Laboratoire MASI - Institut Blaise Pascal
7
 * Universite Pierre et Marie Curie (Paris VI)
8
 *
9
 *  from
10
 *
11
 *  linux/fs/minix/inode.c
12
 *
13
 *  Copyright (C) 1991, 1992  Linus Torvalds
14
 *
15
 *  Goal-directed block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
16
 *  Big-endian to little-endian byte-swapping/bitmaps by
17
 *        David S. Miller (davem@caip.rutgers.edu), 1995
18
 */
19
 
20
#include <asm/segment.h>
21
#include <asm/system.h>
22
 
23
#include <linux/errno.h>
24
#include <linux/fs.h>
25
#include <linux/ext2_fs.h>
26
#include <linux/sched.h>
27
#include <linux/stat.h>
28
#include <linux/string.h>
29
#include <linux/locks.h>
30
#include <linux/mm.h>
31
 
32
static int ext2_update_inode(struct inode * inode, int do_sync);
33
 
34
void ext2_put_inode (struct inode * inode)
35
{
36
        ext2_discard_prealloc (inode);
37
        if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
38
            inode->i_ino == EXT2_ACL_DATA_INO)
39
                return;
40
        inode->u.ext2_i.i_dtime = CURRENT_TIME;
41
        inode->i_dirt = 1;
42
        ext2_update_inode(inode, IS_SYNC(inode));
43
        inode->i_size = 0;
44
        if (inode->i_blocks)
45
                ext2_truncate (inode);
46
        ext2_free_inode (inode);
47
}
48
 
49
#define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
50
 
51
static inline int block_bmap (struct buffer_head * bh, int nr)
52
{
53
        int tmp;
54
 
55
        if (!bh)
56
                return 0;
57
        tmp = swab32(((u32 *) bh->b_data)[nr]);
58
        brelse (bh);
59
        return tmp;
60
}
61
 
62
/*
63
 * ext2_discard_prealloc and ext2_alloc_block are atomic wrt. the
64
 * superblock in the same manner as are ext2_free_blocks and
65
 * ext2_new_block.  We just wait on the super rather than locking it
66
 * here, since ext2_new_block will do the necessary locking and we
67
 * can't block until then.
68
 */
69
void ext2_discard_prealloc (struct inode * inode)
70
{
71
#ifdef EXT2_PREALLOCATE
72
        unsigned short total;
73
 
74
        if (inode->u.ext2_i.i_prealloc_count) {
75
                total = inode->u.ext2_i.i_prealloc_count;
76
                inode->u.ext2_i.i_prealloc_count = 0;
77
                ext2_free_blocks (inode, inode->u.ext2_i.i_prealloc_block, total);
78
        }
79
#endif
80
}
81
 
82
static int ext2_alloc_block (struct inode * inode, unsigned long goal, int * err)
83
{
84
#ifdef EXT2FS_DEBUG
85
        static unsigned long alloc_hits = 0, alloc_attempts = 0;
86
#endif
87
        unsigned long result;
88
        struct buffer_head * bh;
89
 
90
        wait_on_super (inode->i_sb);
91
 
92
#ifdef EXT2_PREALLOCATE
93
        if (inode->u.ext2_i.i_prealloc_count &&
94
            (goal == inode->u.ext2_i.i_prealloc_block ||
95
             goal + 1 == inode->u.ext2_i.i_prealloc_block))
96
        {
97
                result = inode->u.ext2_i.i_prealloc_block++;
98
                inode->u.ext2_i.i_prealloc_count--;
99
                ext2_debug ("preallocation hit (%lu/%lu).\n",
100
                            ++alloc_hits, ++alloc_attempts);
101
 
102
                /* It doesn't matter if we block in getblk() since
103
                   we have already atomically allocated the block, and
104
                   are only clearing it now. */
105
                if (!(bh = getblk (inode->i_sb->s_dev, result,
106
                                   inode->i_sb->s_blocksize))) {
107
                        ext2_error (inode->i_sb, "ext2_alloc_block",
108
                                    "cannot get block %lu", result);
109
                        return 0;
110
                }
111
                memset(bh->b_data, 0, inode->i_sb->s_blocksize);
112
                mark_buffer_uptodate(bh, 1);
113
                mark_buffer_dirty(bh, 1);
114
                brelse (bh);
115
        } else {
116
                ext2_discard_prealloc (inode);
117
                ext2_debug ("preallocation miss (%lu/%lu).\n",
118
                            alloc_hits, ++alloc_attempts);
119
                if (S_ISREG(inode->i_mode))
120
                        result = ext2_new_block (inode, goal,
121
                                 &inode->u.ext2_i.i_prealloc_count,
122
                                 &inode->u.ext2_i.i_prealloc_block, err);
123
                else
124
                        result = ext2_new_block (inode, goal, 0, 0, err);
125
        }
126
#else
127
        result = ext2_new_block (inode, goal, 0, 0, err);
128
#endif
129
 
130
        return result;
131
}
132
 
133
 
134
int ext2_bmap (struct inode * inode, int block)
135
{
136
        int i;
137
        int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
138
        int addr_per_block_bits = EXT2_ADDR_PER_BLOCK_BITS(inode->i_sb);
139
 
140
        if (block < 0) {
141
                ext2_warning (inode->i_sb, "ext2_bmap", "block < 0");
142
                return 0;
143
        }
144
        if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
145
                (1 << (addr_per_block_bits * 2)) +
146
                ((1 << (addr_per_block_bits * 2)) << addr_per_block_bits)) {
147
                ext2_warning (inode->i_sb, "ext2_bmap", "block > big");
148
                return 0;
149
        }
150
        if (block < EXT2_NDIR_BLOCKS)
151
                return inode_bmap (inode, block);
152
        block -= EXT2_NDIR_BLOCKS;
153
        if (block < addr_per_block) {
154
                i = inode_bmap (inode, EXT2_IND_BLOCK);
155
                if (!i)
156
                        return 0;
157
                return block_bmap (bread (inode->i_dev, i,
158
                                          inode->i_sb->s_blocksize), block);
159
        }
160
        block -= addr_per_block;
161
        if (block < (1 << (addr_per_block_bits * 2))) {
162
                i = inode_bmap (inode, EXT2_DIND_BLOCK);
163
                if (!i)
164
                        return 0;
165
                i = block_bmap (bread (inode->i_dev, i,
166
                                       inode->i_sb->s_blocksize),
167
                                block >> addr_per_block_bits);
168
                if (!i)
169
                        return 0;
170
                return block_bmap (bread (inode->i_dev, i,
171
                                          inode->i_sb->s_blocksize),
172
                                   block & (addr_per_block - 1));
173
        }
174
        block -= (1 << (addr_per_block_bits * 2));
175
        i = inode_bmap (inode, EXT2_TIND_BLOCK);
176
        if (!i)
177
                return 0;
178
        i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
179
                        block >> (addr_per_block_bits * 2));
180
        if (!i)
181
                return 0;
182
        i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
183
                        (block >> addr_per_block_bits) & (addr_per_block - 1));
184
        if (!i)
185
                return 0;
186
        return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
187
                           block & (addr_per_block - 1));
188
}
189
 
190
static struct buffer_head * inode_getblk (struct inode * inode, int nr,
191
                                          int create, int new_block, int * err)
192
{
193
        u32 * p;
194
        int tmp, goal = 0;
195
        struct buffer_head * result;
196
        int blocks = inode->i_sb->s_blocksize / 512;
197
 
198
        p = inode->u.ext2_i.i_data + nr;
199
repeat:
200
        tmp = *p;
201
        if (tmp) {
202
                result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
203
                if (tmp == *p)
204
                        return result;
205
                brelse (result);
206
                goto repeat;
207
        }
208
        if (!create || new_block >=
209
            (current->rlim[RLIMIT_FSIZE].rlim_cur >>
210
             EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
211
                *err = -EFBIG;
212
                return NULL;
213
        }
214
        if (inode->u.ext2_i.i_next_alloc_block == new_block)
215
                goal = inode->u.ext2_i.i_next_alloc_goal;
216
 
217
        ext2_debug ("hint = %d,", goal);
218
 
219
        if (!goal) {
220
                for (tmp = nr - 1; tmp >= 0; tmp--) {
221
                        if (inode->u.ext2_i.i_data[tmp]) {
222
                                goal = inode->u.ext2_i.i_data[tmp];
223
                                break;
224
                        }
225
                }
226
                if (!goal)
227
                        goal = (inode->u.ext2_i.i_block_group *
228
                                EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
229
                               swab32(inode->i_sb->u.ext2_sb.s_es->s_first_data_block);
230
        }
231
 
232
        ext2_debug ("goal = %d.\n", goal);
233
 
234
        tmp = ext2_alloc_block (inode, goal, err);
235
        if (!tmp)
236
                return NULL;
237
        result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
238
        if (*p) {
239
                ext2_free_blocks (inode, tmp, 1);
240
                brelse (result);
241
                goto repeat;
242
        }
243
        *p = tmp;
244
        inode->u.ext2_i.i_next_alloc_block = new_block;
245
        inode->u.ext2_i.i_next_alloc_goal = tmp;
246
        inode->i_ctime = CURRENT_TIME;
247
        inode->i_blocks += blocks;
248
        if (IS_SYNC(inode) || inode->u.ext2_i.i_osync)
249
                ext2_sync_inode (inode);
250
        else
251
                inode->i_dirt = 1;
252
        return result;
253
}
254
 
255
static struct buffer_head * block_getblk (struct inode * inode,
256
                                          struct buffer_head * bh, int nr,
257
                                          int create, int blocksize,
258
                                          int new_block, int * err)
259
{
260
        int tmp, goal = 0;
261
        u32 * p;
262
        struct buffer_head * result;
263
        int blocks = inode->i_sb->s_blocksize / 512;
264
 
265
        if (!bh)
266
                return NULL;
267
        if (!buffer_uptodate(bh)) {
268
                ll_rw_block (READ, 1, &bh);
269
                wait_on_buffer (bh);
270
                if (!buffer_uptodate(bh)) {
271
                        brelse (bh);
272
                        return NULL;
273
                }
274
        }
275
        p = (u32 *) bh->b_data + nr;
276
repeat:
277
        tmp = swab32(*p);
278
        if (tmp) {
279
                result = getblk (bh->b_dev, tmp, blocksize);
280
                if (tmp == swab32(*p)) {
281
                        brelse (bh);
282
                        return result;
283
                }
284
                brelse (result);
285
                goto repeat;
286
        }
287
        if (!create || new_block >=
288
            (current->rlim[RLIMIT_FSIZE].rlim_cur >>
289
             EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
290
                brelse (bh);
291
                *err = -EFBIG;
292
                return NULL;
293
        }
294
        if (inode->u.ext2_i.i_next_alloc_block == new_block)
295
                goal = inode->u.ext2_i.i_next_alloc_goal;
296
        if (!goal) {
297
                for (tmp = nr - 1; tmp >= 0; tmp--) {
298
                        if (swab32(((u32 *) bh->b_data)[tmp])) {
299
                                goal = swab32(((u32 *)bh->b_data)[tmp]);
300
                                break;
301
                        }
302
                }
303
                if (!goal)
304
                        goal = bh->b_blocknr;
305
        }
306
        tmp = ext2_alloc_block (inode, goal, err);
307
        if (!tmp) {
308
                brelse (bh);
309
                return NULL;
310
        }
311
        result = getblk (bh->b_dev, tmp, blocksize);
312
        if (swab32(*p)) {
313
                ext2_free_blocks (inode, tmp, 1);
314
                brelse (result);
315
                goto repeat;
316
        }
317
        *p = swab32(tmp);
318
        mark_buffer_dirty(bh, 1);
319
        if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
320
                ll_rw_block (WRITE, 1, &bh);
321
                wait_on_buffer (bh);
322
        }
323
        inode->i_ctime = CURRENT_TIME;
324
        inode->i_blocks += blocks;
325
        inode->i_dirt = 1;
326
        inode->u.ext2_i.i_next_alloc_block = new_block;
327
        inode->u.ext2_i.i_next_alloc_goal = tmp;
328
        brelse (bh);
329
        return result;
330
}
331
 
332
struct buffer_head * ext2_getblk (struct inode * inode, long block,
333
                                  int create, int * err)
334
{
335
        struct buffer_head * bh;
336
        unsigned long b;
337
        unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
338
        int addr_per_block_bits = EXT2_ADDR_PER_BLOCK_BITS(inode->i_sb);
339
 
340
        *err = -EIO;
341
        if (block < 0) {
342
                ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
343
                return NULL;
344
        }
345
        if (block > EXT2_NDIR_BLOCKS + addr_per_block +
346
                (1 << (addr_per_block_bits * 2)) +
347
                ((1 << (addr_per_block_bits * 2)) << addr_per_block_bits)) {
348
                ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
349
                return NULL;
350
        }
351
        /*
352
         * If this is a sequential block allocation, set the next_alloc_block
353
         * to this block now so that all the indblock and data block
354
         * allocations use the same goal zone
355
         */
356
 
357
        ext2_debug ("block %lu, next %lu, goal %lu.\n", block,
358
                    inode->u.ext2_i.i_next_alloc_block,
359
                    inode->u.ext2_i.i_next_alloc_goal);
360
 
361
        if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
362
                inode->u.ext2_i.i_next_alloc_block++;
363
                inode->u.ext2_i.i_next_alloc_goal++;
364
        }
365
 
366
        *err = -ENOSPC;
367
        b = block;
368
        if (block < EXT2_NDIR_BLOCKS)
369
                return inode_getblk (inode, block, create, b, err);
370
        block -= EXT2_NDIR_BLOCKS;
371
        if (block < addr_per_block) {
372
                bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);
373
                return block_getblk (inode, bh, block, create,
374
                                     inode->i_sb->s_blocksize, b, err);
375
        }
376
        block -= addr_per_block;
377
        if (block < (1 << (addr_per_block_bits * 2))) {
378
                bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);
379
                bh = block_getblk (inode, bh, block >> addr_per_block_bits,
380
                                   create, inode->i_sb->s_blocksize, b, err);
381
                return block_getblk (inode, bh, block & (addr_per_block - 1),
382
                                     create, inode->i_sb->s_blocksize, b, err);
383
        }
384
        block -= (1 << (addr_per_block_bits * 2));
385
        bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);
386
        bh = block_getblk (inode, bh, block >> (addr_per_block_bits * 2),
387
                           create, inode->i_sb->s_blocksize, b, err);
388
        bh = block_getblk (inode, bh, (block >> addr_per_block_bits) & (addr_per_block - 1),
389
                           create, inode->i_sb->s_blocksize, b, err);
390
        return block_getblk (inode, bh, block & (addr_per_block - 1), create,
391
                             inode->i_sb->s_blocksize, b, err);
392
}
393
 
394
struct buffer_head * ext2_bread (struct inode * inode, int block,
395
                                 int create, int *err)
396
{
397
        struct buffer_head * bh;
398
 
399
        bh = ext2_getblk (inode, block, create, err);
400
        if (!bh || buffer_uptodate(bh))
401
                return bh;
402
        ll_rw_block (READ, 1, &bh);
403
        wait_on_buffer (bh);
404
        if (buffer_uptodate(bh))
405
                return bh;
406
        brelse (bh);
407
        *err = -EIO;
408
        return NULL;
409
}
410
 
411
void ext2_read_inode (struct inode * inode)
412
{
413
        struct buffer_head * bh;
414
        struct ext2_inode * raw_inode;
415
        unsigned long block_group;
416
        unsigned long group_desc;
417
        unsigned long desc;
418
        unsigned long block;
419
        unsigned long offset;
420
        struct ext2_group_desc * gdp;
421
 
422
        if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
423
             inode->i_ino != EXT2_ACL_DATA_INO &&
424
             inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
425
            inode->i_ino > swab32(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
426
                ext2_error (inode->i_sb, "ext2_read_inode",
427
                            "bad inode number: %lu", inode->i_ino);
428
                return;
429
        }
430
        block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
431
        if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
432
                ext2_panic (inode->i_sb, "ext2_read_inode",
433
                            "group >= groups count");
434
        group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);
435
        desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);
436
        bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
437
        if (!bh) {
438
                ext2_error (inode->i_sb, "ext2_read_inode",
439
                            "Descriptor not loaded");
440
                goto bad_inode;
441
        }
442
 
443
        gdp = (struct ext2_group_desc *) bh->b_data;
444
        /*
445
         * Figure out the offset within the block group inode table
446
         */
447
        offset = ((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb)) *
448
                EXT2_INODE_SIZE(inode->i_sb);
449
        block = swab32(gdp[desc].bg_inode_table) +
450
                (offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));
451
        if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) {
452
                ext2_error (inode->i_sb, "ext2_read_inode",
453
                            "unable to read i-node block - "
454
                            "inode=%lu, block=%lu", inode->i_ino, block);
455
                goto bad_inode;
456
        }
457
 
458
        offset &= (EXT2_BLOCK_SIZE(inode->i_sb) - 1);
459
        raw_inode = (struct ext2_inode *) (bh->b_data + offset);
460
 
461
        inode->i_mode = swab16(raw_inode->i_mode);
462
        inode->i_uid = swab16(raw_inode->i_uid);
463
        inode->i_gid = swab16(raw_inode->i_gid);
464
        inode->i_nlink = swab16(raw_inode->i_links_count);
465
        inode->i_size = swab32(raw_inode->i_size);
466
        inode->i_atime = swab32(raw_inode->i_atime);
467
        inode->i_ctime = swab32(raw_inode->i_ctime);
468
        inode->i_mtime = swab32(raw_inode->i_mtime);
469
        inode->u.ext2_i.i_dtime = swab32(raw_inode->i_dtime);
470
        inode->i_blksize = PAGE_SIZE;   /* This is the optimal IO size (for stat), not the fs block size */
471
        inode->i_blocks = swab32(raw_inode->i_blocks);
472
        inode->i_version = ++event;
473
        inode->u.ext2_i.i_new_inode = 0;
474
        inode->u.ext2_i.i_flags = swab32(raw_inode->i_flags);
475
        inode->u.ext2_i.i_faddr = swab32(raw_inode->i_faddr);
476
        inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
477
        inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
478
        inode->u.ext2_i.i_osync = 0;
479
        inode->u.ext2_i.i_file_acl = swab32(raw_inode->i_file_acl);
480
        inode->u.ext2_i.i_dir_acl = swab32(raw_inode->i_dir_acl);
481
        inode->u.ext2_i.i_version = swab32(raw_inode->i_version);
482
        inode->u.ext2_i.i_block_group = block_group;
483
        inode->u.ext2_i.i_next_alloc_block = 0;
484
        inode->u.ext2_i.i_next_alloc_goal = 0;
485
        if (inode->u.ext2_i.i_prealloc_count)
486
                ext2_error (inode->i_sb, "ext2_read_inode",
487
                            "New inode has non-zero prealloc count!");
488
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
489
                inode->i_rdev = to_kdev_t(swab32(raw_inode->i_block[0]));
490
        else if (S_ISLNK(inode->i_mode) && !inode->i_blocks)
491
                for (block = 0; block < EXT2_N_BLOCKS; block++)
492
                        inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
493
        else for (block = 0; block < EXT2_N_BLOCKS; block++)
494
                inode->u.ext2_i.i_data[block] = swab32(raw_inode->i_block[block]);
495
        brelse (bh);
496
        inode->i_op = NULL;
497
        if (inode->i_ino == EXT2_ACL_IDX_INO ||
498
            inode->i_ino == EXT2_ACL_DATA_INO)
499
                /* Nothing to do */ ;
500
        else if (S_ISREG(inode->i_mode))
501
                inode->i_op = &ext2_file_inode_operations;
502
        else if (S_ISDIR(inode->i_mode))
503
                inode->i_op = &ext2_dir_inode_operations;
504
        else if (S_ISLNK(inode->i_mode))
505
                inode->i_op = &ext2_symlink_inode_operations;
506
        else if (S_ISCHR(inode->i_mode))
507
                inode->i_op = &chrdev_inode_operations;
508
        else if (S_ISBLK(inode->i_mode))
509
                inode->i_op = &blkdev_inode_operations;
510
        else if (S_ISFIFO(inode->i_mode))
511
                init_fifo(inode);
512
        if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
513
                inode->i_flags |= MS_SYNCHRONOUS;
514
        if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL)
515
                inode->i_flags |= S_APPEND;
516
        if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)
517
                inode->i_flags |= S_IMMUTABLE;
518
        if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL)
519
                inode->i_flags |= MS_NOATIME;
520
        return;
521
 
522
bad_inode:
523
        make_bad_inode(inode);
524
        return;
525
}
526
 
527
static int ext2_update_inode(struct inode * inode, int do_sync)
528
{
529
        struct buffer_head * bh;
530
        struct ext2_inode * raw_inode;
531
        unsigned long block_group;
532
        unsigned long group_desc;
533
        unsigned long desc;
534
        unsigned long block;
535
        unsigned long offset;
536
        int err = 0;
537
        struct ext2_group_desc * gdp;
538
 
539
        if ((inode->i_ino != EXT2_ROOT_INO &&
540
             inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
541
            inode->i_ino > swab32(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
542
                ext2_error (inode->i_sb, "ext2_write_inode",
543
                            "bad inode number: %lu", inode->i_ino);
544
                return 0;
545
        }
546
        block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
547
        if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
548
                ext2_panic (inode->i_sb, "ext2_write_inode",
549
                            "group >= groups count");
550
        group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);
551
        desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);
552
        bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
553
        if (!bh)
554
                ext2_panic (inode->i_sb, "ext2_write_inode",
555
                            "Descriptor not loaded");
556
        gdp = (struct ext2_group_desc *) bh->b_data;
557
        /*
558
         * Figure out the offset within the block group inode table
559
         */
560
        offset = ((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb)) *
561
                EXT2_INODE_SIZE(inode->i_sb);
562
        block = swab32(gdp[desc].bg_inode_table) +
563
                (offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));
564
        if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) {
565
                ext2_error (inode->i_sb, "ext2_write_inode",
566
                            "unable to read i-node block - "
567
                            "inode=%lu, block=%lu", inode->i_ino, block);
568
                /*
569
                 * Unfortunately we're in a lose-lose situation.  I think that
570
                 * keeping the inode in-core with the dirty bit set is
571
                 * the worse option, since that will soak up inodes until
572
                 * the end of the world.  Clearing the dirty bit is nasty if
573
                 * we haven't succeeded in writing out, but it's less nasty
574
                 * than the alternative. -- sct
575
                 */
576
                inode->i_dirt = 0;
577
 
578
                return -EIO;
579
        }
580
 
581
        offset &= EXT2_BLOCK_SIZE(inode->i_sb) - 1;
582
        raw_inode = (struct ext2_inode *) (bh->b_data + offset);
583
 
584
        raw_inode->i_mode = swab16(inode->i_mode);
585
        raw_inode->i_uid = swab16(inode->i_uid);
586
        raw_inode->i_gid = swab16(inode->i_gid);
587
        raw_inode->i_links_count = swab16(inode->i_nlink);
588
        raw_inode->i_size = swab32(inode->i_size);
589
        raw_inode->i_atime = swab32(inode->i_atime);
590
        raw_inode->i_ctime = swab32(inode->i_ctime);
591
        raw_inode->i_mtime = swab32(inode->i_mtime);
592
        raw_inode->i_blocks = swab32(inode->i_blocks);
593
        raw_inode->i_dtime = swab32(inode->u.ext2_i.i_dtime);
594
        raw_inode->i_flags = swab32(inode->u.ext2_i.i_flags);
595
        raw_inode->i_faddr = swab32(inode->u.ext2_i.i_faddr);
596
        raw_inode->i_frag = inode->u.ext2_i.i_frag_no;
597
        raw_inode->i_fsize = inode->u.ext2_i.i_frag_size;
598
        raw_inode->i_file_acl = swab32(inode->u.ext2_i.i_file_acl);
599
        raw_inode->i_dir_acl = swab32(inode->u.ext2_i.i_dir_acl);
600
        raw_inode->i_version = swab32(inode->u.ext2_i.i_version);
601
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
602
                raw_inode->i_block[0] = swab32(kdev_t_to_nr(inode->i_rdev));
603
        else if (S_ISLNK(inode->i_mode) && !inode->i_blocks)
604
                for (block = 0; block < EXT2_N_BLOCKS; block++)
605
                        raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
606
        else for (block = 0; block < EXT2_N_BLOCKS; block++)
607
                raw_inode->i_block[block] = swab32(inode->u.ext2_i.i_data[block]);
608
        mark_buffer_dirty(bh, 1);
609
        inode->i_dirt = 0;
610
        if (do_sync) {
611
                ll_rw_block (WRITE, 1, &bh);
612
                wait_on_buffer (bh);
613
                if (buffer_req(bh) && !buffer_uptodate(bh)) {
614
                        ext2_error (inode->i_sb,
615
                                    "IO error syncing ext2 inode ["
616
                                    "%s:%08lx]\n",
617
                                    kdevname(inode->i_dev), inode->i_ino);
618
                        err = -EIO;
619
                }
620
        }
621
        brelse (bh);
622
        return err;
623
}
624
 
625
void ext2_write_inode (struct inode * inode)
626
{
627
        ext2_update_inode (inode, 0);
628
}
629
 
630
int ext2_sync_inode (struct inode *inode)
631
{
632
        return ext2_update_inode (inode, 1);
633
}
634
 

powered by: WebSVN 2.1.0

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