This source file includes following definitions.
- ext2_file_write
- ext2_release_file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <asm/segment.h>
19 #include <asm/system.h>
20
21 #include <linux/errno.h>
22 #include <linux/fs.h>
23 #include <linux/ext2_fs.h>
24 #include <linux/fcntl.h>
25 #include <linux/sched.h>
26 #include <linux/stat.h>
27 #include <linux/locks.h>
28 #include <linux/mm.h>
29 #include <linux/pagemap.h>
30
31 #define NBUF 32
32
33 #define MIN(a,b) (((a)<(b))?(a):(b))
34 #define MAX(a,b) (((a)>(b))?(a):(b))
35
36 #include <linux/fs.h>
37 #include <linux/ext2_fs.h>
38
39 static int ext2_file_write (struct inode *, struct file *, const char *, int);
40 static void ext2_release_file (struct inode *, struct file *);
41
42
43
44
45
46 static struct file_operations ext2_file_operations = {
47 NULL,
48 generic_file_read,
49 ext2_file_write,
50 NULL,
51 NULL,
52 ext2_ioctl,
53 generic_mmap,
54 NULL,
55 ext2_release_file,
56 ext2_sync_file,
57 NULL,
58 NULL,
59 NULL
60 };
61
62 struct inode_operations ext2_file_inode_operations = {
63 &ext2_file_operations,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 NULL,
70 NULL,
71 NULL,
72 NULL,
73 NULL,
74 NULL,
75 generic_readpage,
76 NULL,
77 ext2_bmap,
78 ext2_truncate,
79 ext2_permission,
80 NULL
81 };
82
83 static int ext2_file_write (struct inode * inode, struct file * filp,
84 const char * buf, int count)
85 {
86 const loff_t two_gb = 2147483647;
87 loff_t pos;
88 off_t pos2;
89 long block;
90 int offset;
91 int written, c;
92 struct buffer_head * bh, *bufferlist[NBUF];
93 struct super_block * sb;
94 int err;
95 int i,buffercount,write_error;
96
97 write_error = buffercount = 0;
98 if (!inode) {
99 printk("ext2_file_write: inode = NULL\n");
100 return -EINVAL;
101 }
102 sb = inode->i_sb;
103 if (sb->s_flags & MS_RDONLY)
104
105
106
107 return -ENOSPC;
108
109 if (!S_ISREG(inode->i_mode)) {
110 ext2_warning (sb, "ext2_file_write", "mode = %07o",
111 inode->i_mode);
112 return -EINVAL;
113 }
114 if (filp->f_flags & O_APPEND)
115 pos = inode->i_size;
116 else
117 pos = filp->f_pos;
118 pos2 = (off_t) pos;
119
120
121
122
123
124
125 if (filp->f_flags & O_SYNC)
126 inode->u.ext2_i.i_osync++;
127 block = pos2 >> EXT2_BLOCK_SIZE_BITS(sb);
128 offset = pos2 & (sb->s_blocksize - 1);
129 c = sb->s_blocksize - offset;
130 written = 0;
131 while (count > 0) {
132 if (pos > two_gb) {
133 if (!written)
134 written = -EFBIG;
135 break;
136 }
137 bh = ext2_getblk (inode, block, 1, &err);
138 if (!bh) {
139 if (!written)
140 written = err;
141 break;
142 }
143 count -= c;
144 if (count < 0)
145 c += count;
146 if (c != sb->s_blocksize && !buffer_uptodate(bh)) {
147 ll_rw_block (READ, 1, &bh);
148 wait_on_buffer (bh);
149 if (!buffer_uptodate(bh)) {
150 brelse (bh);
151 if (!written)
152 written = -EIO;
153 break;
154 }
155 }
156 memcpy_fromfs (bh->b_data + offset, buf, c);
157 update_vm_cache(inode, pos, bh->b_data + offset, c);
158 pos2 += c;
159 pos += c;
160 written += c;
161 buf += c;
162 mark_buffer_uptodate(bh, 1);
163 mark_buffer_dirty(bh, 0);
164 if (filp->f_flags & O_SYNC)
165 bufferlist[buffercount++] = bh;
166 else
167 brelse(bh);
168 if (buffercount == NBUF){
169 ll_rw_block(WRITE, buffercount, bufferlist);
170 for(i=0; i<buffercount; i++){
171 wait_on_buffer(bufferlist[i]);
172 if (!buffer_uptodate(bufferlist[i]))
173 write_error=1;
174 brelse(bufferlist[i]);
175 }
176 buffercount=0;
177 }
178 if(write_error)
179 break;
180 block++;
181 offset = 0;
182 c = sb->s_blocksize;
183 }
184 if ( buffercount ){
185 ll_rw_block(WRITE, buffercount, bufferlist);
186 for(i=0; i<buffercount; i++){
187 wait_on_buffer(bufferlist[i]);
188 if (!buffer_uptodate(bufferlist[i]))
189 write_error=1;
190 brelse(bufferlist[i]);
191 }
192 }
193 if (pos > inode->i_size)
194 inode->i_size = pos;
195 if (filp->f_flags & O_SYNC)
196 inode->u.ext2_i.i_osync--;
197 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
198 filp->f_pos = pos;
199 inode->i_dirt = 1;
200 return written;
201 }
202
203
204
205
206
207
208 static void ext2_release_file (struct inode * inode, struct file * filp)
209 {
210 if (filp->f_mode & 2)
211 ext2_discard_prealloc (inode);
212 }