diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-07 09:30:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-11 21:36:11 -0400 |
commit | 79d25767583e4e086f8309bfd1f502660a64fe7f (patch) | |
tree | f13414f324d859f82c604bb4027a4aab19bed909 /fs/qnx4/fsync.c | |
parent | d5aacad548db1ff547adf35d0a77eb2a8ed4fe14 (diff) |
Sanitize qnx4 fsync handling
* have directory operations use mark_buffer_dirty_inode(),
so that sync_mapping_buffers() would get those.
* make qnx4_write_inode() honour its last argument.
* get rid of insane copies of very ancient "walk the indirect blocks"
in qnx4/fsync - they never matched the actual fs layout and, fortunately,
never'd been called. Again, all this junk is not needed; ->fsync()
should just do sync_mapping_buffers + sync_inode (and if we implement
block allocation for qnx4, we'll need to use mark_buffer_dirty_inode()
for extent blocks)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/qnx4/fsync.c')
-rw-r--r-- | fs/qnx4/fsync.c | 169 |
1 files changed, 0 insertions, 169 deletions
diff --git a/fs/qnx4/fsync.c b/fs/qnx4/fsync.c deleted file mode 100644 index aa3b19544bee..000000000000 --- a/fs/qnx4/fsync.c +++ /dev/null | |||
@@ -1,169 +0,0 @@ | |||
1 | /* | ||
2 | * QNX4 file system, Linux implementation. | ||
3 | * | ||
4 | * Version : 0.1 | ||
5 | * | ||
6 | * Using parts of the xiafs filesystem. | ||
7 | * | ||
8 | * History : | ||
9 | * | ||
10 | * 24-03-1998 by Richard Frowijn : first release. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/time.h> | ||
15 | #include <linux/stat.h> | ||
16 | #include <linux/fcntl.h> | ||
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/buffer_head.h> | ||
19 | |||
20 | #include <linux/fs.h> | ||
21 | #include <linux/qnx4_fs.h> | ||
22 | |||
23 | #include <asm/system.h> | ||
24 | |||
25 | /* | ||
26 | * The functions for qnx4 fs file synchronization. | ||
27 | */ | ||
28 | |||
29 | #ifdef CONFIG_QNX4FS_RW | ||
30 | |||
31 | static int 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 = sb_find_get_block(inode->i_sb, *block); | ||
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 | brelse(bh); | ||
52 | return 0; | ||
53 | } | ||
54 | ll_rw_block(WRITE, 1, &bh); | ||
55 | atomic_dec(&bh->b_count); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | #ifdef WTF | ||
60 | static int 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 = sync_block(inode, iblock, wait); | ||
71 | if (rc) | ||
72 | return rc; | ||
73 | *bh = sb_bread(inode->i_sb, tmp); | ||
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 | #endif | ||
84 | |||
85 | static int sync_direct(struct inode *inode, int wait) | ||
86 | { | ||
87 | int i; | ||
88 | int rc, err = 0; | ||
89 | |||
90 | for (i = 0; i < 7; i++) { | ||
91 | rc = sync_block(inode, | ||
92 | (unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait); | ||
93 | if (rc > 0) | ||
94 | break; | ||
95 | if (rc) | ||
96 | err = rc; | ||
97 | } | ||
98 | return err; | ||
99 | } | ||
100 | |||
101 | #ifdef WTF | ||
102 | static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait) | ||
103 | { | ||
104 | int i; | ||
105 | struct buffer_head *ind_bh; | ||
106 | int rc, err = 0; | ||
107 | |||
108 | rc = sync_iblock(inode, iblock, &ind_bh, wait); | ||
109 | if (rc || !ind_bh) | ||
110 | return rc; | ||
111 | |||
112 | for (i = 0; i < 512; i++) { | ||
113 | rc = sync_block(inode, | ||
114 | ((unsigned short *) ind_bh->b_data) + i, | ||
115 | wait); | ||
116 | if (rc > 0) | ||
117 | break; | ||
118 | if (rc) | ||
119 | err = rc; | ||
120 | } | ||
121 | brelse(ind_bh); | ||
122 | return err; | ||
123 | } | ||
124 | |||
125 | static int sync_dindirect(struct inode *inode, unsigned short *diblock, | ||
126 | int wait) | ||
127 | { | ||
128 | int i; | ||
129 | struct buffer_head *dind_bh; | ||
130 | int rc, err = 0; | ||
131 | |||
132 | rc = sync_iblock(inode, diblock, &dind_bh, wait); | ||
133 | if (rc || !dind_bh) | ||
134 | return rc; | ||
135 | |||
136 | for (i = 0; i < 512; i++) { | ||
137 | rc = sync_indirect(inode, | ||
138 | ((unsigned short *) dind_bh->b_data) + i, | ||
139 | wait); | ||
140 | if (rc > 0) | ||
141 | break; | ||
142 | if (rc) | ||
143 | err = rc; | ||
144 | } | ||
145 | brelse(dind_bh); | ||
146 | return err; | ||
147 | } | ||
148 | #endif | ||
149 | |||
150 | int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused) | ||
151 | { | ||
152 | struct inode *inode = dentry->d_inode; | ||
153 | int wait, err = 0; | ||
154 | |||
155 | (void) file; | ||
156 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
157 | S_ISLNK(inode->i_mode))) | ||
158 | return -EINVAL; | ||
159 | |||
160 | lock_kernel(); | ||
161 | for (wait = 0; wait <= 1; wait++) { | ||
162 | err |= sync_direct(inode, wait); | ||
163 | } | ||
164 | err |= qnx4_sync_inode(inode); | ||
165 | unlock_kernel(); | ||
166 | return (err < 0) ? -EIO : 0; | ||
167 | } | ||
168 | |||
169 | #endif | ||