1/* 2 * file.c 3 * 4 * PURPOSE 5 * File handling routines for the OSTA-UDF(tm) filesystem. 6 * 7 * CONTACTS 8 * E-mail regarding any portion of the Linux UDF file system should be 9 * directed to the development team mailing list (run by majordomo): 10 * linux_udf@hpesjro.fc.hp.com 11 * 12 * COPYRIGHT 13 * This file is distributed under the terms of the GNU General Public 14 * License (GPL). Copies of the GPL can be obtained from: 15 * ftp://prep.ai.mit.edu/pub/gnu/GPL 16 * Each contributing author retains all rights to their own work. 17 * 18 * (C) 1998-1999 Dave Boynton 19 * (C) 1998-2001 Ben Fennema 20 * (C) 1999-2000 Stelias Computing Inc 21 * 22 * HISTORY 23 * 24 * 10/02/98 dgb Attempt to integrate into udf.o 25 * 10/07/98 Switched to using generic_readpage, etc., like isofs 26 * And it works! 27 * 12/06/98 blf Added udf_file_read. uses generic_file_read for all cases but 28 * ICBTAG_FLAG_AD_IN_ICB. 29 * 04/06/99 64 bit file handling on 32 bit systems taken from ext2 file.c 30 * 05/12/99 Preliminary file write support 31 */ 32 33#include "udfdecl.h" 34#include <linux/fs.h> 35#include <linux/udf_fs.h> 36#include <asm/uaccess.h> 37#include <linux/kernel.h> 38#include <linux/string.h> /* memset */ 39#include <linux/errno.h> 40#include <linux/locks.h> 41#include <linux/smp_lock.h> 42 43#include "udf_i.h" 44#include "udf_sb.h" 45 46static int udf_adinicb_readpage(struct file *file, struct page * page) 47{ 48 struct inode *inode = page->mapping->host; 49 50 struct buffer_head *bh; 51 int block; 52 char *kaddr; 53 int err = 0; 54 55 if (!PageLocked(page)) 56 PAGE_BUG(page); 57 58 kaddr = kmap(page); 59 memset(kaddr, 0, PAGE_CACHE_SIZE); 60 block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); 61 bh = sb_bread(inode->i_sb, block); 62 if (!bh) 63 { 64 SetPageError(page); 65 err = -EIO; 66 goto out; 67 } 68 memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size); 69 brelse(bh); 70 flush_dcache_page(page); 71 SetPageUptodate(page); 72out: 73 kunmap(page); 74 UnlockPage(page); 75 return err; 76} 77 78static int udf_adinicb_writepage(struct page *page) 79{ 80 struct inode *inode = page->mapping->host; 81 82 struct buffer_head *bh; 83 int block; 84 char *kaddr; 85 int err = 0; 86 87 if (!PageLocked(page)) 88 PAGE_BUG(page); 89 90 kaddr = kmap(page); 91 block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); 92 bh = sb_bread(inode->i_sb, block); 93 if (!bh) 94 { 95 SetPageError(page); 96 err = -EIO; 97 goto out; 98 } 99 memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size); 100 mark_buffer_dirty(bh); 101 brelse(bh); 102 SetPageUptodate(page); 103out: 104 kunmap(page); 105 UnlockPage(page); 106 return err; 107} 108 109static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 110{ 111 kmap(page); 112 return 0; 113} 114 115static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) 116{ 117 struct inode *inode = page->mapping->host; 118 119 struct buffer_head *bh; 120 int block; 121 char *kaddr = page_address(page); 122 int err = 0; 123 124 block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); 125 bh = sb_bread(inode->i_sb, block); 126 if (!bh) 127 { 128 SetPageError(page); 129 err = -EIO; 130 goto out; 131 } 132 memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset, 133 kaddr + offset, to - offset); 134 mark_buffer_dirty(bh); 135 brelse(bh); 136 SetPageUptodate(page); 137out: 138 kunmap(page); 139 /* only one page here */ 140 if (to > inode->i_size) 141 inode->i_size = to; 142 return err; 143} 144 145struct address_space_operations udf_adinicb_aops = { 146 readpage: udf_adinicb_readpage, 147 writepage: udf_adinicb_writepage, 148 sync_page: block_sync_page, 149 prepare_write: udf_adinicb_prepare_write, 150 commit_write: udf_adinicb_commit_write, 151}; 152 153static ssize_t udf_file_write(struct file * file, const char * buf, 154 size_t count, loff_t *ppos) 155{ 156 ssize_t retval; 157 struct inode *inode = file->f_dentry->d_inode; 158 int err, pos; 159 160 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 161 { 162 if (file->f_flags & O_APPEND) 163 pos = inode->i_size; 164 else 165 pos = *ppos; 166 167 if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + 168 pos + count)) 169 { 170 udf_expand_file_adinicb(inode, pos + count, &err); 171 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 172 { 173 udf_debug("udf_expand_adinicb: err=%d\n", err); 174 return err; 175 } 176 } 177 else 178 { 179 if (pos + count > inode->i_size) 180 UDF_I_LENALLOC(inode) = pos + count; 181 else 182 UDF_I_LENALLOC(inode) = inode->i_size; 183 } 184 } 185 186 retval = generic_file_write(file, buf, count, ppos); 187 188 if (retval > 0) 189 { 190 UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME; 191 mark_inode_dirty(inode); 192 } 193 return retval; 194} 195 196/* 197 * udf_ioctl 198 * 199 * PURPOSE 200 * Issue an ioctl. 201 * 202 * DESCRIPTION 203 * Optional - sys_ioctl() will return -ENOTTY if this routine is not 204 * available, and the ioctl cannot be handled without filesystem help. 205 * 206 * sys_ioctl() handles these ioctls that apply only to regular files: 207 * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD 208 * These ioctls are also handled by sys_ioctl(): 209 * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC 210 * All other ioctls are passed to the filesystem. 211 * 212 * Refer to sys_ioctl() in fs/ioctl.c 213 * sys_ioctl() -> . 214 * 215 * PRE-CONDITIONS 216 * inode Pointer to inode that ioctl was issued on. 217 * filp Pointer to file that ioctl was issued on. 218 * cmd The ioctl command. 219 * arg The ioctl argument [can be interpreted as a 220 * user-space pointer if desired]. 221 * 222 * POST-CONDITIONS 223 * <return> Success (>=0) or an error code (<=0) that 224 * sys_ioctl() will return. 225 * 226 * HISTORY 227 * July 1, 1997 - Andrew E. Mileski 228 * Written, tested, and released. 229 */ 230int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 231 unsigned long arg) 232{ 233 int result = -EINVAL; 234 struct buffer_head *bh = NULL; 235 long_ad eaicb; 236 uint8_t *ea = NULL; 237 238 if ( permission(inode, MAY_READ) != 0 ) 239 { 240 udf_debug("no permission to access inode %lu\n", 241 inode->i_ino); 242 return -EPERM; 243 } 244 245 if ( !arg ) 246 { 247 udf_debug("invalid argument to udf_ioctl\n"); 248 return -EINVAL; 249 } 250 251 /* first, do ioctls that don't need to udf_read */ 252 switch (cmd) 253 { 254 case UDF_GETVOLIDENT: 255 return copy_to_user((char *)arg, 256 UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0; 257 case UDF_RELOCATE_BLOCKS: 258 { 259 long old, new; 260 261 if (!capable(CAP_SYS_ADMIN)) return -EACCES; 262 if (get_user(old, (long *)arg)) return -EFAULT; 263 if ((result = udf_relocate_blocks(inode->i_sb, 264 old, &new)) == 0) 265 result = put_user(new, (long *)arg); 266 267 return result; 268 } 269 } 270 271 /* ok, we need to read the inode */ 272 bh = udf_tread(inode->i_sb, 273 udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); 274 275 if (!bh) 276 { 277 udf_debug("bread failed (inode=%ld)\n", inode->i_ino); 278 return -EIO; 279 } 280 281 if (UDF_I_EXTENDED_FE(inode) == 0) 282 { 283 struct fileEntry *fe; 284 285 fe = (struct fileEntry *)bh->b_data; 286 eaicb = lela_to_cpu(fe->extendedAttrICB); 287 if (UDF_I_LENEATTR(inode)) 288 ea = fe->extendedAttr; 289 } 290 else 291 { 292 struct extendedFileEntry *efe; 293 294 efe = (struct extendedFileEntry *)bh->b_data; 295 eaicb = lela_to_cpu(efe->extendedAttrICB); 296 if (UDF_I_LENEATTR(inode)) 297 ea = efe->extendedAttr; 298 } 299 300 switch (cmd) 301 { 302 case UDF_GETEASIZE: 303 result = put_user(UDF_I_LENEATTR(inode), (int *)arg); 304 break; 305 306 case UDF_GETEABLOCK: 307 result = copy_to_user((char *)arg, ea, 308 UDF_I_LENEATTR(inode)) ? -EFAULT : 0; 309 break; 310 } 311 312 udf_release_data(bh); 313 return result; 314} 315 316/* 317 * udf_release_file 318 * 319 * PURPOSE 320 * Called when all references to the file are closed 321 * 322 * DESCRIPTION 323 * Discard prealloced blocks 324 * 325 * HISTORY 326 * 327 */ 328static int udf_release_file(struct inode * inode, struct file * filp) 329{ 330 if (filp->f_mode & FMODE_WRITE) 331 { 332 lock_kernel(); 333 udf_discard_prealloc(inode); 334 unlock_kernel(); 335 } 336 return 0; 337} 338 339/* 340 * udf_open_file 341 * 342 * PURPOSE 343 * Called when an inode is about to be open. 344 * 345 * DESCRIPTION 346 * Use this to disallow opening RW large files on 32 bit systems. 347 * On 64 bit systems we force on O_LARGEFILE in sys_open. 348 * 349 * HISTORY 350 * 351 */ 352static int udf_open_file(struct inode * inode, struct file * filp) 353{ 354 if ((inode->i_size & 0xFFFFFFFF80000000ULL) && !(filp->f_flags & O_LARGEFILE)) 355 return -EFBIG; 356 return 0; 357} 358 359struct file_operations udf_file_operations = { 360 read: generic_file_read, 361 ioctl: udf_ioctl, 362 open: udf_open_file, 363 mmap: generic_file_mmap, 364 write: udf_file_write, 365 release: udf_release_file, 366 fsync: udf_fsync_file, 367}; 368 369struct inode_operations udf_file_inode_operations = { 370 truncate: udf_truncate, 371}; 372