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