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) 11 * linux/fs/minix/file.c 13 * Copyright (C) 1991, 1992 Linus Torvalds 15 * ext2 fs regular file handling primitives 18 #include <asm/uaccess.h> 19 #include <asm/system.h> 21 #include <linux/errno.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> 29 #include <linux/pagemap.h> 33 #define MIN(a,b) (((a)<(b))?(a):(b)) 34 #define MAX(a,b) (((a)>(b))?(a):(b)) 37 #include <linux/ext2_fs.h> 39 static long longext2_file_lseek(struct inode
*,struct file
*,long long,int); 40 static longext2_file_write(struct inode
*,struct file
*,const char*,unsigned long); 41 static voidext2_release_file(struct inode
*,struct file
*); 44 * We have mostly NULL's here: the current defaults are ok for 45 * the ext2 filesystem. 47 static struct file_operations ext2_file_operations
= { 48 ext2_file_lseek
,/* lseek */ 49 generic_file_read
,/* read */ 50 ext2_file_write
,/* write */ 51 NULL
,/* readdir - bad */ 52 NULL
,/* select - default */ 53 ext2_ioctl
,/* ioctl */ 54 generic_file_mmap
,/* mmap */ 55 NULL
,/* no special open is needed */ 56 ext2_release_file
,/* release */ 57 ext2_sync_file
,/* fsync */ 59 NULL
,/* check_media_change */ 63 struct inode_operations ext2_file_inode_operations
= { 64 &ext2_file_operations
,/* default file operations */ 75 NULL
,/* follow_link */ 76 generic_readpage
,/* readpage */ 79 ext2_truncate
,/* truncate */ 80 ext2_permission
,/* permission */ 85 * Make sure the offset never goes beyond the 32-bit mark.. 87 static long longext2_file_lseek(struct inode
*inode
, 96 offset
+= inode
->i_size
; 99 offset
+= file
->f_pos
; 102 /* make sure the offset fits in 32 bits */ 103 if(((unsigned long long) offset
>>32) ==0) { 104 if(offset
!= file
->f_pos
) { 105 file
->f_pos
= offset
; 107 file
->f_version
= ++event
; 114 staticinlinevoidremove_suid(struct inode
*inode
) 118 /* set S_IGID if S_IXGRP is set, and always set S_ISUID */ 119 mode
= (inode
->i_mode
& S_IXGRP
)*(S_ISGID
/S_IXGRP
) | S_ISUID
; 121 /* was any of the uid bits set? */ 122 mode
&= inode
->i_mode
; 123 if(mode
&& !suser()) { 124 inode
->i_mode
&= ~mode
; 129 static longext2_file_write(struct inode
* inode
,struct file
* filp
, 130 const char* buf
,unsigned long count
) 136 struct buffer_head
* bh
, *bufferlist
[NBUF
]; 137 struct super_block
* sb
; 139 int i
,buffercount
,write_error
; 141 /* POSIX: mtime/ctime may not change for 0 count */ 144 write_error
= buffercount
=0; 146 printk("ext2_file_write: inode = NULL\n"); 150 if(sb
->s_flags
& MS_RDONLY
) 152 * This fs has been automatically remounted ro because of errors 156 if(!S_ISREG(inode
->i_mode
)) { 157 ext2_warning(sb
,"ext2_file_write","mode = %07o", 163 if(filp
->f_flags
& O_APPEND
) 167 /* Check for overflow.. */ 168 if(pos
> (__u32
) (pos
+ count
)) { 169 count
= ~pos
;/* == 0xFFFFFFFF - pos */ 175 * If a file has been opened in synchronous mode, we have to ensure 176 * that meta-data will also be written synchronously. Thus, we 177 * set the i_osync field. This field is tested by the allocation 180 if(filp
->f_flags
& O_SYNC
) 181 inode
->u
.ext2_i
.i_osync
++; 182 block
= pos
>>EXT2_BLOCK_SIZE_BITS(sb
); 183 offset
= pos
& (sb
->s_blocksize
-1); 184 c
= sb
->s_blocksize
- offset
; 187 bh
=ext2_getblk(inode
, block
,1, &err
); 195 if(c
!= sb
->s_blocksize
&& !buffer_uptodate(bh
)) { 196 ll_rw_block(READ
,1, &bh
); 198 if(!buffer_uptodate(bh
)) { 205 c
-=copy_from_user(bh
->b_data
+ offset
, buf
, c
); 212 update_vm_cache(inode
, pos
, bh
->b_data
+ offset
, c
); 217 mark_buffer_uptodate(bh
,1); 218 mark_buffer_dirty(bh
,0); 219 if(filp
->f_flags
& O_SYNC
) 220 bufferlist
[buffercount
++] = bh
; 223 if(buffercount
== NBUF
){ 224 ll_rw_block(WRITE
, buffercount
, bufferlist
); 225 for(i
=0; i
<buffercount
; i
++){ 226 wait_on_buffer(bufferlist
[i
]); 227 if(!buffer_uptodate(bufferlist
[i
])) 229 brelse(bufferlist
[i
]); 240 ll_rw_block(WRITE
, buffercount
, bufferlist
); 241 for(i
=0; i
<buffercount
; i
++){ 242 wait_on_buffer(bufferlist
[i
]); 243 if(!buffer_uptodate(bufferlist
[i
])) 245 brelse(bufferlist
[i
]); 248 if(pos
> inode
->i_size
) 250 if(filp
->f_flags
& O_SYNC
) 251 inode
->u
.ext2_i
.i_osync
--; 252 inode
->i_ctime
= inode
->i_mtime
= CURRENT_TIME
; 259 * Called when an inode is released. Note that this is different 260 * from ext2_open: open gets called at every open, but release 261 * gets called only when /all/ the files are closed. 263 static voidext2_release_file(struct inode
* inode
,struct file
* filp
) 266 ext2_discard_prealloc(inode
);