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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/fs/minix/fsync.c
3
 *
4
 *  Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
5
 *  from
6
 *  Copyright (C) 1991, 1992 Linus Torvalds
7
 *
8
 *  Copyright (C) 1996 Gertjan van Wingerde (gertjan@cs.vu.nl)
9
 *      Minix V2 fs support
10
 *
11
 *  minix fsync primitive
12
 */
13
 
14
#include <linux/errno.h>
15
#include <linux/sched.h>
16
#include <linux/stat.h>
17
#include <linux/fcntl.h>
18
#include <linux/locks.h>
19
 
20
#include <linux/fs.h>
21
#include <linux/minix_fs.h>
22
 
23
#include <asm/segment.h>
24
#include <asm/system.h>
25
 
26
#define blocksize BLOCK_SIZE
27
 
28
/*
29
 * The functions for minix V1 fs file synchronization.
30
 */
31
static int V1_sync_block (struct inode * inode, unsigned short * block, int wait)
32
{
33
        struct buffer_head * bh;
34
        unsigned short tmp;
35
 
36
        if (!*block)
37
                return 0;
38
        tmp = *block;
39
        bh = get_hash_table(inode->i_dev, *block, blocksize);
40
        if (!bh)
41
                return 0;
42
        if (*block != tmp) {
43
                brelse (bh);
44
                return 1;
45
        }
46
        if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
47
                brelse(bh);
48
                return -1;
49
        }
50
        if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
51
        {
52
                brelse(bh);
53
                return 0;
54
        }
55
        ll_rw_block(WRITE, 1, &bh);
56
        bh->b_count--;
57
        return 0;
58
}
59
 
60
static int V1_sync_iblock (struct inode * inode, unsigned short * iblock,
61
                        struct buffer_head **bh, int wait)
62
{
63
        int rc;
64
        unsigned short tmp;
65
 
66
        *bh = NULL;
67
        tmp = *iblock;
68
        if (!tmp)
69
                return 0;
70
        rc = V1_sync_block (inode, iblock, wait);
71
        if (rc)
72
                return rc;
73
        *bh = bread(inode->i_dev, tmp, blocksize);
74
        if (tmp != *iblock) {
75
                brelse(*bh);
76
                *bh = NULL;
77
                return 1;
78
        }
79
        if (!*bh)
80
                return -1;
81
        return 0;
82
}
83
 
84
static int V1_sync_direct(struct inode *inode, int wait)
85
{
86
        int i;
87
        int rc, err = 0;
88
 
89
        for (i = 0; i < 7; i++) {
90
                rc = V1_sync_block (inode,
91
                     (unsigned short *) inode->u.minix_i.u.i1_data + i, wait);
92
                if (rc > 0)
93
                        break;
94
                if (rc)
95
                        err = rc;
96
        }
97
        return err;
98
}
99
 
100
static int V1_sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
101
{
102
        int i;
103
        struct buffer_head * ind_bh;
104
        int rc, err = 0;
105
 
106
        rc = V1_sync_iblock (inode, iblock, &ind_bh, wait);
107
        if (rc || !ind_bh)
108
                return rc;
109
 
110
        for (i = 0; i < 512; i++) {
111
                rc = V1_sync_block (inode,
112
                                    ((unsigned short *) ind_bh->b_data) + i,
113
                                    wait);
114
                if (rc > 0)
115
                        break;
116
                if (rc)
117
                        err = rc;
118
        }
119
        brelse(ind_bh);
120
        return err;
121
}
122
 
123
static int V1_sync_dindirect(struct inode *inode, unsigned short *diblock,
124
                          int wait)
125
{
126
        int i;
127
        struct buffer_head * dind_bh;
128
        int rc, err = 0;
129
 
130
        rc = V1_sync_iblock (inode, diblock, &dind_bh, wait);
131
        if (rc || !dind_bh)
132
                return rc;
133
 
134
        for (i = 0; i < 512; i++) {
135
                rc = V1_sync_indirect (inode,
136
                                       ((unsigned short *) dind_bh->b_data) + i,
137
                                       wait);
138
                if (rc > 0)
139
                        break;
140
                if (rc)
141
                        err = rc;
142
        }
143
        brelse(dind_bh);
144
        return err;
145
}
146
 
147
int V1_minix_sync_file(struct inode * inode, struct file * file)
148
{
149
        int wait, err = 0;
150
 
151
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
152
             S_ISLNK(inode->i_mode)))
153
                return -EINVAL;
154
 
155
        for (wait=0; wait<=1; wait++)
156
        {
157
                err |= V1_sync_direct(inode, wait);
158
                err |= V1_sync_indirect(inode, inode->u.minix_i.u.i1_data + 7, wait);
159
                err |= V1_sync_dindirect(inode, inode->u.minix_i.u.i1_data + 8, wait);
160
        }
161
        err |= minix_sync_inode (inode);
162
        return (err < 0) ? -EIO : 0;
163
}
164
 
165
/*
166
 * The functions for minix V2 fs file synchronization.
167
 */
168
static int V2_sync_block (struct inode * inode, unsigned long * block, int wait)
169
{
170
        struct buffer_head * bh;
171
        unsigned long tmp;
172
 
173
        if (!*block)
174
                return 0;
175
        tmp = *block;
176
        bh = get_hash_table(inode->i_dev, *block, blocksize);
177
        if (!bh)
178
                return 0;
179
        if (*block != tmp) {
180
                brelse (bh);
181
                return 1;
182
        }
183
        if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
184
                brelse(bh);
185
                return -1;
186
        }
187
        if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
188
        {
189
                brelse(bh);
190
                return 0;
191
        }
192
        ll_rw_block(WRITE, 1, &bh);
193
        bh->b_count--;
194
        return 0;
195
}
196
 
197
static int V2_sync_iblock (struct inode * inode, unsigned long * iblock,
198
                        struct buffer_head **bh, int wait)
199
{
200
        int rc;
201
        unsigned long tmp;
202
 
203
        *bh = NULL;
204
        tmp = *iblock;
205
        if (!tmp)
206
                return 0;
207
        rc = V2_sync_block (inode, iblock, wait);
208
        if (rc)
209
                return rc;
210
        *bh = bread(inode->i_dev, tmp, blocksize);
211
        if (tmp != *iblock) {
212
                brelse(*bh);
213
                *bh = NULL;
214
                return 1;
215
        }
216
        if (!*bh)
217
                return -1;
218
        return 0;
219
}
220
 
221
static int V2_sync_direct(struct inode *inode, int wait)
222
{
223
        int i;
224
        int rc, err = 0;
225
 
226
        for (i = 0; i < 7; i++) {
227
                rc = V2_sync_block (inode,
228
                        (unsigned long *)inode->u.minix_i.u.i2_data + i, wait);
229
                if (rc > 0)
230
                        break;
231
                if (rc)
232
                        err = rc;
233
        }
234
        return err;
235
}
236
 
237
static int V2_sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
238
{
239
        int i;
240
        struct buffer_head * ind_bh;
241
        int rc, err = 0;
242
 
243
        rc = V2_sync_iblock (inode, iblock, &ind_bh, wait);
244
        if (rc || !ind_bh)
245
                return rc;
246
 
247
        for (i = 0; i < 256; i++) {
248
                rc = V2_sync_block (inode,
249
                                    ((unsigned long *) ind_bh->b_data) + i,
250
                                    wait);
251
                if (rc > 0)
252
                        break;
253
                if (rc)
254
                        err = rc;
255
        }
256
        brelse(ind_bh);
257
        return err;
258
}
259
 
260
static int V2_sync_dindirect(struct inode *inode, unsigned long *diblock,
261
                          int wait)
262
{
263
        int i;
264
        struct buffer_head * dind_bh;
265
        int rc, err = 0;
266
 
267
        rc = V2_sync_iblock (inode, diblock, &dind_bh, wait);
268
        if (rc || !dind_bh)
269
                return rc;
270
 
271
        for (i = 0; i < 256; i++) {
272
                rc = V2_sync_indirect (inode,
273
                                       ((unsigned long *) dind_bh->b_data) + i,
274
                                       wait);
275
                if (rc > 0)
276
                        break;
277
                if (rc)
278
                        err = rc;
279
        }
280
        brelse(dind_bh);
281
        return err;
282
}
283
 
284
static int V2_sync_tindirect(struct inode *inode, unsigned long *tiblock,
285
                          int wait)
286
{
287
        int i;
288
        struct buffer_head * tind_bh;
289
        int rc, err = 0;
290
 
291
        rc = V2_sync_iblock (inode, tiblock, &tind_bh, wait);
292
        if (rc || !tind_bh)
293
                return rc;
294
 
295
        for (i = 0; i < 256; i++) {
296
                rc = V2_sync_dindirect (inode,
297
                                        ((unsigned long *) tind_bh->b_data) + i,
298
                                        wait);
299
                if (rc > 0)
300
                        break;
301
                if (rc)
302
                        err = rc;
303
        }
304
        brelse(tind_bh);
305
        return err;
306
}
307
 
308
int V2_minix_sync_file(struct inode * inode, struct file * file)
309
{
310
        int wait, err = 0;
311
 
312
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
313
             S_ISLNK(inode->i_mode)))
314
                return -EINVAL;
315
 
316
        for (wait=0; wait<=1; wait++)
317
        {
318
                err |= V2_sync_direct(inode, wait);
319
                err |= V2_sync_indirect(inode,
320
                      (unsigned long *) inode->u.minix_i.u.i2_data + 7, wait);
321
                err |= V2_sync_dindirect(inode,
322
                      (unsigned long *) inode->u.minix_i.u.i2_data + 8, wait);
323
                err |= V2_sync_tindirect(inode,
324
                      (unsigned long *) inode->u.minix_i.u.i2_data + 9, wait);
325
        }
326
        err |= minix_sync_inode (inode);
327
        return (err < 0) ? -EIO : 0;
328
}
329
 
330
/*
331
 * The function which is called for file synchronization.
332
 */
333
int minix_sync_file(struct inode * inode, struct file * file)
334
{
335
        if (INODE_VERSION(inode) == MINIX_V1)
336
                return V1_minix_sync_file(inode, file);
337
        else
338
                return V2_minix_sync_file(inode, file);
339
}

powered by: WebSVN 2.1.0

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