Import 2.3.7pre3
[davej-history.git] / fs / ext2 / file.c
blob806859ba0be272643319a41837a39acbd02570d4
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>
33 #include <linux/smp_lock.h>
35 #define NBUF 32
37 #define MIN(a,b) (((a)<(b))?(a):(b))
38 #define MAX(a,b) (((a)>(b))?(a):(b))
40 static int ext2_writepage (struct file * file, struct page * page);
41 static long long ext2_file_lseek(struct file *, long long, int);
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
62 * Make sure the offset never goes beyond the 32-bit mark..
64 static long long ext2_file_lseek(
65 struct file *file,
66 long long offset,
67 int origin)
69 struct inode *inode = file->f_dentry->d_inode;
71 switch (origin) {
72 case 2:
73 offset += inode->i_size;
74 break;
75 case 1:
76 offset += file->f_pos;
78 if (((unsigned long long) offset >> 32) != 0) {
79 #if BITS_PER_LONG < 64
80 return -EINVAL;
81 #else
82 if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
83 return -EINVAL;
84 #endif
86 if (offset != file->f_pos) {
87 file->f_pos = offset;
88 file->f_reada = 0;
89 file->f_version = ++event;
91 return offset;
94 static inline void remove_suid(struct inode *inode)
96 unsigned int mode;
98 /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
99 mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
101 /* was any of the uid bits set? */
102 mode &= inode->i_mode;
103 if (mode && !capable(CAP_FSETID)) {
104 inode->i_mode &= ~mode;
105 mark_inode_dirty(inode);
109 static int ext2_writepage (struct file * file, struct page * page)
111 return block_write_full_page(file, page, ext2_getblk_block);
114 static long ext2_write_one_page (struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
116 return block_write_one_page(file, page, offset, bytes, buf, ext2_getblk_block);
120 * Write to a file (through the page cache).
122 static ssize_t
123 ext2_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
125 return generic_file_write(file, buf, count, ppos, ext2_write_one_page);
129 * Called when an inode is released. Note that this is different
130 * from ext2_file_open: open gets called at every open, but release
131 * gets called only when /all/ the files are closed.
133 static int ext2_release_file (struct inode * inode, struct file * filp)
135 if (filp->f_mode & FMODE_WRITE)
136 ext2_discard_prealloc (inode);
137 return 0;
140 #if BITS_PER_LONG < 64
142 * Called when an inode is about to be open.
143 * We use this to disallow opening RW large files on 32bit systems.
145 static int ext2_open_file (struct inode * inode, struct file * filp)
147 if (inode->u.ext2_i.i_high_size && (filp->f_mode & FMODE_WRITE))
148 return -EFBIG;
149 return 0;
151 #endif
154 * We have mostly NULL's here: the current defaults are ok for
155 * the ext2 filesystem.
157 static struct file_operations ext2_file_operations = {
158 ext2_file_lseek, /* lseek */
159 generic_file_read, /* read */
160 ext2_file_write, /* write */
161 NULL, /* readdir - bad */
162 NULL, /* poll - default */
163 ext2_ioctl, /* ioctl */
164 generic_file_mmap, /* mmap */
165 #if BITS_PER_LONG == 64
166 NULL, /* no special open is needed */
167 #else
168 ext2_open_file,
169 #endif
170 NULL, /* flush */
171 ext2_release_file, /* release */
172 ext2_sync_file, /* fsync */
173 NULL, /* fasync */
174 NULL, /* check_media_change */
175 NULL /* revalidate */
178 struct inode_operations ext2_file_inode_operations = {
179 &ext2_file_operations,/* default file operations */
180 NULL, /* create */
181 NULL, /* lookup */
182 NULL, /* link */
183 NULL, /* unlink */
184 NULL, /* symlink */
185 NULL, /* mkdir */
186 NULL, /* rmdir */
187 NULL, /* mknod */
188 NULL, /* rename */
189 NULL, /* readlink */
190 NULL, /* follow_link */
191 generic_readpage, /* readpage */
192 ext2_writepage, /* writepage */
193 ext2_bmap, /* bmap */
194 ext2_truncate, /* truncate */
195 ext2_permission, /* permission */
196 NULL, /* smap */
197 NULL, /* updatepage */
198 NULL, /* revalidate */
199 generic_block_flushpage,/* flushpage */