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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [xiafs/] [fsync.c] - Blame information for rev 1777

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

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

powered by: WebSVN 2.1.0

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