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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [fs/] [ext/] [fsync.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
 
2
/*
3
 *  linux/fs/ext/fsync.c
4
 *
5
 *  Copyright (C) 1993  Stephen Tweedie (sct@dcs.ed.ac.uk)
6
 *  from
7
 *  Copyright (C) 1992  Remy Card (card@masi.ibp.fr)
8
 *  from
9
 *  linux/fs/minix/truncate.c   Copyright (C) 1991, 1992  Linus Torvalds
10
 *
11
 *  extfs fsync primitive
12
 */
13
 
14
#include <asm/segment.h>
15
#include <asm/system.h>
16
 
17
#include <linux/errno.h>
18
#include <linux/sched.h>
19
#include <linux/stat.h>
20
#include <linux/fcntl.h>
21
#include <linux/locks.h>
22
 
23
#include <linux/fs.h>
24
#include <linux/ext_fs.h>
25
 
26
 
27
#define blocksize BLOCK_SIZE
28
#define addr_per_block 256
29
 
30
static int sync_block (struct inode * inode, unsigned long * block, int wait)
31
{
32
        struct buffer_head * bh;
33
        int tmp;
34
 
35
        if (!*block)
36
                return 0;
37
        tmp = *block;
38
        bh = get_hash_table(inode->i_dev, *block, blocksize);
39
        if (!bh)
40
                return 0;
41
        if (*block != tmp) {
42
                brelse (bh);
43
                return 1;
44
        }
45
        if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
46
                brelse(bh);
47
                return -1;
48
        }
49
        if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
50
        {
51
                brelse(bh);
52
                return 0;
53
        }
54
        ll_rw_block(WRITE, 1, &bh);
55
        bh->b_count--;
56
        return 0;
57
}
58
 
59
static int sync_iblock (struct inode * inode, unsigned long * iblock,
60
                        struct buffer_head **bh, int wait)
61
{
62
        int rc, tmp;
63
 
64
        *bh = NULL;
65
        tmp = *iblock;
66
        if (!tmp)
67
                return 0;
68
        rc = sync_block (inode, iblock, wait);
69
        if (rc)
70
                return rc;
71
        *bh = bread(inode->i_dev, tmp, blocksize);
72
        if (tmp != *iblock) {
73
                brelse(*bh);
74
                *bh = NULL;
75
                return 1;
76
        }
77
        if (!*bh)
78
                return -1;
79
        return 0;
80
}
81
 
82
 
83
static int sync_direct(struct inode *inode, int wait)
84
{
85
        int i;
86
        int rc, err = 0;
87
 
88
        for (i = 0; i < 9; i++) {
89
                rc = sync_block (inode, inode->u.ext_i.i_data + i, wait);
90
                if (rc > 0)
91
                        break;
92
                if (rc)
93
                        err = rc;
94
        }
95
        return err;
96
}
97
 
98
static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
99
{
100
        int i;
101
        struct buffer_head * ind_bh;
102
        int rc, err = 0;
103
 
104
        rc = sync_iblock (inode, iblock, &ind_bh, wait);
105
        if (rc || !ind_bh)
106
                return rc;
107
 
108
        for (i = 0; i < addr_per_block; i++) {
109
                rc = sync_block (inode,
110
                                 ((unsigned long *) ind_bh->b_data) + i,
111
                                 wait);
112
                if (rc > 0)
113
                        break;
114
                if (rc)
115
                        err = rc;
116
        }
117
        brelse(ind_bh);
118
        return err;
119
}
120
 
121
static int sync_dindirect(struct inode *inode, unsigned long *diblock,
122
                          int wait)
123
{
124
        int i;
125
        struct buffer_head * dind_bh;
126
        int rc, err = 0;
127
 
128
        rc = sync_iblock (inode, diblock, &dind_bh, wait);
129
        if (rc || !dind_bh)
130
                return rc;
131
 
132
        for (i = 0; i < addr_per_block; i++) {
133
                rc = sync_indirect (inode,
134
                                    ((unsigned long *) dind_bh->b_data) + i,
135
                                    wait);
136
                if (rc > 0)
137
                        break;
138
                if (rc)
139
                        err = rc;
140
        }
141
        brelse(dind_bh);
142
        return err;
143
}
144
 
145
static int sync_tindirect(struct inode *inode, unsigned long *tiblock,
146
                          int wait)
147
{
148
        int i;
149
        struct buffer_head * tind_bh;
150
        int rc, err = 0;
151
 
152
        rc = sync_iblock (inode, tiblock, &tind_bh, wait);
153
        if (rc || !tind_bh)
154
                return rc;
155
 
156
        for (i = 0; i < addr_per_block; i++) {
157
                rc = sync_dindirect (inode,
158
                                     ((unsigned long *) tind_bh->b_data) + i,
159
                                     wait);
160
                if (rc > 0)
161
                        break;
162
                if (rc)
163
                        err = rc;
164
        }
165
        brelse(tind_bh);
166
        return err;
167
}
168
 
169
int ext_sync_file(struct inode * inode, struct file *file)
170
{
171
        int wait, err = 0;
172
 
173
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
174
             S_ISLNK(inode->i_mode)))
175
                return -EINVAL;
176
        for (wait=0; wait<=1; wait++)
177
        {
178
                err |= sync_direct(inode, wait);
179
                err |= sync_indirect(inode, inode->u.ext_i.i_data+9, wait);
180
                err |= sync_dindirect(inode, inode->u.ext_i.i_data+10, wait);
181
                err |= sync_tindirect(inode, inode->u.ext_i.i_data+11, wait);
182
        }
183
        err |= ext_sync_inode (inode);
184
        return (err < 0) ? -EIO : 0;
185
}

powered by: WebSVN 2.1.0

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