1
2
3
4
5#include <linux/time.h>
6#include <linux/reiserfs_fs.h>
7#include <linux/reiserfs_acl.h>
8#include <linux/reiserfs_xattr.h>
9#include <asm/uaccess.h>
10#include <linux/pagemap.h>
11#include <linux/swap.h>
12#include <linux/writeback.h>
13#include <linux/blkdev.h>
14#include <linux/buffer_head.h>
15#include <linux/quotaops.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32static int reiserfs_file_release(struct inode *inode, struct file *filp)
33{
34
35 struct reiserfs_transaction_handle th;
36 int err;
37 int jbegin_failure = 0;
38
39 BUG_ON(!S_ISREG(inode->i_mode));
40
41
42 if ((atomic_read(&inode->i_count) > 1 ||
43 !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
44 !tail_has_to_be_packed(inode)) &&
45 REISERFS_I(inode)->i_prealloc_count <= 0) {
46 return 0;
47 }
48
49 mutex_lock(&inode->i_mutex);
50
51 mutex_lock(&(REISERFS_I(inode)->i_mmap));
52 if (REISERFS_I(inode)->i_flags & i_ever_mapped)
53 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
54
55 reiserfs_write_lock(inode->i_sb);
56
57
58
59
60
61 err = journal_begin(&th, inode->i_sb, 1);
62 if (err) {
63
64
65
66
67 jbegin_failure = err;
68 err = journal_join_abort(&th, inode->i_sb, 1);
69
70 if (err) {
71
72
73
74
75
76
77
78 igrab(inode);
79 reiserfs_warning(inode->i_sb, "clm-9001",
80 "pinning inode %lu because the "
81 "preallocation can't be freed",
82 inode->i_ino);
83 goto out;
84 }
85 }
86 reiserfs_update_inode_transaction(inode);
87
88#ifdef REISERFS_PREALLOCATE
89 reiserfs_discard_prealloc(&th, inode);
90#endif
91 err = journal_end(&th, inode->i_sb, 1);
92
93
94 if (!err)
95 err = jbegin_failure;
96
97 if (!err && atomic_read(&inode->i_count) <= 1 &&
98 (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
99 tail_has_to_be_packed(inode)) {
100
101
102
103
104 err = reiserfs_truncate_file(inode, 0);
105 }
106 out:
107 mutex_unlock(&(REISERFS_I(inode)->i_mmap));
108 mutex_unlock(&inode->i_mutex);
109 reiserfs_write_unlock(inode->i_sb);
110 return err;
111}
112
113static int reiserfs_file_mmap(struct file *file, struct vm_area_struct *vma)
114{
115 struct inode *inode;
116
117 inode = file->f_path.dentry->d_inode;
118 mutex_lock(&(REISERFS_I(inode)->i_mmap));
119 REISERFS_I(inode)->i_flags |= i_ever_mapped;
120 mutex_unlock(&(REISERFS_I(inode)->i_mmap));
121
122 return generic_file_mmap(file, vma);
123}
124
125static void reiserfs_vfs_truncate_file(struct inode *inode)
126{
127 reiserfs_truncate_file(inode, 1);
128}
129
130
131
132
133
134
135
136
137static int reiserfs_sync_file(struct file *filp,
138 struct dentry *dentry, int datasync)
139{
140 struct inode *inode = dentry->d_inode;
141 int err;
142 int barrier_done;
143
144 BUG_ON(!S_ISREG(inode->i_mode));
145 err = sync_mapping_buffers(inode->i_mapping);
146 reiserfs_write_lock(inode->i_sb);
147 barrier_done = reiserfs_commit_for_inode(inode);
148 reiserfs_write_unlock(inode->i_sb);
149 if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb))
150 blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
151 if (barrier_done < 0)
152 return barrier_done;
153 return (err < 0) ? -EIO : 0;
154}
155
156
157int reiserfs_commit_page(struct inode *inode, struct page *page,
158 unsigned from, unsigned to)
159{
160 unsigned block_start, block_end;
161 int partial = 0;
162 unsigned blocksize;
163 struct buffer_head *bh, *head;
164 unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
165 int new;
166 int logit = reiserfs_file_data_log(inode);
167 struct super_block *s = inode->i_sb;
168 int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
169 struct reiserfs_transaction_handle th;
170 int ret = 0;
171
172 th.t_trans_id = 0;
173 blocksize = 1 << inode->i_blkbits;
174
175 if (logit) {
176 reiserfs_write_lock(s);
177 ret = journal_begin(&th, s, bh_per_page + 1);
178 if (ret)
179 goto drop_write_lock;
180 reiserfs_update_inode_transaction(inode);
181 }
182 for (bh = head = page_buffers(page), block_start = 0;
183 bh != head || !block_start;
184 block_start = block_end, bh = bh->b_this_page) {
185
186 new = buffer_new(bh);
187 clear_buffer_new(bh);
188 block_end = block_start + blocksize;
189 if (block_end <= from || block_start >= to) {
190 if (!buffer_uptodate(bh))
191 partial = 1;
192 } else {
193 set_buffer_uptodate(bh);
194 if (logit) {
195 reiserfs_prepare_for_journal(s, bh, 1);
196 journal_mark_dirty(&th, s, bh);
197 } else if (!buffer_dirty(bh)) {
198 mark_buffer_dirty(bh);
199
200
201
202 if (reiserfs_data_ordered(inode->i_sb) &&
203 (new || page->index >= i_size_index)) {
204 reiserfs_add_ordered_list(inode, bh);
205 }
206 }
207 }
208 }
209 if (logit) {
210 ret = journal_end(&th, s, bh_per_page + 1);
211 drop_write_lock:
212 reiserfs_write_unlock(s);
213 }
214
215
216
217
218
219
220 if (!partial)
221 SetPageUptodate(page);
222 return ret;
223}
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251static ssize_t reiserfs_file_write(struct file *file,
252 const char __user * buf,
253
254 size_t count,
255 loff_t * ppos
256
257 )
258{
259 struct inode *inode = file->f_path.dentry->d_inode;
260
261
262 struct reiserfs_transaction_handle th;
263 th.t_trans_id = 0;
264
265
266
267
268
269
270
271
272 if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 &&
273 *ppos + count > MAX_NON_LFS) {
274 if (*ppos >= MAX_NON_LFS) {
275 return -EFBIG;
276 }
277 if (count > MAX_NON_LFS - (unsigned long)*ppos)
278 count = MAX_NON_LFS - (unsigned long)*ppos;
279 }
280
281 return do_sync_write(file, buf, count, ppos);
282}
283
284const struct file_operations reiserfs_file_operations = {
285 .read = do_sync_read,
286 .write = reiserfs_file_write,
287 .ioctl = reiserfs_ioctl,
288#ifdef CONFIG_COMPAT
289 .compat_ioctl = reiserfs_compat_ioctl,
290#endif
291 .mmap = reiserfs_file_mmap,
292 .open = generic_file_open,
293 .release = reiserfs_file_release,
294 .fsync = reiserfs_sync_file,
295 .aio_read = generic_file_aio_read,
296 .aio_write = generic_file_aio_write,
297 .splice_read = generic_file_splice_read,
298 .splice_write = generic_file_splice_write,
299 .llseek = generic_file_llseek,
300};
301
302const struct inode_operations reiserfs_file_inode_operations = {
303 .truncate = reiserfs_vfs_truncate_file,
304 .setattr = reiserfs_setattr,
305 .setxattr = reiserfs_setxattr,
306 .getxattr = reiserfs_getxattr,
307 .listxattr = reiserfs_listxattr,
308 .removexattr = reiserfs_removexattr,
309 .permission = reiserfs_permission,
310};
311