This source file includes following definitions.
- sync_block
- sync_iblock
- sync_direct
- sync_indirect
- sync_dindirect
- xiafs_sync_file
1
2
3
4
5
6
7
8
9
10
11 #include <asm/segment.h>
12 #include <asm/system.h>
13
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/tty.h>
17 #include <linux/stat.h>
18 #include <linux/fcntl.h>
19 #include <linux/locks.h>
20
21 #include <linux/fs.h>
22 #include <linux/xia_fs.h>
23
24 #include "xiafs_mac.h"
25
26
27 #define blocksize (XIAFS_ZSIZE(inode->i_sb))
28 #define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb))
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 && bh->b_req && !bh->b_uptodate) {
46 brelse(bh);
47 return -1;
48 }
49 if (wait || !bh->b_uptodate || !bh->b_dirt)
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 < 8; 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 int xiafs_sync_file(struct inode * inode, struct file * file)
146 {
147 int wait, err = 0;
148
149 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
150 S_ISLNK(inode->i_mode)))
151 return -EINVAL;
152 for (wait=0; wait<=1; wait++)
153 {
154 err |= sync_direct(inode, wait);
155 err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait);
156 err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait);
157 }
158 err |= xiafs_sync_inode (inode);
159 return (err < 0) ? -EIO : 0;
160 }