Linux-2.3.3 and a short hiatus..
[davej-history.git] / fs / ext2 / file.c
blob2e4d2812cf0458957aaa1ea3d2218e1b5c85caf7
1 /*
2 * linux/fs/ext2/file.c
4 * Copyright (C) 1992, 1993, 1994, 1995
5 * Remy Card (card@masi.ibp.fr)
6 * Laboratoire MASI - Institut Blaise Pascal
7 * Universite Pierre et Marie Curie (Paris VI)
9 * from
11 * linux/fs/minix/file.c
13 * Copyright (C) 1991, 1992 Linus Torvalds
15 * ext2 fs regular file handling primitives
17 * 64-bit file support on 64-bit platforms by Jakub Jelinek
18 * (jj@sunsite.ms.mff.cuni.cz)
21 #include <asm/uaccess.h>
22 #include <asm/system.h>
24 #include <linux/errno.h>
25 #include <linux/fs.h>
26 #include <linux/ext2_fs.h>
27 #include <linux/fcntl.h>
28 #include <linux/sched.h>
29 #include <linux/stat.h>
30 #include <linux/locks.h>
31 #include <linux/mm.h>
32 #include <linux/pagemap.h>
34 #define NBUF 32
36 #define MIN(a,b) (((a)<(b))?(a):(b))
37 #define MAX(a,b) (((a)>(b))?(a):(b))
39 static long long ext2_file_lseek(struct file *, long long, int);
40 static ssize_t ext2_file_write (struct file *, const char *, size_t, loff_t *);
41 static int ext2_release_file (struct inode *, struct file *);
42 #if BITS_PER_LONG < 64
43 static int ext2_open_file (struct inode *, struct file *);
45 #else
47 #define EXT2_MAX_SIZE(bits) \
48 (((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + \
49 (1LL << (bits - 2)) * (1LL << (bits - 2)) + \
50 (1LL << (bits - 2)) * (1LL << (bits - 2)) * (1LL << (bits - 2))) * \
51 (1LL << bits)) - 1)
53 static long long ext2_max_sizes[] = {
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
58 #endif
61 * We have mostly NULL's here: the current defaults are ok for
62 * the ext2 filesystem.
64 static struct file_operations ext2_file_operations = {
65 ext2_file_lseek, /* lseek */
66 generic_file_read, /* read */
67 ext2_file_write, /* write */
68 NULL, /* readdir - bad */
69 NULL, /* poll - default */
70 ext2_ioctl, /* ioctl */
71 generic_file_mmap, /* mmap */
72 #if BITS_PER_LONG == 64
73 NULL, /* no special open is needed */
74 #else
75 ext2_open_file,
76 #endif
77 NULL, /* flush */
78 ext2_release_file, /* release */
79 ext2_sync_file, /* fsync */
80 NULL, /* fasync */
81 NULL, /* check_media_change */
82 NULL /* revalidate */
85 struct inode_operations ext2_file_inode_operations = {
86 &ext2_file_operations,/* default file operations */
87 NULL, /* create */
88 NULL, /* lookup */
89 NULL, /* link */
90 NULL, /* unlink */
91 NULL, /* symlink */
92 NULL, /* mkdir */
93 NULL, /* rmdir */
94 NULL, /* mknod */
95 NULL, /* rename */
96 NULL, /* readlink */
97 NULL, /* follow_link */
98 generic_readpage, /* readpage */
99 NULL, /* writepage */
100 ext2_bmap, /* bmap */
101 ext2_truncate, /* truncate */
102 ext2_permission, /* permission */
103 NULL /* smap */
107 * Make sure the offset never goes beyond the 32-bit mark..
109 static long long ext2_file_lseek(
110 struct file *file,
111 long long offset,
112 int origin)
114 struct inode *inode = file->f_dentry->d_inode;
116 switch (origin) {
117 case 2:
118 offset += inode->i_size;
119 break;
120 case 1:
121 offset += file->f_pos;
123 if (((unsigned long long) offset >> 32) != 0) {
124 #if BITS_PER_LONG < 64
125 return -EINVAL;
126 #else
127 if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
128 return -EINVAL;
129 #endif
131 if (offset != file->f_pos) {
132 file->f_pos = offset;
133 file->f_reada = 0;
134 file->f_version = ++event;
136 return offset;
139 static inline void remove_suid(struct inode *inode)
141 unsigned int mode;
143 /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
144 mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
146 /* was any of the uid bits set? */
147 mode &= inode->i_mode;
148 if (mode && !capable(CAP_FSETID)) {
149 inode->i_mode &= ~mode;
150 mark_inode_dirty(inode);
154 static ssize_t ext2_file_write (struct file * filp, const char * buf,
155 size_t count, loff_t *ppos)
157 struct inode * inode = filp->f_dentry->d_inode;
158 off_t pos;
159 long block;
160 int offset;
161 int written, c;
162 struct buffer_head * bh, *bufferlist[NBUF];
163 struct super_block * sb;
164 int err;
165 int i,buffercount,write_error;
167 /* POSIX: mtime/ctime may not change for 0 count */
168 if (!count)
169 return 0;
170 write_error = buffercount = 0;
171 if (!inode) {
172 printk("ext2_file_write: inode = NULL\n");
173 return -EINVAL;
175 sb = inode->i_sb;
176 if (sb->s_flags & MS_RDONLY)
178 * This fs has been automatically remounted ro because of errors
180 return -ENOSPC;
182 if (!S_ISREG(inode->i_mode)) {
183 ext2_warning (sb, "ext2_file_write", "mode = %07o",
184 inode->i_mode);
185 return -EINVAL;
187 remove_suid(inode);
189 if (filp->f_flags & O_APPEND)
190 pos = inode->i_size;
191 else {
192 pos = *ppos;
193 if (pos != *ppos)
194 return -EINVAL;
195 #if BITS_PER_LONG >= 64
196 if (pos > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(sb)])
197 return -EINVAL;
198 #endif
201 /* Check for overflow.. */
202 #if BITS_PER_LONG < 64
203 if (pos > (__u32) (pos + count)) {
204 count = ~pos; /* == 0xFFFFFFFF - pos */
205 if (!count)
206 return -EFBIG;
208 #else
210 off_t max = ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(sb)];
212 if (pos + count > max) {
213 count = max - pos;
214 if (!count)
215 return -EFBIG;
217 if (((pos + count) >> 32) &&
218 !(sb->u.ext2_sb.s_es->s_feature_ro_compat &
219 cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE))) {
220 /* If this is the first large file created, add a flag
221 to the superblock */
222 sb->u.ext2_sb.s_es->s_feature_ro_compat |=
223 cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
224 mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
227 #endif
230 * If a file has been opened in synchronous mode, we have to ensure
231 * that meta-data will also be written synchronously. Thus, we
232 * set the i_osync field. This field is tested by the allocation
233 * routines.
235 if (filp->f_flags & O_SYNC)
236 inode->u.ext2_i.i_osync++;
237 block = pos >> EXT2_BLOCK_SIZE_BITS(sb);
238 offset = pos & (sb->s_blocksize - 1);
239 c = sb->s_blocksize - offset;
240 written = 0;
241 do {
242 bh = ext2_getblk (inode, block, 1, &err);
243 if (!bh) {
244 if (!written)
245 written = err;
246 break;
248 if (c > count)
249 c = count;
250 if (c != sb->s_blocksize && !buffer_uptodate(bh)) {
251 ll_rw_block (READ, 1, &bh);
252 wait_on_buffer (bh);
253 if (!buffer_uptodate(bh)) {
254 brelse (bh);
255 if (!written)
256 written = -EIO;
257 break;
260 c -= copy_from_user (bh->b_data + offset, buf, c);
261 if (!c) {
262 brelse(bh);
263 if (!written)
264 written = -EFAULT;
265 break;
267 update_vm_cache(inode, pos, bh->b_data + offset, c);
268 pos += c;
269 written += c;
270 buf += c;
271 count -= c;
272 mark_buffer_uptodate(bh, 1);
273 mark_buffer_dirty(bh, 0);
275 if (filp->f_flags & O_SYNC)
276 bufferlist[buffercount++] = bh;
277 else
278 brelse(bh);
279 if (buffercount == NBUF){
280 ll_rw_block(WRITE, buffercount, bufferlist);
281 for(i=0; i<buffercount; i++){
282 wait_on_buffer(bufferlist[i]);
283 if (!buffer_uptodate(bufferlist[i]))
284 write_error=1;
285 brelse(bufferlist[i]);
287 buffercount=0;
289 if(write_error)
290 break;
291 block++;
292 offset = 0;
293 c = sb->s_blocksize;
294 } while (count);
295 if ( buffercount ){
296 ll_rw_block(WRITE, buffercount, bufferlist);
297 for(i=0; i<buffercount; i++){
298 wait_on_buffer(bufferlist[i]);
299 if (!buffer_uptodate(bufferlist[i]))
300 write_error=1;
301 brelse(bufferlist[i]);
304 if (pos > inode->i_size)
305 inode->i_size = pos;
306 if (filp->f_flags & O_SYNC)
307 inode->u.ext2_i.i_osync--;
308 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
309 *ppos = pos;
310 mark_inode_dirty(inode);
311 return written;
315 * Called when an inode is released. Note that this is different
316 * from ext2_file_open: open gets called at every open, but release
317 * gets called only when /all/ the files are closed.
319 static int ext2_release_file (struct inode * inode, struct file * filp)
321 if (filp->f_mode & FMODE_WRITE)
322 ext2_discard_prealloc (inode);
323 return 0;
326 #if BITS_PER_LONG < 64
328 * Called when an inode is about to be open.
329 * We use this to disallow opening RW large files on 32bit systems.
331 static int ext2_open_file (struct inode * inode, struct file * filp)
333 if (inode->u.ext2_i.i_high_size && (filp->f_mode & FMODE_WRITE))
334 return -EFBIG;
335 return 0;
337 #endif