aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/file.c')
-rw-r--r--fs/reiserfs/file.c100
1 files changed, 54 insertions, 46 deletions
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index ed58d843d578..db9e80ba53a0 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -15,20 +15,20 @@
15#include <linux/quotaops.h> 15#include <linux/quotaops.h>
16 16
17/* 17/*
18** We pack the tails of files on file close, not at the time they are written. 18 * We pack the tails of files on file close, not at the time they are written.
19** This implies an unnecessary copy of the tail and an unnecessary indirect item 19 * This implies an unnecessary copy of the tail and an unnecessary indirect item
20** insertion/balancing, for files that are written in one write. 20 * insertion/balancing, for files that are written in one write.
21** It avoids unnecessary tail packings (balances) for files that are written in 21 * It avoids unnecessary tail packings (balances) for files that are written in
22** multiple writes and are small enough to have tails. 22 * multiple writes and are small enough to have tails.
23** 23 *
24** file_release is called by the VFS layer when the file is closed. If 24 * file_release is called by the VFS layer when the file is closed. If
25** this is the last open file descriptor, and the file 25 * this is the last open file descriptor, and the file
26** small enough to have a tail, and the tail is currently in an 26 * small enough to have a tail, and the tail is currently in an
27** unformatted node, the tail is converted back into a direct item. 27 * unformatted node, the tail is converted back into a direct item.
28** 28 *
29** We use reiserfs_truncate_file to pack the tail, since it already has 29 * We use reiserfs_truncate_file to pack the tail, since it already has
30** all the conditions coded. 30 * all the conditions coded.
31*/ 31 */
32static int reiserfs_file_release(struct inode *inode, struct file *filp) 32static int reiserfs_file_release(struct inode *inode, struct file *filp)
33{ 33{
34 34
@@ -41,10 +41,10 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
41 if (atomic_add_unless(&REISERFS_I(inode)->openers, -1, 1)) 41 if (atomic_add_unless(&REISERFS_I(inode)->openers, -1, 1))
42 return 0; 42 return 0;
43 43
44 mutex_lock(&(REISERFS_I(inode)->tailpack)); 44 mutex_lock(&REISERFS_I(inode)->tailpack);
45 45
46 if (!atomic_dec_and_test(&REISERFS_I(inode)->openers)) { 46 if (!atomic_dec_and_test(&REISERFS_I(inode)->openers)) {
47 mutex_unlock(&(REISERFS_I(inode)->tailpack)); 47 mutex_unlock(&REISERFS_I(inode)->tailpack);
48 return 0; 48 return 0;
49 } 49 }
50 50
@@ -52,31 +52,35 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
52 if ((!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) || 52 if ((!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
53 !tail_has_to_be_packed(inode)) && 53 !tail_has_to_be_packed(inode)) &&
54 REISERFS_I(inode)->i_prealloc_count <= 0) { 54 REISERFS_I(inode)->i_prealloc_count <= 0) {
55 mutex_unlock(&(REISERFS_I(inode)->tailpack)); 55 mutex_unlock(&REISERFS_I(inode)->tailpack);
56 return 0; 56 return 0;
57 } 57 }
58 58
59 reiserfs_write_lock(inode->i_sb); 59 reiserfs_write_lock(inode->i_sb);
60 /* freeing preallocation only involves relogging blocks that 60 /*
61 * freeing preallocation only involves relogging blocks that
61 * are already in the current transaction. preallocation gets 62 * are already in the current transaction. preallocation gets
62 * freed at the end of each transaction, so it is impossible for 63 * freed at the end of each transaction, so it is impossible for
63 * us to log any additional blocks (including quota blocks) 64 * us to log any additional blocks (including quota blocks)
64 */ 65 */
65 err = journal_begin(&th, inode->i_sb, 1); 66 err = journal_begin(&th, inode->i_sb, 1);
66 if (err) { 67 if (err) {
67 /* uh oh, we can't allow the inode to go away while there 68 /*
69 * uh oh, we can't allow the inode to go away while there
68 * is still preallocation blocks pending. Try to join the 70 * is still preallocation blocks pending. Try to join the
69 * aborted transaction 71 * aborted transaction
70 */ 72 */
71 jbegin_failure = err; 73 jbegin_failure = err;
72 err = journal_join_abort(&th, inode->i_sb, 1); 74 err = journal_join_abort(&th, inode->i_sb);
73 75
74 if (err) { 76 if (err) {
75 /* hmpf, our choices here aren't good. We can pin the inode 77 /*
76 * which will disallow unmount from every happening, we can 78 * hmpf, our choices here aren't good. We can pin
77 * do nothing, which will corrupt random memory on unmount, 79 * the inode which will disallow unmount from ever
78 * or we can forcibly remove the file from the preallocation 80 * happening, we can do nothing, which will corrupt
79 * list, which will leak blocks on disk. Lets pin the inode 81 * random memory on unmount, or we can forcibly
82 * remove the file from the preallocation list, which
83 * will leak blocks on disk. Lets pin the inode
80 * and let the admin know what is going on. 84 * and let the admin know what is going on.
81 */ 85 */
82 igrab(inode); 86 igrab(inode);
@@ -92,7 +96,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
92#ifdef REISERFS_PREALLOCATE 96#ifdef REISERFS_PREALLOCATE
93 reiserfs_discard_prealloc(&th, inode); 97 reiserfs_discard_prealloc(&th, inode);
94#endif 98#endif
95 err = journal_end(&th, inode->i_sb, 1); 99 err = journal_end(&th);
96 100
97 /* copy back the error code from journal_begin */ 101 /* copy back the error code from journal_begin */
98 if (!err) 102 if (!err)
@@ -102,35 +106,38 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
102 (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) && 106 (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
103 tail_has_to_be_packed(inode)) { 107 tail_has_to_be_packed(inode)) {
104 108
105 /* if regular file is released by last holder and it has been 109 /*
106 appended (we append by unformatted node only) or its direct 110 * if regular file is released by last holder and it has been
107 item(s) had to be converted, then it may have to be 111 * appended (we append by unformatted node only) or its direct
108 indirect2direct converted */ 112 * item(s) had to be converted, then it may have to be
113 * indirect2direct converted
114 */
109 err = reiserfs_truncate_file(inode, 0); 115 err = reiserfs_truncate_file(inode, 0);
110 } 116 }
111 out: 117out:
112 reiserfs_write_unlock(inode->i_sb); 118 reiserfs_write_unlock(inode->i_sb);
113 mutex_unlock(&(REISERFS_I(inode)->tailpack)); 119 mutex_unlock(&REISERFS_I(inode)->tailpack);
114 return err; 120 return err;
115} 121}
116 122
117static int reiserfs_file_open(struct inode *inode, struct file *file) 123static int reiserfs_file_open(struct inode *inode, struct file *file)
118{ 124{
119 int err = dquot_file_open(inode, file); 125 int err = dquot_file_open(inode, file);
126
127 /* somebody might be tailpacking on final close; wait for it */
120 if (!atomic_inc_not_zero(&REISERFS_I(inode)->openers)) { 128 if (!atomic_inc_not_zero(&REISERFS_I(inode)->openers)) {
121 /* somebody might be tailpacking on final close; wait for it */ 129 mutex_lock(&REISERFS_I(inode)->tailpack);
122 mutex_lock(&(REISERFS_I(inode)->tailpack));
123 atomic_inc(&REISERFS_I(inode)->openers); 130 atomic_inc(&REISERFS_I(inode)->openers);
124 mutex_unlock(&(REISERFS_I(inode)->tailpack)); 131 mutex_unlock(&REISERFS_I(inode)->tailpack);
125 } 132 }
126 return err; 133 return err;
127} 134}
128 135
129void reiserfs_vfs_truncate_file(struct inode *inode) 136void reiserfs_vfs_truncate_file(struct inode *inode)
130{ 137{
131 mutex_lock(&(REISERFS_I(inode)->tailpack)); 138 mutex_lock(&REISERFS_I(inode)->tailpack);
132 reiserfs_truncate_file(inode, 1); 139 reiserfs_truncate_file(inode, 1);
133 mutex_unlock(&(REISERFS_I(inode)->tailpack)); 140 mutex_unlock(&REISERFS_I(inode)->tailpack);
134} 141}
135 142
136/* Sync a reiserfs file. */ 143/* Sync a reiserfs file. */
@@ -205,10 +212,11 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
205 set_buffer_uptodate(bh); 212 set_buffer_uptodate(bh);
206 if (logit) { 213 if (logit) {
207 reiserfs_prepare_for_journal(s, bh, 1); 214 reiserfs_prepare_for_journal(s, bh, 1);
208 journal_mark_dirty(&th, s, bh); 215 journal_mark_dirty(&th, bh);
209 } else if (!buffer_dirty(bh)) { 216 } else if (!buffer_dirty(bh)) {
210 mark_buffer_dirty(bh); 217 mark_buffer_dirty(bh);
211 /* do data=ordered on any page past the end 218 /*
219 * do data=ordered on any page past the end
212 * of file and any buffer marked BH_New. 220 * of file and any buffer marked BH_New.
213 */ 221 */
214 if (reiserfs_data_ordered(inode->i_sb) && 222 if (reiserfs_data_ordered(inode->i_sb) &&
@@ -219,8 +227,8 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
219 } 227 }
220 } 228 }
221 if (logit) { 229 if (logit) {
222 ret = journal_end(&th, s, bh_per_page + 1); 230 ret = journal_end(&th);
223 drop_write_lock: 231drop_write_lock:
224 reiserfs_write_unlock(s); 232 reiserfs_write_unlock(s);
225 } 233 }
226 /* 234 /*
@@ -235,8 +243,8 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
235} 243}
236 244
237const struct file_operations reiserfs_file_operations = { 245const struct file_operations reiserfs_file_operations = {
238 .read = do_sync_read, 246 .read = new_sync_read,
239 .write = do_sync_write, 247 .write = new_sync_write,
240 .unlocked_ioctl = reiserfs_ioctl, 248 .unlocked_ioctl = reiserfs_ioctl,
241#ifdef CONFIG_COMPAT 249#ifdef CONFIG_COMPAT
242 .compat_ioctl = reiserfs_compat_ioctl, 250 .compat_ioctl = reiserfs_compat_ioctl,
@@ -245,10 +253,10 @@ const struct file_operations reiserfs_file_operations = {
245 .open = reiserfs_file_open, 253 .open = reiserfs_file_open,
246 .release = reiserfs_file_release, 254 .release = reiserfs_file_release,
247 .fsync = reiserfs_sync_file, 255 .fsync = reiserfs_sync_file,
248 .aio_read = generic_file_aio_read, 256 .read_iter = generic_file_read_iter,
249 .aio_write = generic_file_aio_write, 257 .write_iter = generic_file_write_iter,
250 .splice_read = generic_file_splice_read, 258 .splice_read = generic_file_splice_read,
251 .splice_write = generic_file_splice_write, 259 .splice_write = iter_file_splice_write,
252 .llseek = generic_file_llseek, 260 .llseek = generic_file_llseek,
253}; 261};
254 262