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