1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * inode.c 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * PURPOSE 5*1da177e4SLinus Torvalds * Inode handling routines for the OSTA-UDF(tm) filesystem. 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * CONTACTS 8*1da177e4SLinus Torvalds * E-mail regarding any portion of the Linux UDF file system should be 9*1da177e4SLinus Torvalds * directed to the development team mailing list (run by majordomo): 10*1da177e4SLinus Torvalds * linux_udf@hpesjro.fc.hp.com 11*1da177e4SLinus Torvalds * 12*1da177e4SLinus Torvalds * COPYRIGHT 13*1da177e4SLinus Torvalds * This file is distributed under the terms of the GNU General Public 14*1da177e4SLinus Torvalds * License (GPL). Copies of the GPL can be obtained from: 15*1da177e4SLinus Torvalds * ftp://prep.ai.mit.edu/pub/gnu/GPL 16*1da177e4SLinus Torvalds * Each contributing author retains all rights to their own work. 17*1da177e4SLinus Torvalds * 18*1da177e4SLinus Torvalds * (C) 1998 Dave Boynton 19*1da177e4SLinus Torvalds * (C) 1998-2004 Ben Fennema 20*1da177e4SLinus Torvalds * (C) 1999-2000 Stelias Computing Inc 21*1da177e4SLinus Torvalds * 22*1da177e4SLinus Torvalds * HISTORY 23*1da177e4SLinus Torvalds * 24*1da177e4SLinus Torvalds * 10/04/98 dgb Added rudimentary directory functions 25*1da177e4SLinus Torvalds * 10/07/98 Fully working udf_block_map! It works! 26*1da177e4SLinus Torvalds * 11/25/98 bmap altered to better support extents 27*1da177e4SLinus Torvalds * 12/06/98 blf partition support in udf_iget, udf_block_map and udf_read_inode 28*1da177e4SLinus Torvalds * 12/12/98 rewrote udf_block_map to handle next extents and descs across 29*1da177e4SLinus Torvalds * block boundaries (which is not actually allowed) 30*1da177e4SLinus Torvalds * 12/20/98 added support for strategy 4096 31*1da177e4SLinus Torvalds * 03/07/99 rewrote udf_block_map (again) 32*1da177e4SLinus Torvalds * New funcs, inode_bmap, udf_next_aext 33*1da177e4SLinus Torvalds * 04/19/99 Support for writing device EA's for major/minor # 34*1da177e4SLinus Torvalds */ 35*1da177e4SLinus Torvalds 36*1da177e4SLinus Torvalds #include "udfdecl.h" 37*1da177e4SLinus Torvalds #include <linux/mm.h> 38*1da177e4SLinus Torvalds #include <linux/smp_lock.h> 39*1da177e4SLinus Torvalds #include <linux/module.h> 40*1da177e4SLinus Torvalds #include <linux/pagemap.h> 41*1da177e4SLinus Torvalds #include <linux/buffer_head.h> 42*1da177e4SLinus Torvalds #include <linux/writeback.h> 43*1da177e4SLinus Torvalds #include <linux/slab.h> 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds #include "udf_i.h" 46*1da177e4SLinus Torvalds #include "udf_sb.h" 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds MODULE_AUTHOR("Ben Fennema"); 49*1da177e4SLinus Torvalds MODULE_DESCRIPTION("Universal Disk Format Filesystem"); 50*1da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 51*1da177e4SLinus Torvalds 52*1da177e4SLinus Torvalds #define EXTENT_MERGE_SIZE 5 53*1da177e4SLinus Torvalds 54*1da177e4SLinus Torvalds static mode_t udf_convert_permissions(struct fileEntry *); 55*1da177e4SLinus Torvalds static int udf_update_inode(struct inode *, int); 56*1da177e4SLinus Torvalds static void udf_fill_inode(struct inode *, struct buffer_head *); 57*1da177e4SLinus Torvalds static struct buffer_head *inode_getblk(struct inode *, long, int *, 58*1da177e4SLinus Torvalds long *, int *); 59*1da177e4SLinus Torvalds static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, 60*1da177e4SLinus Torvalds kernel_lb_addr, uint32_t, struct buffer_head *); 61*1da177e4SLinus Torvalds static void udf_split_extents(struct inode *, int *, int, int, 62*1da177e4SLinus Torvalds kernel_long_ad [EXTENT_MERGE_SIZE], int *); 63*1da177e4SLinus Torvalds static void udf_prealloc_extents(struct inode *, int, int, 64*1da177e4SLinus Torvalds kernel_long_ad [EXTENT_MERGE_SIZE], int *); 65*1da177e4SLinus Torvalds static void udf_merge_extents(struct inode *, 66*1da177e4SLinus Torvalds kernel_long_ad [EXTENT_MERGE_SIZE], int *); 67*1da177e4SLinus Torvalds static void udf_update_extents(struct inode *, 68*1da177e4SLinus Torvalds kernel_long_ad [EXTENT_MERGE_SIZE], int, int, 69*1da177e4SLinus Torvalds kernel_lb_addr, uint32_t, struct buffer_head **); 70*1da177e4SLinus Torvalds static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); 71*1da177e4SLinus Torvalds 72*1da177e4SLinus Torvalds /* 73*1da177e4SLinus Torvalds * udf_delete_inode 74*1da177e4SLinus Torvalds * 75*1da177e4SLinus Torvalds * PURPOSE 76*1da177e4SLinus Torvalds * Clean-up before the specified inode is destroyed. 77*1da177e4SLinus Torvalds * 78*1da177e4SLinus Torvalds * DESCRIPTION 79*1da177e4SLinus Torvalds * This routine is called when the kernel destroys an inode structure 80*1da177e4SLinus Torvalds * ie. when iput() finds i_count == 0. 81*1da177e4SLinus Torvalds * 82*1da177e4SLinus Torvalds * HISTORY 83*1da177e4SLinus Torvalds * July 1, 1997 - Andrew E. Mileski 84*1da177e4SLinus Torvalds * Written, tested, and released. 85*1da177e4SLinus Torvalds * 86*1da177e4SLinus Torvalds * Called at the last iput() if i_nlink is zero. 87*1da177e4SLinus Torvalds */ 88*1da177e4SLinus Torvalds void udf_delete_inode(struct inode * inode) 89*1da177e4SLinus Torvalds { 90*1da177e4SLinus Torvalds if (is_bad_inode(inode)) 91*1da177e4SLinus Torvalds goto no_delete; 92*1da177e4SLinus Torvalds 93*1da177e4SLinus Torvalds inode->i_size = 0; 94*1da177e4SLinus Torvalds udf_truncate(inode); 95*1da177e4SLinus Torvalds lock_kernel(); 96*1da177e4SLinus Torvalds 97*1da177e4SLinus Torvalds udf_update_inode(inode, IS_SYNC(inode)); 98*1da177e4SLinus Torvalds udf_free_inode(inode); 99*1da177e4SLinus Torvalds 100*1da177e4SLinus Torvalds unlock_kernel(); 101*1da177e4SLinus Torvalds return; 102*1da177e4SLinus Torvalds no_delete: 103*1da177e4SLinus Torvalds clear_inode(inode); 104*1da177e4SLinus Torvalds } 105*1da177e4SLinus Torvalds 106*1da177e4SLinus Torvalds void udf_clear_inode(struct inode *inode) 107*1da177e4SLinus Torvalds { 108*1da177e4SLinus Torvalds if (!(inode->i_sb->s_flags & MS_RDONLY)) { 109*1da177e4SLinus Torvalds lock_kernel(); 110*1da177e4SLinus Torvalds udf_discard_prealloc(inode); 111*1da177e4SLinus Torvalds unlock_kernel(); 112*1da177e4SLinus Torvalds } 113*1da177e4SLinus Torvalds 114*1da177e4SLinus Torvalds kfree(UDF_I_DATA(inode)); 115*1da177e4SLinus Torvalds UDF_I_DATA(inode) = NULL; 116*1da177e4SLinus Torvalds } 117*1da177e4SLinus Torvalds 118*1da177e4SLinus Torvalds static int udf_writepage(struct page *page, struct writeback_control *wbc) 119*1da177e4SLinus Torvalds { 120*1da177e4SLinus Torvalds return block_write_full_page(page, udf_get_block, wbc); 121*1da177e4SLinus Torvalds } 122*1da177e4SLinus Torvalds 123*1da177e4SLinus Torvalds static int udf_readpage(struct file *file, struct page *page) 124*1da177e4SLinus Torvalds { 125*1da177e4SLinus Torvalds return block_read_full_page(page, udf_get_block); 126*1da177e4SLinus Torvalds } 127*1da177e4SLinus Torvalds 128*1da177e4SLinus Torvalds static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 129*1da177e4SLinus Torvalds { 130*1da177e4SLinus Torvalds return block_prepare_write(page, from, to, udf_get_block); 131*1da177e4SLinus Torvalds } 132*1da177e4SLinus Torvalds 133*1da177e4SLinus Torvalds static sector_t udf_bmap(struct address_space *mapping, sector_t block) 134*1da177e4SLinus Torvalds { 135*1da177e4SLinus Torvalds return generic_block_bmap(mapping,block,udf_get_block); 136*1da177e4SLinus Torvalds } 137*1da177e4SLinus Torvalds 138*1da177e4SLinus Torvalds struct address_space_operations udf_aops = { 139*1da177e4SLinus Torvalds .readpage = udf_readpage, 140*1da177e4SLinus Torvalds .writepage = udf_writepage, 141*1da177e4SLinus Torvalds .sync_page = block_sync_page, 142*1da177e4SLinus Torvalds .prepare_write = udf_prepare_write, 143*1da177e4SLinus Torvalds .commit_write = generic_commit_write, 144*1da177e4SLinus Torvalds .bmap = udf_bmap, 145*1da177e4SLinus Torvalds }; 146*1da177e4SLinus Torvalds 147*1da177e4SLinus Torvalds void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) 148*1da177e4SLinus Torvalds { 149*1da177e4SLinus Torvalds struct page *page; 150*1da177e4SLinus Torvalds char *kaddr; 151*1da177e4SLinus Torvalds struct writeback_control udf_wbc = { 152*1da177e4SLinus Torvalds .sync_mode = WB_SYNC_NONE, 153*1da177e4SLinus Torvalds .nr_to_write = 1, 154*1da177e4SLinus Torvalds }; 155*1da177e4SLinus Torvalds 156*1da177e4SLinus Torvalds /* from now on we have normal address_space methods */ 157*1da177e4SLinus Torvalds inode->i_data.a_ops = &udf_aops; 158*1da177e4SLinus Torvalds 159*1da177e4SLinus Torvalds if (!UDF_I_LENALLOC(inode)) 160*1da177e4SLinus Torvalds { 161*1da177e4SLinus Torvalds if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) 162*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT; 163*1da177e4SLinus Torvalds else 164*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG; 165*1da177e4SLinus Torvalds mark_inode_dirty(inode); 166*1da177e4SLinus Torvalds return; 167*1da177e4SLinus Torvalds } 168*1da177e4SLinus Torvalds 169*1da177e4SLinus Torvalds page = grab_cache_page(inode->i_mapping, 0); 170*1da177e4SLinus Torvalds if (!PageLocked(page)) 171*1da177e4SLinus Torvalds PAGE_BUG(page); 172*1da177e4SLinus Torvalds if (!PageUptodate(page)) 173*1da177e4SLinus Torvalds { 174*1da177e4SLinus Torvalds kaddr = kmap(page); 175*1da177e4SLinus Torvalds memset(kaddr + UDF_I_LENALLOC(inode), 0x00, 176*1da177e4SLinus Torvalds PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode)); 177*1da177e4SLinus Torvalds memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 178*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode)); 179*1da177e4SLinus Torvalds flush_dcache_page(page); 180*1da177e4SLinus Torvalds SetPageUptodate(page); 181*1da177e4SLinus Torvalds kunmap(page); 182*1da177e4SLinus Torvalds } 183*1da177e4SLinus Torvalds memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00, 184*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode)); 185*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = 0; 186*1da177e4SLinus Torvalds if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) 187*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT; 188*1da177e4SLinus Torvalds else 189*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG; 190*1da177e4SLinus Torvalds 191*1da177e4SLinus Torvalds inode->i_data.a_ops->writepage(page, &udf_wbc); 192*1da177e4SLinus Torvalds page_cache_release(page); 193*1da177e4SLinus Torvalds 194*1da177e4SLinus Torvalds mark_inode_dirty(inode); 195*1da177e4SLinus Torvalds } 196*1da177e4SLinus Torvalds 197*1da177e4SLinus Torvalds struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) 198*1da177e4SLinus Torvalds { 199*1da177e4SLinus Torvalds int newblock; 200*1da177e4SLinus Torvalds struct buffer_head *sbh = NULL, *dbh = NULL; 201*1da177e4SLinus Torvalds kernel_lb_addr bloc, eloc; 202*1da177e4SLinus Torvalds uint32_t elen, extoffset; 203*1da177e4SLinus Torvalds uint8_t alloctype; 204*1da177e4SLinus Torvalds 205*1da177e4SLinus Torvalds struct udf_fileident_bh sfibh, dfibh; 206*1da177e4SLinus Torvalds loff_t f_pos = udf_ext0_offset(inode) >> 2; 207*1da177e4SLinus Torvalds int size = (udf_ext0_offset(inode) + inode->i_size) >> 2; 208*1da177e4SLinus Torvalds struct fileIdentDesc cfi, *sfi, *dfi; 209*1da177e4SLinus Torvalds 210*1da177e4SLinus Torvalds if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) 211*1da177e4SLinus Torvalds alloctype = ICBTAG_FLAG_AD_SHORT; 212*1da177e4SLinus Torvalds else 213*1da177e4SLinus Torvalds alloctype = ICBTAG_FLAG_AD_LONG; 214*1da177e4SLinus Torvalds 215*1da177e4SLinus Torvalds if (!inode->i_size) 216*1da177e4SLinus Torvalds { 217*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = alloctype; 218*1da177e4SLinus Torvalds mark_inode_dirty(inode); 219*1da177e4SLinus Torvalds return NULL; 220*1da177e4SLinus Torvalds } 221*1da177e4SLinus Torvalds 222*1da177e4SLinus Torvalds /* alloc block, and copy data to it */ 223*1da177e4SLinus Torvalds *block = udf_new_block(inode->i_sb, inode, 224*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).partitionReferenceNum, 225*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).logicalBlockNum, err); 226*1da177e4SLinus Torvalds 227*1da177e4SLinus Torvalds if (!(*block)) 228*1da177e4SLinus Torvalds return NULL; 229*1da177e4SLinus Torvalds newblock = udf_get_pblock(inode->i_sb, *block, 230*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).partitionReferenceNum, 0); 231*1da177e4SLinus Torvalds if (!newblock) 232*1da177e4SLinus Torvalds return NULL; 233*1da177e4SLinus Torvalds dbh = udf_tgetblk(inode->i_sb, newblock); 234*1da177e4SLinus Torvalds if (!dbh) 235*1da177e4SLinus Torvalds return NULL; 236*1da177e4SLinus Torvalds lock_buffer(dbh); 237*1da177e4SLinus Torvalds memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize); 238*1da177e4SLinus Torvalds set_buffer_uptodate(dbh); 239*1da177e4SLinus Torvalds unlock_buffer(dbh); 240*1da177e4SLinus Torvalds mark_buffer_dirty_inode(dbh, inode); 241*1da177e4SLinus Torvalds 242*1da177e4SLinus Torvalds sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; 243*1da177e4SLinus Torvalds sbh = sfibh.sbh = sfibh.ebh = NULL; 244*1da177e4SLinus Torvalds dfibh.soffset = dfibh.eoffset = 0; 245*1da177e4SLinus Torvalds dfibh.sbh = dfibh.ebh = dbh; 246*1da177e4SLinus Torvalds while ( (f_pos < size) ) 247*1da177e4SLinus Torvalds { 248*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; 249*1da177e4SLinus Torvalds sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL); 250*1da177e4SLinus Torvalds if (!sfi) 251*1da177e4SLinus Torvalds { 252*1da177e4SLinus Torvalds udf_release_data(dbh); 253*1da177e4SLinus Torvalds return NULL; 254*1da177e4SLinus Torvalds } 255*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = alloctype; 256*1da177e4SLinus Torvalds sfi->descTag.tagLocation = cpu_to_le32(*block); 257*1da177e4SLinus Torvalds dfibh.soffset = dfibh.eoffset; 258*1da177e4SLinus Torvalds dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); 259*1da177e4SLinus Torvalds dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset); 260*1da177e4SLinus Torvalds if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse, 261*1da177e4SLinus Torvalds sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) 262*1da177e4SLinus Torvalds { 263*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; 264*1da177e4SLinus Torvalds udf_release_data(dbh); 265*1da177e4SLinus Torvalds return NULL; 266*1da177e4SLinus Torvalds } 267*1da177e4SLinus Torvalds } 268*1da177e4SLinus Torvalds mark_buffer_dirty_inode(dbh, inode); 269*1da177e4SLinus Torvalds 270*1da177e4SLinus Torvalds memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); 271*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = 0; 272*1da177e4SLinus Torvalds bloc = UDF_I_LOCATION(inode); 273*1da177e4SLinus Torvalds eloc.logicalBlockNum = *block; 274*1da177e4SLinus Torvalds eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; 275*1da177e4SLinus Torvalds elen = inode->i_size; 276*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) = elen; 277*1da177e4SLinus Torvalds extoffset = udf_file_entry_alloc_offset(inode); 278*1da177e4SLinus Torvalds udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0); 279*1da177e4SLinus Torvalds /* UniqueID stuff */ 280*1da177e4SLinus Torvalds 281*1da177e4SLinus Torvalds udf_release_data(sbh); 282*1da177e4SLinus Torvalds mark_inode_dirty(inode); 283*1da177e4SLinus Torvalds return dbh; 284*1da177e4SLinus Torvalds } 285*1da177e4SLinus Torvalds 286*1da177e4SLinus Torvalds static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) 287*1da177e4SLinus Torvalds { 288*1da177e4SLinus Torvalds int err, new; 289*1da177e4SLinus Torvalds struct buffer_head *bh; 290*1da177e4SLinus Torvalds unsigned long phys; 291*1da177e4SLinus Torvalds 292*1da177e4SLinus Torvalds if (!create) 293*1da177e4SLinus Torvalds { 294*1da177e4SLinus Torvalds phys = udf_block_map(inode, block); 295*1da177e4SLinus Torvalds if (phys) 296*1da177e4SLinus Torvalds map_bh(bh_result, inode->i_sb, phys); 297*1da177e4SLinus Torvalds return 0; 298*1da177e4SLinus Torvalds } 299*1da177e4SLinus Torvalds 300*1da177e4SLinus Torvalds err = -EIO; 301*1da177e4SLinus Torvalds new = 0; 302*1da177e4SLinus Torvalds bh = NULL; 303*1da177e4SLinus Torvalds 304*1da177e4SLinus Torvalds lock_kernel(); 305*1da177e4SLinus Torvalds 306*1da177e4SLinus Torvalds if (block < 0) 307*1da177e4SLinus Torvalds goto abort_negative; 308*1da177e4SLinus Torvalds 309*1da177e4SLinus Torvalds if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) 310*1da177e4SLinus Torvalds { 311*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_BLOCK(inode) ++; 312*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_GOAL(inode) ++; 313*1da177e4SLinus Torvalds } 314*1da177e4SLinus Torvalds 315*1da177e4SLinus Torvalds err = 0; 316*1da177e4SLinus Torvalds 317*1da177e4SLinus Torvalds bh = inode_getblk(inode, block, &err, &phys, &new); 318*1da177e4SLinus Torvalds if (bh) 319*1da177e4SLinus Torvalds BUG(); 320*1da177e4SLinus Torvalds if (err) 321*1da177e4SLinus Torvalds goto abort; 322*1da177e4SLinus Torvalds if (!phys) 323*1da177e4SLinus Torvalds BUG(); 324*1da177e4SLinus Torvalds 325*1da177e4SLinus Torvalds if (new) 326*1da177e4SLinus Torvalds set_buffer_new(bh_result); 327*1da177e4SLinus Torvalds map_bh(bh_result, inode->i_sb, phys); 328*1da177e4SLinus Torvalds abort: 329*1da177e4SLinus Torvalds unlock_kernel(); 330*1da177e4SLinus Torvalds return err; 331*1da177e4SLinus Torvalds 332*1da177e4SLinus Torvalds abort_negative: 333*1da177e4SLinus Torvalds udf_warning(inode->i_sb, "udf_get_block", "block < 0"); 334*1da177e4SLinus Torvalds goto abort; 335*1da177e4SLinus Torvalds } 336*1da177e4SLinus Torvalds 337*1da177e4SLinus Torvalds static struct buffer_head * 338*1da177e4SLinus Torvalds udf_getblk(struct inode *inode, long block, int create, int *err) 339*1da177e4SLinus Torvalds { 340*1da177e4SLinus Torvalds struct buffer_head dummy; 341*1da177e4SLinus Torvalds 342*1da177e4SLinus Torvalds dummy.b_state = 0; 343*1da177e4SLinus Torvalds dummy.b_blocknr = -1000; 344*1da177e4SLinus Torvalds *err = udf_get_block(inode, block, &dummy, create); 345*1da177e4SLinus Torvalds if (!*err && buffer_mapped(&dummy)) 346*1da177e4SLinus Torvalds { 347*1da177e4SLinus Torvalds struct buffer_head *bh; 348*1da177e4SLinus Torvalds bh = sb_getblk(inode->i_sb, dummy.b_blocknr); 349*1da177e4SLinus Torvalds if (buffer_new(&dummy)) 350*1da177e4SLinus Torvalds { 351*1da177e4SLinus Torvalds lock_buffer(bh); 352*1da177e4SLinus Torvalds memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); 353*1da177e4SLinus Torvalds set_buffer_uptodate(bh); 354*1da177e4SLinus Torvalds unlock_buffer(bh); 355*1da177e4SLinus Torvalds mark_buffer_dirty_inode(bh, inode); 356*1da177e4SLinus Torvalds } 357*1da177e4SLinus Torvalds return bh; 358*1da177e4SLinus Torvalds } 359*1da177e4SLinus Torvalds return NULL; 360*1da177e4SLinus Torvalds } 361*1da177e4SLinus Torvalds 362*1da177e4SLinus Torvalds static struct buffer_head * inode_getblk(struct inode * inode, long block, 363*1da177e4SLinus Torvalds int *err, long *phys, int *new) 364*1da177e4SLinus Torvalds { 365*1da177e4SLinus Torvalds struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; 366*1da177e4SLinus Torvalds kernel_long_ad laarr[EXTENT_MERGE_SIZE]; 367*1da177e4SLinus Torvalds uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; 368*1da177e4SLinus Torvalds int count = 0, startnum = 0, endnum = 0; 369*1da177e4SLinus Torvalds uint32_t elen = 0; 370*1da177e4SLinus Torvalds kernel_lb_addr eloc, pbloc, cbloc, nbloc; 371*1da177e4SLinus Torvalds int c = 1; 372*1da177e4SLinus Torvalds uint64_t lbcount = 0, b_off = 0; 373*1da177e4SLinus Torvalds uint32_t newblocknum, newblock, offset = 0; 374*1da177e4SLinus Torvalds int8_t etype; 375*1da177e4SLinus Torvalds int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; 376*1da177e4SLinus Torvalds char lastblock = 0; 377*1da177e4SLinus Torvalds 378*1da177e4SLinus Torvalds pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode); 379*1da177e4SLinus Torvalds b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits; 380*1da177e4SLinus Torvalds pbloc = cbloc = nbloc = UDF_I_LOCATION(inode); 381*1da177e4SLinus Torvalds 382*1da177e4SLinus Torvalds /* find the extent which contains the block we are looking for. 383*1da177e4SLinus Torvalds alternate between laarr[0] and laarr[1] for locations of the 384*1da177e4SLinus Torvalds current extent, and the previous extent */ 385*1da177e4SLinus Torvalds do 386*1da177e4SLinus Torvalds { 387*1da177e4SLinus Torvalds if (pbh != cbh) 388*1da177e4SLinus Torvalds { 389*1da177e4SLinus Torvalds udf_release_data(pbh); 390*1da177e4SLinus Torvalds atomic_inc(&cbh->b_count); 391*1da177e4SLinus Torvalds pbh = cbh; 392*1da177e4SLinus Torvalds } 393*1da177e4SLinus Torvalds if (cbh != nbh) 394*1da177e4SLinus Torvalds { 395*1da177e4SLinus Torvalds udf_release_data(cbh); 396*1da177e4SLinus Torvalds atomic_inc(&nbh->b_count); 397*1da177e4SLinus Torvalds cbh = nbh; 398*1da177e4SLinus Torvalds } 399*1da177e4SLinus Torvalds 400*1da177e4SLinus Torvalds lbcount += elen; 401*1da177e4SLinus Torvalds 402*1da177e4SLinus Torvalds pbloc = cbloc; 403*1da177e4SLinus Torvalds cbloc = nbloc; 404*1da177e4SLinus Torvalds 405*1da177e4SLinus Torvalds pextoffset = cextoffset; 406*1da177e4SLinus Torvalds cextoffset = nextoffset; 407*1da177e4SLinus Torvalds 408*1da177e4SLinus Torvalds if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1) 409*1da177e4SLinus Torvalds break; 410*1da177e4SLinus Torvalds 411*1da177e4SLinus Torvalds c = !c; 412*1da177e4SLinus Torvalds 413*1da177e4SLinus Torvalds laarr[c].extLength = (etype << 30) | elen; 414*1da177e4SLinus Torvalds laarr[c].extLocation = eloc; 415*1da177e4SLinus Torvalds 416*1da177e4SLinus Torvalds if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 417*1da177e4SLinus Torvalds pgoal = eloc.logicalBlockNum + 418*1da177e4SLinus Torvalds ((elen + inode->i_sb->s_blocksize - 1) >> 419*1da177e4SLinus Torvalds inode->i_sb->s_blocksize_bits); 420*1da177e4SLinus Torvalds 421*1da177e4SLinus Torvalds count ++; 422*1da177e4SLinus Torvalds } while (lbcount + elen <= b_off); 423*1da177e4SLinus Torvalds 424*1da177e4SLinus Torvalds b_off -= lbcount; 425*1da177e4SLinus Torvalds offset = b_off >> inode->i_sb->s_blocksize_bits; 426*1da177e4SLinus Torvalds 427*1da177e4SLinus Torvalds /* if the extent is allocated and recorded, return the block 428*1da177e4SLinus Torvalds if the extent is not a multiple of the blocksize, round up */ 429*1da177e4SLinus Torvalds 430*1da177e4SLinus Torvalds if (etype == (EXT_RECORDED_ALLOCATED >> 30)) 431*1da177e4SLinus Torvalds { 432*1da177e4SLinus Torvalds if (elen & (inode->i_sb->s_blocksize - 1)) 433*1da177e4SLinus Torvalds { 434*1da177e4SLinus Torvalds elen = EXT_RECORDED_ALLOCATED | 435*1da177e4SLinus Torvalds ((elen + inode->i_sb->s_blocksize - 1) & 436*1da177e4SLinus Torvalds ~(inode->i_sb->s_blocksize - 1)); 437*1da177e4SLinus Torvalds etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1); 438*1da177e4SLinus Torvalds } 439*1da177e4SLinus Torvalds udf_release_data(pbh); 440*1da177e4SLinus Torvalds udf_release_data(cbh); 441*1da177e4SLinus Torvalds udf_release_data(nbh); 442*1da177e4SLinus Torvalds newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); 443*1da177e4SLinus Torvalds *phys = newblock; 444*1da177e4SLinus Torvalds return NULL; 445*1da177e4SLinus Torvalds } 446*1da177e4SLinus Torvalds 447*1da177e4SLinus Torvalds if (etype == -1) 448*1da177e4SLinus Torvalds { 449*1da177e4SLinus Torvalds endnum = startnum = ((count > 1) ? 1 : count); 450*1da177e4SLinus Torvalds if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1)) 451*1da177e4SLinus Torvalds { 452*1da177e4SLinus Torvalds laarr[c].extLength = 453*1da177e4SLinus Torvalds (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) | 454*1da177e4SLinus Torvalds (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) + 455*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) & 456*1da177e4SLinus Torvalds ~(inode->i_sb->s_blocksize - 1)); 457*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) = 458*1da177e4SLinus Torvalds (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) & 459*1da177e4SLinus Torvalds ~(inode->i_sb->s_blocksize - 1); 460*1da177e4SLinus Torvalds } 461*1da177e4SLinus Torvalds c = !c; 462*1da177e4SLinus Torvalds laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | 463*1da177e4SLinus Torvalds ((offset + 1) << inode->i_sb->s_blocksize_bits); 464*1da177e4SLinus Torvalds memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); 465*1da177e4SLinus Torvalds count ++; 466*1da177e4SLinus Torvalds endnum ++; 467*1da177e4SLinus Torvalds lastblock = 1; 468*1da177e4SLinus Torvalds } 469*1da177e4SLinus Torvalds else 470*1da177e4SLinus Torvalds endnum = startnum = ((count > 2) ? 2 : count); 471*1da177e4SLinus Torvalds 472*1da177e4SLinus Torvalds /* if the current extent is in position 0, swap it with the previous */ 473*1da177e4SLinus Torvalds if (!c && count != 1) 474*1da177e4SLinus Torvalds { 475*1da177e4SLinus Torvalds laarr[2] = laarr[0]; 476*1da177e4SLinus Torvalds laarr[0] = laarr[1]; 477*1da177e4SLinus Torvalds laarr[1] = laarr[2]; 478*1da177e4SLinus Torvalds c = 1; 479*1da177e4SLinus Torvalds } 480*1da177e4SLinus Torvalds 481*1da177e4SLinus Torvalds /* if the current block is located in a extent, read the next extent */ 482*1da177e4SLinus Torvalds if (etype != -1) 483*1da177e4SLinus Torvalds { 484*1da177e4SLinus Torvalds if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1) 485*1da177e4SLinus Torvalds { 486*1da177e4SLinus Torvalds laarr[c+1].extLength = (etype << 30) | elen; 487*1da177e4SLinus Torvalds laarr[c+1].extLocation = eloc; 488*1da177e4SLinus Torvalds count ++; 489*1da177e4SLinus Torvalds startnum ++; 490*1da177e4SLinus Torvalds endnum ++; 491*1da177e4SLinus Torvalds } 492*1da177e4SLinus Torvalds else 493*1da177e4SLinus Torvalds lastblock = 1; 494*1da177e4SLinus Torvalds } 495*1da177e4SLinus Torvalds udf_release_data(cbh); 496*1da177e4SLinus Torvalds udf_release_data(nbh); 497*1da177e4SLinus Torvalds 498*1da177e4SLinus Torvalds /* if the current extent is not recorded but allocated, get the 499*1da177e4SLinus Torvalds block in the extent corresponding to the requested block */ 500*1da177e4SLinus Torvalds if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) 501*1da177e4SLinus Torvalds newblocknum = laarr[c].extLocation.logicalBlockNum + offset; 502*1da177e4SLinus Torvalds else /* otherwise, allocate a new block */ 503*1da177e4SLinus Torvalds { 504*1da177e4SLinus Torvalds if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block) 505*1da177e4SLinus Torvalds goal = UDF_I_NEXT_ALLOC_GOAL(inode); 506*1da177e4SLinus Torvalds 507*1da177e4SLinus Torvalds if (!goal) 508*1da177e4SLinus Torvalds { 509*1da177e4SLinus Torvalds if (!(goal = pgoal)) 510*1da177e4SLinus Torvalds goal = UDF_I_LOCATION(inode).logicalBlockNum + 1; 511*1da177e4SLinus Torvalds } 512*1da177e4SLinus Torvalds 513*1da177e4SLinus Torvalds if (!(newblocknum = udf_new_block(inode->i_sb, inode, 514*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) 515*1da177e4SLinus Torvalds { 516*1da177e4SLinus Torvalds udf_release_data(pbh); 517*1da177e4SLinus Torvalds *err = -ENOSPC; 518*1da177e4SLinus Torvalds return NULL; 519*1da177e4SLinus Torvalds } 520*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize; 521*1da177e4SLinus Torvalds } 522*1da177e4SLinus Torvalds 523*1da177e4SLinus Torvalds /* if the extent the requsted block is located in contains multiple blocks, 524*1da177e4SLinus Torvalds split the extent into at most three extents. blocks prior to requested 525*1da177e4SLinus Torvalds block, requested block, and blocks after requested block */ 526*1da177e4SLinus Torvalds udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); 527*1da177e4SLinus Torvalds 528*1da177e4SLinus Torvalds #ifdef UDF_PREALLOCATE 529*1da177e4SLinus Torvalds /* preallocate blocks */ 530*1da177e4SLinus Torvalds udf_prealloc_extents(inode, c, lastblock, laarr, &endnum); 531*1da177e4SLinus Torvalds #endif 532*1da177e4SLinus Torvalds 533*1da177e4SLinus Torvalds /* merge any continuous blocks in laarr */ 534*1da177e4SLinus Torvalds udf_merge_extents(inode, laarr, &endnum); 535*1da177e4SLinus Torvalds 536*1da177e4SLinus Torvalds /* write back the new extents, inserting new extents if the new number 537*1da177e4SLinus Torvalds of extents is greater than the old number, and deleting extents if 538*1da177e4SLinus Torvalds the new number of extents is less than the old number */ 539*1da177e4SLinus Torvalds udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh); 540*1da177e4SLinus Torvalds 541*1da177e4SLinus Torvalds udf_release_data(pbh); 542*1da177e4SLinus Torvalds 543*1da177e4SLinus Torvalds if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, 544*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).partitionReferenceNum, 0))) 545*1da177e4SLinus Torvalds { 546*1da177e4SLinus Torvalds return NULL; 547*1da177e4SLinus Torvalds } 548*1da177e4SLinus Torvalds *phys = newblock; 549*1da177e4SLinus Torvalds *err = 0; 550*1da177e4SLinus Torvalds *new = 1; 551*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_BLOCK(inode) = block; 552*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum; 553*1da177e4SLinus Torvalds inode->i_ctime = current_fs_time(inode->i_sb); 554*1da177e4SLinus Torvalds 555*1da177e4SLinus Torvalds if (IS_SYNC(inode)) 556*1da177e4SLinus Torvalds udf_sync_inode(inode); 557*1da177e4SLinus Torvalds else 558*1da177e4SLinus Torvalds mark_inode_dirty(inode); 559*1da177e4SLinus Torvalds return result; 560*1da177e4SLinus Torvalds } 561*1da177e4SLinus Torvalds 562*1da177e4SLinus Torvalds static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum, 563*1da177e4SLinus Torvalds kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) 564*1da177e4SLinus Torvalds { 565*1da177e4SLinus Torvalds if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) || 566*1da177e4SLinus Torvalds (laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 567*1da177e4SLinus Torvalds { 568*1da177e4SLinus Torvalds int curr = *c; 569*1da177e4SLinus Torvalds int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) + 570*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; 571*1da177e4SLinus Torvalds int8_t etype = (laarr[curr].extLength >> 30); 572*1da177e4SLinus Torvalds 573*1da177e4SLinus Torvalds if (blen == 1) 574*1da177e4SLinus Torvalds ; 575*1da177e4SLinus Torvalds else if (!offset || blen == offset + 1) 576*1da177e4SLinus Torvalds { 577*1da177e4SLinus Torvalds laarr[curr+2] = laarr[curr+1]; 578*1da177e4SLinus Torvalds laarr[curr+1] = laarr[curr]; 579*1da177e4SLinus Torvalds } 580*1da177e4SLinus Torvalds else 581*1da177e4SLinus Torvalds { 582*1da177e4SLinus Torvalds laarr[curr+3] = laarr[curr+1]; 583*1da177e4SLinus Torvalds laarr[curr+2] = laarr[curr+1] = laarr[curr]; 584*1da177e4SLinus Torvalds } 585*1da177e4SLinus Torvalds 586*1da177e4SLinus Torvalds if (offset) 587*1da177e4SLinus Torvalds { 588*1da177e4SLinus Torvalds if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) 589*1da177e4SLinus Torvalds { 590*1da177e4SLinus Torvalds udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset); 591*1da177e4SLinus Torvalds laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | 592*1da177e4SLinus Torvalds (offset << inode->i_sb->s_blocksize_bits); 593*1da177e4SLinus Torvalds laarr[curr].extLocation.logicalBlockNum = 0; 594*1da177e4SLinus Torvalds laarr[curr].extLocation.partitionReferenceNum = 0; 595*1da177e4SLinus Torvalds } 596*1da177e4SLinus Torvalds else 597*1da177e4SLinus Torvalds laarr[curr].extLength = (etype << 30) | 598*1da177e4SLinus Torvalds (offset << inode->i_sb->s_blocksize_bits); 599*1da177e4SLinus Torvalds curr ++; 600*1da177e4SLinus Torvalds (*c) ++; 601*1da177e4SLinus Torvalds (*endnum) ++; 602*1da177e4SLinus Torvalds } 603*1da177e4SLinus Torvalds 604*1da177e4SLinus Torvalds laarr[curr].extLocation.logicalBlockNum = newblocknum; 605*1da177e4SLinus Torvalds if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 606*1da177e4SLinus Torvalds laarr[curr].extLocation.partitionReferenceNum = 607*1da177e4SLinus Torvalds UDF_I_LOCATION(inode).partitionReferenceNum; 608*1da177e4SLinus Torvalds laarr[curr].extLength = EXT_RECORDED_ALLOCATED | 609*1da177e4SLinus Torvalds inode->i_sb->s_blocksize; 610*1da177e4SLinus Torvalds curr ++; 611*1da177e4SLinus Torvalds 612*1da177e4SLinus Torvalds if (blen != offset + 1) 613*1da177e4SLinus Torvalds { 614*1da177e4SLinus Torvalds if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) 615*1da177e4SLinus Torvalds laarr[curr].extLocation.logicalBlockNum += (offset + 1); 616*1da177e4SLinus Torvalds laarr[curr].extLength = (etype << 30) | 617*1da177e4SLinus Torvalds ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits); 618*1da177e4SLinus Torvalds curr ++; 619*1da177e4SLinus Torvalds (*endnum) ++; 620*1da177e4SLinus Torvalds } 621*1da177e4SLinus Torvalds } 622*1da177e4SLinus Torvalds } 623*1da177e4SLinus Torvalds 624*1da177e4SLinus Torvalds static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, 625*1da177e4SLinus Torvalds kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) 626*1da177e4SLinus Torvalds { 627*1da177e4SLinus Torvalds int start, length = 0, currlength = 0, i; 628*1da177e4SLinus Torvalds 629*1da177e4SLinus Torvalds if (*endnum >= (c+1)) 630*1da177e4SLinus Torvalds { 631*1da177e4SLinus Torvalds if (!lastblock) 632*1da177e4SLinus Torvalds return; 633*1da177e4SLinus Torvalds else 634*1da177e4SLinus Torvalds start = c; 635*1da177e4SLinus Torvalds } 636*1da177e4SLinus Torvalds else 637*1da177e4SLinus Torvalds { 638*1da177e4SLinus Torvalds if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) 639*1da177e4SLinus Torvalds { 640*1da177e4SLinus Torvalds start = c+1; 641*1da177e4SLinus Torvalds length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) + 642*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); 643*1da177e4SLinus Torvalds } 644*1da177e4SLinus Torvalds else 645*1da177e4SLinus Torvalds start = c; 646*1da177e4SLinus Torvalds } 647*1da177e4SLinus Torvalds 648*1da177e4SLinus Torvalds for (i=start+1; i<=*endnum; i++) 649*1da177e4SLinus Torvalds { 650*1da177e4SLinus Torvalds if (i == *endnum) 651*1da177e4SLinus Torvalds { 652*1da177e4SLinus Torvalds if (lastblock) 653*1da177e4SLinus Torvalds length += UDF_DEFAULT_PREALLOC_BLOCKS; 654*1da177e4SLinus Torvalds } 655*1da177e4SLinus Torvalds else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 656*1da177e4SLinus Torvalds length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 657*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); 658*1da177e4SLinus Torvalds else 659*1da177e4SLinus Torvalds break; 660*1da177e4SLinus Torvalds } 661*1da177e4SLinus Torvalds 662*1da177e4SLinus Torvalds if (length) 663*1da177e4SLinus Torvalds { 664*1da177e4SLinus Torvalds int next = laarr[start].extLocation.logicalBlockNum + 665*1da177e4SLinus Torvalds (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) + 666*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); 667*1da177e4SLinus Torvalds int numalloc = udf_prealloc_blocks(inode->i_sb, inode, 668*1da177e4SLinus Torvalds laarr[start].extLocation.partitionReferenceNum, 669*1da177e4SLinus Torvalds next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length : 670*1da177e4SLinus Torvalds UDF_DEFAULT_PREALLOC_BLOCKS) - currlength); 671*1da177e4SLinus Torvalds 672*1da177e4SLinus Torvalds if (numalloc) 673*1da177e4SLinus Torvalds { 674*1da177e4SLinus Torvalds if (start == (c+1)) 675*1da177e4SLinus Torvalds laarr[start].extLength += 676*1da177e4SLinus Torvalds (numalloc << inode->i_sb->s_blocksize_bits); 677*1da177e4SLinus Torvalds else 678*1da177e4SLinus Torvalds { 679*1da177e4SLinus Torvalds memmove(&laarr[c+2], &laarr[c+1], 680*1da177e4SLinus Torvalds sizeof(long_ad) * (*endnum - (c+1))); 681*1da177e4SLinus Torvalds (*endnum) ++; 682*1da177e4SLinus Torvalds laarr[c+1].extLocation.logicalBlockNum = next; 683*1da177e4SLinus Torvalds laarr[c+1].extLocation.partitionReferenceNum = 684*1da177e4SLinus Torvalds laarr[c].extLocation.partitionReferenceNum; 685*1da177e4SLinus Torvalds laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED | 686*1da177e4SLinus Torvalds (numalloc << inode->i_sb->s_blocksize_bits); 687*1da177e4SLinus Torvalds start = c+1; 688*1da177e4SLinus Torvalds } 689*1da177e4SLinus Torvalds 690*1da177e4SLinus Torvalds for (i=start+1; numalloc && i<*endnum; i++) 691*1da177e4SLinus Torvalds { 692*1da177e4SLinus Torvalds int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 693*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; 694*1da177e4SLinus Torvalds 695*1da177e4SLinus Torvalds if (elen > numalloc) 696*1da177e4SLinus Torvalds { 697*1da177e4SLinus Torvalds laarr[i].extLength -= 698*1da177e4SLinus Torvalds (numalloc << inode->i_sb->s_blocksize_bits); 699*1da177e4SLinus Torvalds numalloc = 0; 700*1da177e4SLinus Torvalds } 701*1da177e4SLinus Torvalds else 702*1da177e4SLinus Torvalds { 703*1da177e4SLinus Torvalds numalloc -= elen; 704*1da177e4SLinus Torvalds if (*endnum > (i+1)) 705*1da177e4SLinus Torvalds memmove(&laarr[i], &laarr[i+1], 706*1da177e4SLinus Torvalds sizeof(long_ad) * (*endnum - (i+1))); 707*1da177e4SLinus Torvalds i --; 708*1da177e4SLinus Torvalds (*endnum) --; 709*1da177e4SLinus Torvalds } 710*1da177e4SLinus Torvalds } 711*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits; 712*1da177e4SLinus Torvalds } 713*1da177e4SLinus Torvalds } 714*1da177e4SLinus Torvalds } 715*1da177e4SLinus Torvalds 716*1da177e4SLinus Torvalds static void udf_merge_extents(struct inode *inode, 717*1da177e4SLinus Torvalds kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) 718*1da177e4SLinus Torvalds { 719*1da177e4SLinus Torvalds int i; 720*1da177e4SLinus Torvalds 721*1da177e4SLinus Torvalds for (i=0; i<(*endnum-1); i++) 722*1da177e4SLinus Torvalds { 723*1da177e4SLinus Torvalds if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30)) 724*1da177e4SLinus Torvalds { 725*1da177e4SLinus Torvalds if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) || 726*1da177e4SLinus Torvalds ((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) == 727*1da177e4SLinus Torvalds (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 728*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))) 729*1da177e4SLinus Torvalds { 730*1da177e4SLinus Torvalds if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 731*1da177e4SLinus Torvalds (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) + 732*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) 733*1da177e4SLinus Torvalds { 734*1da177e4SLinus Torvalds laarr[i+1].extLength = (laarr[i+1].extLength - 735*1da177e4SLinus Torvalds (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 736*1da177e4SLinus Torvalds UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); 737*1da177e4SLinus Torvalds laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + 738*1da177e4SLinus Torvalds (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; 739*1da177e4SLinus Torvalds laarr[i+1].extLocation.logicalBlockNum = 740*1da177e4SLinus Torvalds laarr[i].extLocation.logicalBlockNum + 741*1da177e4SLinus Torvalds ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >> 742*1da177e4SLinus Torvalds inode->i_sb->s_blocksize_bits); 743*1da177e4SLinus Torvalds } 744*1da177e4SLinus Torvalds else 745*1da177e4SLinus Torvalds { 746*1da177e4SLinus Torvalds laarr[i].extLength = laarr[i+1].extLength + 747*1da177e4SLinus Torvalds (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 748*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1)); 749*1da177e4SLinus Torvalds if (*endnum > (i+2)) 750*1da177e4SLinus Torvalds memmove(&laarr[i+1], &laarr[i+2], 751*1da177e4SLinus Torvalds sizeof(long_ad) * (*endnum - (i+2))); 752*1da177e4SLinus Torvalds i --; 753*1da177e4SLinus Torvalds (*endnum) --; 754*1da177e4SLinus Torvalds } 755*1da177e4SLinus Torvalds } 756*1da177e4SLinus Torvalds } 757*1da177e4SLinus Torvalds else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) && 758*1da177e4SLinus Torvalds ((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) 759*1da177e4SLinus Torvalds { 760*1da177e4SLinus Torvalds udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0, 761*1da177e4SLinus Torvalds ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 762*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); 763*1da177e4SLinus Torvalds laarr[i].extLocation.logicalBlockNum = 0; 764*1da177e4SLinus Torvalds laarr[i].extLocation.partitionReferenceNum = 0; 765*1da177e4SLinus Torvalds 766*1da177e4SLinus Torvalds if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 767*1da177e4SLinus Torvalds (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) + 768*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) 769*1da177e4SLinus Torvalds { 770*1da177e4SLinus Torvalds laarr[i+1].extLength = (laarr[i+1].extLength - 771*1da177e4SLinus Torvalds (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 772*1da177e4SLinus Torvalds UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); 773*1da177e4SLinus Torvalds laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + 774*1da177e4SLinus Torvalds (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; 775*1da177e4SLinus Torvalds } 776*1da177e4SLinus Torvalds else 777*1da177e4SLinus Torvalds { 778*1da177e4SLinus Torvalds laarr[i].extLength = laarr[i+1].extLength + 779*1da177e4SLinus Torvalds (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 780*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1)); 781*1da177e4SLinus Torvalds if (*endnum > (i+2)) 782*1da177e4SLinus Torvalds memmove(&laarr[i+1], &laarr[i+2], 783*1da177e4SLinus Torvalds sizeof(long_ad) * (*endnum - (i+2))); 784*1da177e4SLinus Torvalds i --; 785*1da177e4SLinus Torvalds (*endnum) --; 786*1da177e4SLinus Torvalds } 787*1da177e4SLinus Torvalds } 788*1da177e4SLinus Torvalds else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) 789*1da177e4SLinus Torvalds { 790*1da177e4SLinus Torvalds udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0, 791*1da177e4SLinus Torvalds ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + 792*1da177e4SLinus Torvalds inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); 793*1da177e4SLinus Torvalds laarr[i].extLocation.logicalBlockNum = 0; 794*1da177e4SLinus Torvalds laarr[i].extLocation.partitionReferenceNum = 0; 795*1da177e4SLinus Torvalds laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) | 796*1da177e4SLinus Torvalds EXT_NOT_RECORDED_NOT_ALLOCATED; 797*1da177e4SLinus Torvalds } 798*1da177e4SLinus Torvalds } 799*1da177e4SLinus Torvalds } 800*1da177e4SLinus Torvalds 801*1da177e4SLinus Torvalds static void udf_update_extents(struct inode *inode, 802*1da177e4SLinus Torvalds kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, 803*1da177e4SLinus Torvalds kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) 804*1da177e4SLinus Torvalds { 805*1da177e4SLinus Torvalds int start = 0, i; 806*1da177e4SLinus Torvalds kernel_lb_addr tmploc; 807*1da177e4SLinus Torvalds uint32_t tmplen; 808*1da177e4SLinus Torvalds 809*1da177e4SLinus Torvalds if (startnum > endnum) 810*1da177e4SLinus Torvalds { 811*1da177e4SLinus Torvalds for (i=0; i<(startnum-endnum); i++) 812*1da177e4SLinus Torvalds { 813*1da177e4SLinus Torvalds udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, 814*1da177e4SLinus Torvalds laarr[i].extLength, *pbh); 815*1da177e4SLinus Torvalds } 816*1da177e4SLinus Torvalds } 817*1da177e4SLinus Torvalds else if (startnum < endnum) 818*1da177e4SLinus Torvalds { 819*1da177e4SLinus Torvalds for (i=0; i<(endnum-startnum); i++) 820*1da177e4SLinus Torvalds { 821*1da177e4SLinus Torvalds udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, 822*1da177e4SLinus Torvalds laarr[i].extLength, *pbh); 823*1da177e4SLinus Torvalds udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, 824*1da177e4SLinus Torvalds &laarr[i].extLength, pbh, 1); 825*1da177e4SLinus Torvalds start ++; 826*1da177e4SLinus Torvalds } 827*1da177e4SLinus Torvalds } 828*1da177e4SLinus Torvalds 829*1da177e4SLinus Torvalds for (i=start; i<endnum; i++) 830*1da177e4SLinus Torvalds { 831*1da177e4SLinus Torvalds udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); 832*1da177e4SLinus Torvalds udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, 833*1da177e4SLinus Torvalds laarr[i].extLength, *pbh, 1); 834*1da177e4SLinus Torvalds } 835*1da177e4SLinus Torvalds } 836*1da177e4SLinus Torvalds 837*1da177e4SLinus Torvalds struct buffer_head * udf_bread(struct inode * inode, int block, 838*1da177e4SLinus Torvalds int create, int * err) 839*1da177e4SLinus Torvalds { 840*1da177e4SLinus Torvalds struct buffer_head * bh = NULL; 841*1da177e4SLinus Torvalds 842*1da177e4SLinus Torvalds bh = udf_getblk(inode, block, create, err); 843*1da177e4SLinus Torvalds if (!bh) 844*1da177e4SLinus Torvalds return NULL; 845*1da177e4SLinus Torvalds 846*1da177e4SLinus Torvalds if (buffer_uptodate(bh)) 847*1da177e4SLinus Torvalds return bh; 848*1da177e4SLinus Torvalds ll_rw_block(READ, 1, &bh); 849*1da177e4SLinus Torvalds wait_on_buffer(bh); 850*1da177e4SLinus Torvalds if (buffer_uptodate(bh)) 851*1da177e4SLinus Torvalds return bh; 852*1da177e4SLinus Torvalds brelse(bh); 853*1da177e4SLinus Torvalds *err = -EIO; 854*1da177e4SLinus Torvalds return NULL; 855*1da177e4SLinus Torvalds } 856*1da177e4SLinus Torvalds 857*1da177e4SLinus Torvalds void udf_truncate(struct inode * inode) 858*1da177e4SLinus Torvalds { 859*1da177e4SLinus Torvalds int offset; 860*1da177e4SLinus Torvalds int err; 861*1da177e4SLinus Torvalds 862*1da177e4SLinus Torvalds if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 863*1da177e4SLinus Torvalds S_ISLNK(inode->i_mode))) 864*1da177e4SLinus Torvalds return; 865*1da177e4SLinus Torvalds if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 866*1da177e4SLinus Torvalds return; 867*1da177e4SLinus Torvalds 868*1da177e4SLinus Torvalds lock_kernel(); 869*1da177e4SLinus Torvalds if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 870*1da177e4SLinus Torvalds { 871*1da177e4SLinus Torvalds if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + 872*1da177e4SLinus Torvalds inode->i_size)) 873*1da177e4SLinus Torvalds { 874*1da177e4SLinus Torvalds udf_expand_file_adinicb(inode, inode->i_size, &err); 875*1da177e4SLinus Torvalds if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 876*1da177e4SLinus Torvalds { 877*1da177e4SLinus Torvalds inode->i_size = UDF_I_LENALLOC(inode); 878*1da177e4SLinus Torvalds unlock_kernel(); 879*1da177e4SLinus Torvalds return; 880*1da177e4SLinus Torvalds } 881*1da177e4SLinus Torvalds else 882*1da177e4SLinus Torvalds udf_truncate_extents(inode); 883*1da177e4SLinus Torvalds } 884*1da177e4SLinus Torvalds else 885*1da177e4SLinus Torvalds { 886*1da177e4SLinus Torvalds offset = inode->i_size & (inode->i_sb->s_blocksize - 1); 887*1da177e4SLinus Torvalds memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode)); 888*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = inode->i_size; 889*1da177e4SLinus Torvalds } 890*1da177e4SLinus Torvalds } 891*1da177e4SLinus Torvalds else 892*1da177e4SLinus Torvalds { 893*1da177e4SLinus Torvalds block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block); 894*1da177e4SLinus Torvalds udf_truncate_extents(inode); 895*1da177e4SLinus Torvalds } 896*1da177e4SLinus Torvalds 897*1da177e4SLinus Torvalds inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); 898*1da177e4SLinus Torvalds if (IS_SYNC(inode)) 899*1da177e4SLinus Torvalds udf_sync_inode (inode); 900*1da177e4SLinus Torvalds else 901*1da177e4SLinus Torvalds mark_inode_dirty(inode); 902*1da177e4SLinus Torvalds unlock_kernel(); 903*1da177e4SLinus Torvalds } 904*1da177e4SLinus Torvalds 905*1da177e4SLinus Torvalds static void 906*1da177e4SLinus Torvalds __udf_read_inode(struct inode *inode) 907*1da177e4SLinus Torvalds { 908*1da177e4SLinus Torvalds struct buffer_head *bh = NULL; 909*1da177e4SLinus Torvalds struct fileEntry *fe; 910*1da177e4SLinus Torvalds uint16_t ident; 911*1da177e4SLinus Torvalds 912*1da177e4SLinus Torvalds /* 913*1da177e4SLinus Torvalds * Set defaults, but the inode is still incomplete! 914*1da177e4SLinus Torvalds * Note: get_new_inode() sets the following on a new inode: 915*1da177e4SLinus Torvalds * i_sb = sb 916*1da177e4SLinus Torvalds * i_no = ino 917*1da177e4SLinus Torvalds * i_flags = sb->s_flags 918*1da177e4SLinus Torvalds * i_state = 0 919*1da177e4SLinus Torvalds * clean_inode(): zero fills and sets 920*1da177e4SLinus Torvalds * i_count = 1 921*1da177e4SLinus Torvalds * i_nlink = 1 922*1da177e4SLinus Torvalds * i_op = NULL; 923*1da177e4SLinus Torvalds */ 924*1da177e4SLinus Torvalds inode->i_blksize = PAGE_SIZE; 925*1da177e4SLinus Torvalds 926*1da177e4SLinus Torvalds bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident); 927*1da177e4SLinus Torvalds 928*1da177e4SLinus Torvalds if (!bh) 929*1da177e4SLinus Torvalds { 930*1da177e4SLinus Torvalds printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n", 931*1da177e4SLinus Torvalds inode->i_ino); 932*1da177e4SLinus Torvalds make_bad_inode(inode); 933*1da177e4SLinus Torvalds return; 934*1da177e4SLinus Torvalds } 935*1da177e4SLinus Torvalds 936*1da177e4SLinus Torvalds if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && 937*1da177e4SLinus Torvalds ident != TAG_IDENT_USE) 938*1da177e4SLinus Torvalds { 939*1da177e4SLinus Torvalds printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", 940*1da177e4SLinus Torvalds inode->i_ino, ident); 941*1da177e4SLinus Torvalds udf_release_data(bh); 942*1da177e4SLinus Torvalds make_bad_inode(inode); 943*1da177e4SLinus Torvalds return; 944*1da177e4SLinus Torvalds } 945*1da177e4SLinus Torvalds 946*1da177e4SLinus Torvalds fe = (struct fileEntry *)bh->b_data; 947*1da177e4SLinus Torvalds 948*1da177e4SLinus Torvalds if (le16_to_cpu(fe->icbTag.strategyType) == 4096) 949*1da177e4SLinus Torvalds { 950*1da177e4SLinus Torvalds struct buffer_head *ibh = NULL, *nbh = NULL; 951*1da177e4SLinus Torvalds struct indirectEntry *ie; 952*1da177e4SLinus Torvalds 953*1da177e4SLinus Torvalds ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident); 954*1da177e4SLinus Torvalds if (ident == TAG_IDENT_IE) 955*1da177e4SLinus Torvalds { 956*1da177e4SLinus Torvalds if (ibh) 957*1da177e4SLinus Torvalds { 958*1da177e4SLinus Torvalds kernel_lb_addr loc; 959*1da177e4SLinus Torvalds ie = (struct indirectEntry *)ibh->b_data; 960*1da177e4SLinus Torvalds 961*1da177e4SLinus Torvalds loc = lelb_to_cpu(ie->indirectICB.extLocation); 962*1da177e4SLinus Torvalds 963*1da177e4SLinus Torvalds if (ie->indirectICB.extLength && 964*1da177e4SLinus Torvalds (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident))) 965*1da177e4SLinus Torvalds { 966*1da177e4SLinus Torvalds if (ident == TAG_IDENT_FE || 967*1da177e4SLinus Torvalds ident == TAG_IDENT_EFE) 968*1da177e4SLinus Torvalds { 969*1da177e4SLinus Torvalds memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); 970*1da177e4SLinus Torvalds udf_release_data(bh); 971*1da177e4SLinus Torvalds udf_release_data(ibh); 972*1da177e4SLinus Torvalds udf_release_data(nbh); 973*1da177e4SLinus Torvalds __udf_read_inode(inode); 974*1da177e4SLinus Torvalds return; 975*1da177e4SLinus Torvalds } 976*1da177e4SLinus Torvalds else 977*1da177e4SLinus Torvalds { 978*1da177e4SLinus Torvalds udf_release_data(nbh); 979*1da177e4SLinus Torvalds udf_release_data(ibh); 980*1da177e4SLinus Torvalds } 981*1da177e4SLinus Torvalds } 982*1da177e4SLinus Torvalds else 983*1da177e4SLinus Torvalds udf_release_data(ibh); 984*1da177e4SLinus Torvalds } 985*1da177e4SLinus Torvalds } 986*1da177e4SLinus Torvalds else 987*1da177e4SLinus Torvalds udf_release_data(ibh); 988*1da177e4SLinus Torvalds } 989*1da177e4SLinus Torvalds else if (le16_to_cpu(fe->icbTag.strategyType) != 4) 990*1da177e4SLinus Torvalds { 991*1da177e4SLinus Torvalds printk(KERN_ERR "udf: unsupported strategy type: %d\n", 992*1da177e4SLinus Torvalds le16_to_cpu(fe->icbTag.strategyType)); 993*1da177e4SLinus Torvalds udf_release_data(bh); 994*1da177e4SLinus Torvalds make_bad_inode(inode); 995*1da177e4SLinus Torvalds return; 996*1da177e4SLinus Torvalds } 997*1da177e4SLinus Torvalds udf_fill_inode(inode, bh); 998*1da177e4SLinus Torvalds udf_release_data(bh); 999*1da177e4SLinus Torvalds } 1000*1da177e4SLinus Torvalds 1001*1da177e4SLinus Torvalds static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) 1002*1da177e4SLinus Torvalds { 1003*1da177e4SLinus Torvalds struct fileEntry *fe; 1004*1da177e4SLinus Torvalds struct extendedFileEntry *efe; 1005*1da177e4SLinus Torvalds time_t convtime; 1006*1da177e4SLinus Torvalds long convtime_usec; 1007*1da177e4SLinus Torvalds int offset; 1008*1da177e4SLinus Torvalds 1009*1da177e4SLinus Torvalds fe = (struct fileEntry *)bh->b_data; 1010*1da177e4SLinus Torvalds efe = (struct extendedFileEntry *)bh->b_data; 1011*1da177e4SLinus Torvalds 1012*1da177e4SLinus Torvalds if (le16_to_cpu(fe->icbTag.strategyType) == 4) 1013*1da177e4SLinus Torvalds UDF_I_STRAT4096(inode) = 0; 1014*1da177e4SLinus Torvalds else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */ 1015*1da177e4SLinus Torvalds UDF_I_STRAT4096(inode) = 1; 1016*1da177e4SLinus Torvalds 1017*1da177e4SLinus Torvalds UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK; 1018*1da177e4SLinus Torvalds UDF_I_UNIQUE(inode) = 0; 1019*1da177e4SLinus Torvalds UDF_I_LENEATTR(inode) = 0; 1020*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) = 0; 1021*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = 0; 1022*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; 1023*1da177e4SLinus Torvalds UDF_I_NEXT_ALLOC_GOAL(inode) = 0; 1024*1da177e4SLinus Torvalds if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE) 1025*1da177e4SLinus Torvalds { 1026*1da177e4SLinus Torvalds UDF_I_EFE(inode) = 1; 1027*1da177e4SLinus Torvalds UDF_I_USE(inode) = 0; 1028*1da177e4SLinus Torvalds UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL); 1029*1da177e4SLinus Torvalds memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); 1030*1da177e4SLinus Torvalds } 1031*1da177e4SLinus Torvalds else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) 1032*1da177e4SLinus Torvalds { 1033*1da177e4SLinus Torvalds UDF_I_EFE(inode) = 0; 1034*1da177e4SLinus Torvalds UDF_I_USE(inode) = 0; 1035*1da177e4SLinus Torvalds UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL); 1036*1da177e4SLinus Torvalds memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry)); 1037*1da177e4SLinus Torvalds } 1038*1da177e4SLinus Torvalds else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) 1039*1da177e4SLinus Torvalds { 1040*1da177e4SLinus Torvalds UDF_I_EFE(inode) = 0; 1041*1da177e4SLinus Torvalds UDF_I_USE(inode) = 1; 1042*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = 1043*1da177e4SLinus Torvalds le32_to_cpu( 1044*1da177e4SLinus Torvalds ((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs); 1045*1da177e4SLinus Torvalds UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL); 1046*1da177e4SLinus Torvalds memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); 1047*1da177e4SLinus Torvalds return; 1048*1da177e4SLinus Torvalds } 1049*1da177e4SLinus Torvalds 1050*1da177e4SLinus Torvalds inode->i_uid = le32_to_cpu(fe->uid); 1051*1da177e4SLinus Torvalds if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; 1052*1da177e4SLinus Torvalds 1053*1da177e4SLinus Torvalds inode->i_gid = le32_to_cpu(fe->gid); 1054*1da177e4SLinus Torvalds if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; 1055*1da177e4SLinus Torvalds 1056*1da177e4SLinus Torvalds inode->i_nlink = le16_to_cpu(fe->fileLinkCount); 1057*1da177e4SLinus Torvalds if (!inode->i_nlink) 1058*1da177e4SLinus Torvalds inode->i_nlink = 1; 1059*1da177e4SLinus Torvalds 1060*1da177e4SLinus Torvalds inode->i_size = le64_to_cpu(fe->informationLength); 1061*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) = inode->i_size; 1062*1da177e4SLinus Torvalds 1063*1da177e4SLinus Torvalds inode->i_mode = udf_convert_permissions(fe); 1064*1da177e4SLinus Torvalds inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask; 1065*1da177e4SLinus Torvalds 1066*1da177e4SLinus Torvalds if (UDF_I_EFE(inode) == 0) 1067*1da177e4SLinus Torvalds { 1068*1da177e4SLinus Torvalds inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << 1069*1da177e4SLinus Torvalds (inode->i_sb->s_blocksize_bits - 9); 1070*1da177e4SLinus Torvalds 1071*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1072*1da177e4SLinus Torvalds lets_to_cpu(fe->accessTime)) ) 1073*1da177e4SLinus Torvalds { 1074*1da177e4SLinus Torvalds inode->i_atime.tv_sec = convtime; 1075*1da177e4SLinus Torvalds inode->i_atime.tv_nsec = convtime_usec * 1000; 1076*1da177e4SLinus Torvalds } 1077*1da177e4SLinus Torvalds else 1078*1da177e4SLinus Torvalds { 1079*1da177e4SLinus Torvalds inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb); 1080*1da177e4SLinus Torvalds } 1081*1da177e4SLinus Torvalds 1082*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1083*1da177e4SLinus Torvalds lets_to_cpu(fe->modificationTime)) ) 1084*1da177e4SLinus Torvalds { 1085*1da177e4SLinus Torvalds inode->i_mtime.tv_sec = convtime; 1086*1da177e4SLinus Torvalds inode->i_mtime.tv_nsec = convtime_usec * 1000; 1087*1da177e4SLinus Torvalds } 1088*1da177e4SLinus Torvalds else 1089*1da177e4SLinus Torvalds { 1090*1da177e4SLinus Torvalds inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb); 1091*1da177e4SLinus Torvalds } 1092*1da177e4SLinus Torvalds 1093*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1094*1da177e4SLinus Torvalds lets_to_cpu(fe->attrTime)) ) 1095*1da177e4SLinus Torvalds { 1096*1da177e4SLinus Torvalds inode->i_ctime.tv_sec = convtime; 1097*1da177e4SLinus Torvalds inode->i_ctime.tv_nsec = convtime_usec * 1000; 1098*1da177e4SLinus Torvalds } 1099*1da177e4SLinus Torvalds else 1100*1da177e4SLinus Torvalds { 1101*1da177e4SLinus Torvalds inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); 1102*1da177e4SLinus Torvalds } 1103*1da177e4SLinus Torvalds 1104*1da177e4SLinus Torvalds UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID); 1105*1da177e4SLinus Torvalds UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr); 1106*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs); 1107*1da177e4SLinus Torvalds offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode); 1108*1da177e4SLinus Torvalds } 1109*1da177e4SLinus Torvalds else 1110*1da177e4SLinus Torvalds { 1111*1da177e4SLinus Torvalds inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 1112*1da177e4SLinus Torvalds (inode->i_sb->s_blocksize_bits - 9); 1113*1da177e4SLinus Torvalds 1114*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1115*1da177e4SLinus Torvalds lets_to_cpu(efe->accessTime)) ) 1116*1da177e4SLinus Torvalds { 1117*1da177e4SLinus Torvalds inode->i_atime.tv_sec = convtime; 1118*1da177e4SLinus Torvalds inode->i_atime.tv_nsec = convtime_usec * 1000; 1119*1da177e4SLinus Torvalds } 1120*1da177e4SLinus Torvalds else 1121*1da177e4SLinus Torvalds { 1122*1da177e4SLinus Torvalds inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb); 1123*1da177e4SLinus Torvalds } 1124*1da177e4SLinus Torvalds 1125*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1126*1da177e4SLinus Torvalds lets_to_cpu(efe->modificationTime)) ) 1127*1da177e4SLinus Torvalds { 1128*1da177e4SLinus Torvalds inode->i_mtime.tv_sec = convtime; 1129*1da177e4SLinus Torvalds inode->i_mtime.tv_nsec = convtime_usec * 1000; 1130*1da177e4SLinus Torvalds } 1131*1da177e4SLinus Torvalds else 1132*1da177e4SLinus Torvalds { 1133*1da177e4SLinus Torvalds inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb); 1134*1da177e4SLinus Torvalds } 1135*1da177e4SLinus Torvalds 1136*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1137*1da177e4SLinus Torvalds lets_to_cpu(efe->createTime)) ) 1138*1da177e4SLinus Torvalds { 1139*1da177e4SLinus Torvalds UDF_I_CRTIME(inode).tv_sec = convtime; 1140*1da177e4SLinus Torvalds UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000; 1141*1da177e4SLinus Torvalds } 1142*1da177e4SLinus Torvalds else 1143*1da177e4SLinus Torvalds { 1144*1da177e4SLinus Torvalds UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb); 1145*1da177e4SLinus Torvalds } 1146*1da177e4SLinus Torvalds 1147*1da177e4SLinus Torvalds if ( udf_stamp_to_time(&convtime, &convtime_usec, 1148*1da177e4SLinus Torvalds lets_to_cpu(efe->attrTime)) ) 1149*1da177e4SLinus Torvalds { 1150*1da177e4SLinus Torvalds inode->i_ctime.tv_sec = convtime; 1151*1da177e4SLinus Torvalds inode->i_ctime.tv_nsec = convtime_usec * 1000; 1152*1da177e4SLinus Torvalds } 1153*1da177e4SLinus Torvalds else 1154*1da177e4SLinus Torvalds { 1155*1da177e4SLinus Torvalds inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); 1156*1da177e4SLinus Torvalds } 1157*1da177e4SLinus Torvalds 1158*1da177e4SLinus Torvalds UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID); 1159*1da177e4SLinus Torvalds UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr); 1160*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs); 1161*1da177e4SLinus Torvalds offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode); 1162*1da177e4SLinus Torvalds } 1163*1da177e4SLinus Torvalds 1164*1da177e4SLinus Torvalds switch (fe->icbTag.fileType) 1165*1da177e4SLinus Torvalds { 1166*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_DIRECTORY: 1167*1da177e4SLinus Torvalds { 1168*1da177e4SLinus Torvalds inode->i_op = &udf_dir_inode_operations; 1169*1da177e4SLinus Torvalds inode->i_fop = &udf_dir_operations; 1170*1da177e4SLinus Torvalds inode->i_mode |= S_IFDIR; 1171*1da177e4SLinus Torvalds inode->i_nlink ++; 1172*1da177e4SLinus Torvalds break; 1173*1da177e4SLinus Torvalds } 1174*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_REALTIME: 1175*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_REGULAR: 1176*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_UNDEF: 1177*1da177e4SLinus Torvalds { 1178*1da177e4SLinus Torvalds if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 1179*1da177e4SLinus Torvalds inode->i_data.a_ops = &udf_adinicb_aops; 1180*1da177e4SLinus Torvalds else 1181*1da177e4SLinus Torvalds inode->i_data.a_ops = &udf_aops; 1182*1da177e4SLinus Torvalds inode->i_op = &udf_file_inode_operations; 1183*1da177e4SLinus Torvalds inode->i_fop = &udf_file_operations; 1184*1da177e4SLinus Torvalds inode->i_mode |= S_IFREG; 1185*1da177e4SLinus Torvalds break; 1186*1da177e4SLinus Torvalds } 1187*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_BLOCK: 1188*1da177e4SLinus Torvalds { 1189*1da177e4SLinus Torvalds inode->i_mode |= S_IFBLK; 1190*1da177e4SLinus Torvalds break; 1191*1da177e4SLinus Torvalds } 1192*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_CHAR: 1193*1da177e4SLinus Torvalds { 1194*1da177e4SLinus Torvalds inode->i_mode |= S_IFCHR; 1195*1da177e4SLinus Torvalds break; 1196*1da177e4SLinus Torvalds } 1197*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_FIFO: 1198*1da177e4SLinus Torvalds { 1199*1da177e4SLinus Torvalds init_special_inode(inode, inode->i_mode | S_IFIFO, 0); 1200*1da177e4SLinus Torvalds break; 1201*1da177e4SLinus Torvalds } 1202*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_SOCKET: 1203*1da177e4SLinus Torvalds { 1204*1da177e4SLinus Torvalds init_special_inode(inode, inode->i_mode | S_IFSOCK, 0); 1205*1da177e4SLinus Torvalds break; 1206*1da177e4SLinus Torvalds } 1207*1da177e4SLinus Torvalds case ICBTAG_FILE_TYPE_SYMLINK: 1208*1da177e4SLinus Torvalds { 1209*1da177e4SLinus Torvalds inode->i_data.a_ops = &udf_symlink_aops; 1210*1da177e4SLinus Torvalds inode->i_op = &page_symlink_inode_operations; 1211*1da177e4SLinus Torvalds inode->i_mode = S_IFLNK|S_IRWXUGO; 1212*1da177e4SLinus Torvalds break; 1213*1da177e4SLinus Torvalds } 1214*1da177e4SLinus Torvalds default: 1215*1da177e4SLinus Torvalds { 1216*1da177e4SLinus Torvalds printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n", 1217*1da177e4SLinus Torvalds inode->i_ino, fe->icbTag.fileType); 1218*1da177e4SLinus Torvalds make_bad_inode(inode); 1219*1da177e4SLinus Torvalds return; 1220*1da177e4SLinus Torvalds } 1221*1da177e4SLinus Torvalds } 1222*1da177e4SLinus Torvalds if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 1223*1da177e4SLinus Torvalds { 1224*1da177e4SLinus Torvalds struct deviceSpec *dsea = 1225*1da177e4SLinus Torvalds (struct deviceSpec *) 1226*1da177e4SLinus Torvalds udf_get_extendedattr(inode, 12, 1); 1227*1da177e4SLinus Torvalds 1228*1da177e4SLinus Torvalds if (dsea) 1229*1da177e4SLinus Torvalds { 1230*1da177e4SLinus Torvalds init_special_inode(inode, inode->i_mode, MKDEV( 1231*1da177e4SLinus Torvalds le32_to_cpu(dsea->majorDeviceIdent), 1232*1da177e4SLinus Torvalds le32_to_cpu(dsea->minorDeviceIdent))); 1233*1da177e4SLinus Torvalds /* Developer ID ??? */ 1234*1da177e4SLinus Torvalds } 1235*1da177e4SLinus Torvalds else 1236*1da177e4SLinus Torvalds { 1237*1da177e4SLinus Torvalds make_bad_inode(inode); 1238*1da177e4SLinus Torvalds } 1239*1da177e4SLinus Torvalds } 1240*1da177e4SLinus Torvalds } 1241*1da177e4SLinus Torvalds 1242*1da177e4SLinus Torvalds static mode_t 1243*1da177e4SLinus Torvalds udf_convert_permissions(struct fileEntry *fe) 1244*1da177e4SLinus Torvalds { 1245*1da177e4SLinus Torvalds mode_t mode; 1246*1da177e4SLinus Torvalds uint32_t permissions; 1247*1da177e4SLinus Torvalds uint32_t flags; 1248*1da177e4SLinus Torvalds 1249*1da177e4SLinus Torvalds permissions = le32_to_cpu(fe->permissions); 1250*1da177e4SLinus Torvalds flags = le16_to_cpu(fe->icbTag.flags); 1251*1da177e4SLinus Torvalds 1252*1da177e4SLinus Torvalds mode = (( permissions ) & S_IRWXO) | 1253*1da177e4SLinus Torvalds (( permissions >> 2 ) & S_IRWXG) | 1254*1da177e4SLinus Torvalds (( permissions >> 4 ) & S_IRWXU) | 1255*1da177e4SLinus Torvalds (( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) | 1256*1da177e4SLinus Torvalds (( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) | 1257*1da177e4SLinus Torvalds (( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0); 1258*1da177e4SLinus Torvalds 1259*1da177e4SLinus Torvalds return mode; 1260*1da177e4SLinus Torvalds } 1261*1da177e4SLinus Torvalds 1262*1da177e4SLinus Torvalds /* 1263*1da177e4SLinus Torvalds * udf_write_inode 1264*1da177e4SLinus Torvalds * 1265*1da177e4SLinus Torvalds * PURPOSE 1266*1da177e4SLinus Torvalds * Write out the specified inode. 1267*1da177e4SLinus Torvalds * 1268*1da177e4SLinus Torvalds * DESCRIPTION 1269*1da177e4SLinus Torvalds * This routine is called whenever an inode is synced. 1270*1da177e4SLinus Torvalds * Currently this routine is just a placeholder. 1271*1da177e4SLinus Torvalds * 1272*1da177e4SLinus Torvalds * HISTORY 1273*1da177e4SLinus Torvalds * July 1, 1997 - Andrew E. Mileski 1274*1da177e4SLinus Torvalds * Written, tested, and released. 1275*1da177e4SLinus Torvalds */ 1276*1da177e4SLinus Torvalds 1277*1da177e4SLinus Torvalds int udf_write_inode(struct inode * inode, int sync) 1278*1da177e4SLinus Torvalds { 1279*1da177e4SLinus Torvalds int ret; 1280*1da177e4SLinus Torvalds lock_kernel(); 1281*1da177e4SLinus Torvalds ret = udf_update_inode(inode, sync); 1282*1da177e4SLinus Torvalds unlock_kernel(); 1283*1da177e4SLinus Torvalds return ret; 1284*1da177e4SLinus Torvalds } 1285*1da177e4SLinus Torvalds 1286*1da177e4SLinus Torvalds int udf_sync_inode(struct inode * inode) 1287*1da177e4SLinus Torvalds { 1288*1da177e4SLinus Torvalds return udf_update_inode(inode, 1); 1289*1da177e4SLinus Torvalds } 1290*1da177e4SLinus Torvalds 1291*1da177e4SLinus Torvalds static int 1292*1da177e4SLinus Torvalds udf_update_inode(struct inode *inode, int do_sync) 1293*1da177e4SLinus Torvalds { 1294*1da177e4SLinus Torvalds struct buffer_head *bh = NULL; 1295*1da177e4SLinus Torvalds struct fileEntry *fe; 1296*1da177e4SLinus Torvalds struct extendedFileEntry *efe; 1297*1da177e4SLinus Torvalds uint32_t udfperms; 1298*1da177e4SLinus Torvalds uint16_t icbflags; 1299*1da177e4SLinus Torvalds uint16_t crclen; 1300*1da177e4SLinus Torvalds int i; 1301*1da177e4SLinus Torvalds kernel_timestamp cpu_time; 1302*1da177e4SLinus Torvalds int err = 0; 1303*1da177e4SLinus Torvalds 1304*1da177e4SLinus Torvalds bh = udf_tread(inode->i_sb, 1305*1da177e4SLinus Torvalds udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); 1306*1da177e4SLinus Torvalds 1307*1da177e4SLinus Torvalds if (!bh) 1308*1da177e4SLinus Torvalds { 1309*1da177e4SLinus Torvalds udf_debug("bread failure\n"); 1310*1da177e4SLinus Torvalds return -EIO; 1311*1da177e4SLinus Torvalds } 1312*1da177e4SLinus Torvalds 1313*1da177e4SLinus Torvalds memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); 1314*1da177e4SLinus Torvalds 1315*1da177e4SLinus Torvalds fe = (struct fileEntry *)bh->b_data; 1316*1da177e4SLinus Torvalds efe = (struct extendedFileEntry *)bh->b_data; 1317*1da177e4SLinus Torvalds 1318*1da177e4SLinus Torvalds if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) 1319*1da177e4SLinus Torvalds { 1320*1da177e4SLinus Torvalds struct unallocSpaceEntry *use = 1321*1da177e4SLinus Torvalds (struct unallocSpaceEntry *)bh->b_data; 1322*1da177e4SLinus Torvalds 1323*1da177e4SLinus Torvalds use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); 1324*1da177e4SLinus Torvalds memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); 1325*1da177e4SLinus Torvalds crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) - 1326*1da177e4SLinus Torvalds sizeof(tag); 1327*1da177e4SLinus Torvalds use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); 1328*1da177e4SLinus Torvalds use->descTag.descCRCLength = cpu_to_le16(crclen); 1329*1da177e4SLinus Torvalds use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0)); 1330*1da177e4SLinus Torvalds 1331*1da177e4SLinus Torvalds use->descTag.tagChecksum = 0; 1332*1da177e4SLinus Torvalds for (i=0; i<16; i++) 1333*1da177e4SLinus Torvalds if (i != 4) 1334*1da177e4SLinus Torvalds use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; 1335*1da177e4SLinus Torvalds 1336*1da177e4SLinus Torvalds mark_buffer_dirty(bh); 1337*1da177e4SLinus Torvalds udf_release_data(bh); 1338*1da177e4SLinus Torvalds return err; 1339*1da177e4SLinus Torvalds } 1340*1da177e4SLinus Torvalds 1341*1da177e4SLinus Torvalds if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) 1342*1da177e4SLinus Torvalds fe->uid = cpu_to_le32(inode->i_uid); 1343*1da177e4SLinus Torvalds 1344*1da177e4SLinus Torvalds if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) 1345*1da177e4SLinus Torvalds fe->gid = cpu_to_le32(inode->i_gid); 1346*1da177e4SLinus Torvalds 1347*1da177e4SLinus Torvalds udfperms = ((inode->i_mode & S_IRWXO) ) | 1348*1da177e4SLinus Torvalds ((inode->i_mode & S_IRWXG) << 2) | 1349*1da177e4SLinus Torvalds ((inode->i_mode & S_IRWXU) << 4); 1350*1da177e4SLinus Torvalds 1351*1da177e4SLinus Torvalds udfperms |= (le32_to_cpu(fe->permissions) & 1352*1da177e4SLinus Torvalds (FE_PERM_O_DELETE | FE_PERM_O_CHATTR | 1353*1da177e4SLinus Torvalds FE_PERM_G_DELETE | FE_PERM_G_CHATTR | 1354*1da177e4SLinus Torvalds FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); 1355*1da177e4SLinus Torvalds fe->permissions = cpu_to_le32(udfperms); 1356*1da177e4SLinus Torvalds 1357*1da177e4SLinus Torvalds if (S_ISDIR(inode->i_mode)) 1358*1da177e4SLinus Torvalds fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); 1359*1da177e4SLinus Torvalds else 1360*1da177e4SLinus Torvalds fe->fileLinkCount = cpu_to_le16(inode->i_nlink); 1361*1da177e4SLinus Torvalds 1362*1da177e4SLinus Torvalds fe->informationLength = cpu_to_le64(inode->i_size); 1363*1da177e4SLinus Torvalds 1364*1da177e4SLinus Torvalds if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 1365*1da177e4SLinus Torvalds { 1366*1da177e4SLinus Torvalds regid *eid; 1367*1da177e4SLinus Torvalds struct deviceSpec *dsea = 1368*1da177e4SLinus Torvalds (struct deviceSpec *) 1369*1da177e4SLinus Torvalds udf_get_extendedattr(inode, 12, 1); 1370*1da177e4SLinus Torvalds 1371*1da177e4SLinus Torvalds if (!dsea) 1372*1da177e4SLinus Torvalds { 1373*1da177e4SLinus Torvalds dsea = (struct deviceSpec *) 1374*1da177e4SLinus Torvalds udf_add_extendedattr(inode, 1375*1da177e4SLinus Torvalds sizeof(struct deviceSpec) + 1376*1da177e4SLinus Torvalds sizeof(regid), 12, 0x3); 1377*1da177e4SLinus Torvalds dsea->attrType = cpu_to_le32(12); 1378*1da177e4SLinus Torvalds dsea->attrSubtype = 1; 1379*1da177e4SLinus Torvalds dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) + 1380*1da177e4SLinus Torvalds sizeof(regid)); 1381*1da177e4SLinus Torvalds dsea->impUseLength = cpu_to_le32(sizeof(regid)); 1382*1da177e4SLinus Torvalds } 1383*1da177e4SLinus Torvalds eid = (regid *)dsea->impUse; 1384*1da177e4SLinus Torvalds memset(eid, 0, sizeof(regid)); 1385*1da177e4SLinus Torvalds strcpy(eid->ident, UDF_ID_DEVELOPER); 1386*1da177e4SLinus Torvalds eid->identSuffix[0] = UDF_OS_CLASS_UNIX; 1387*1da177e4SLinus Torvalds eid->identSuffix[1] = UDF_OS_ID_LINUX; 1388*1da177e4SLinus Torvalds dsea->majorDeviceIdent = cpu_to_le32(imajor(inode)); 1389*1da177e4SLinus Torvalds dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); 1390*1da177e4SLinus Torvalds } 1391*1da177e4SLinus Torvalds 1392*1da177e4SLinus Torvalds if (UDF_I_EFE(inode) == 0) 1393*1da177e4SLinus Torvalds { 1394*1da177e4SLinus Torvalds memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry)); 1395*1da177e4SLinus Torvalds fe->logicalBlocksRecorded = cpu_to_le64( 1396*1da177e4SLinus Torvalds (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> 1397*1da177e4SLinus Torvalds (inode->i_sb->s_blocksize_bits - 9)); 1398*1da177e4SLinus Torvalds 1399*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_atime)) 1400*1da177e4SLinus Torvalds fe->accessTime = cpu_to_lets(cpu_time); 1401*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) 1402*1da177e4SLinus Torvalds fe->modificationTime = cpu_to_lets(cpu_time); 1403*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) 1404*1da177e4SLinus Torvalds fe->attrTime = cpu_to_lets(cpu_time); 1405*1da177e4SLinus Torvalds memset(&(fe->impIdent), 0, sizeof(regid)); 1406*1da177e4SLinus Torvalds strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); 1407*1da177e4SLinus Torvalds fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1408*1da177e4SLinus Torvalds fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1409*1da177e4SLinus Torvalds fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); 1410*1da177e4SLinus Torvalds fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); 1411*1da177e4SLinus Torvalds fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); 1412*1da177e4SLinus Torvalds fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); 1413*1da177e4SLinus Torvalds crclen = sizeof(struct fileEntry); 1414*1da177e4SLinus Torvalds } 1415*1da177e4SLinus Torvalds else 1416*1da177e4SLinus Torvalds { 1417*1da177e4SLinus Torvalds memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); 1418*1da177e4SLinus Torvalds efe->objectSize = cpu_to_le64(inode->i_size); 1419*1da177e4SLinus Torvalds efe->logicalBlocksRecorded = cpu_to_le64( 1420*1da177e4SLinus Torvalds (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> 1421*1da177e4SLinus Torvalds (inode->i_sb->s_blocksize_bits - 9)); 1422*1da177e4SLinus Torvalds 1423*1da177e4SLinus Torvalds if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec || 1424*1da177e4SLinus Torvalds (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec && 1425*1da177e4SLinus Torvalds UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec)) 1426*1da177e4SLinus Torvalds { 1427*1da177e4SLinus Torvalds UDF_I_CRTIME(inode) = inode->i_atime; 1428*1da177e4SLinus Torvalds } 1429*1da177e4SLinus Torvalds if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec || 1430*1da177e4SLinus Torvalds (UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec && 1431*1da177e4SLinus Torvalds UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec)) 1432*1da177e4SLinus Torvalds { 1433*1da177e4SLinus Torvalds UDF_I_CRTIME(inode) = inode->i_mtime; 1434*1da177e4SLinus Torvalds } 1435*1da177e4SLinus Torvalds if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec || 1436*1da177e4SLinus Torvalds (UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec && 1437*1da177e4SLinus Torvalds UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec)) 1438*1da177e4SLinus Torvalds { 1439*1da177e4SLinus Torvalds UDF_I_CRTIME(inode) = inode->i_ctime; 1440*1da177e4SLinus Torvalds } 1441*1da177e4SLinus Torvalds 1442*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_atime)) 1443*1da177e4SLinus Torvalds efe->accessTime = cpu_to_lets(cpu_time); 1444*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) 1445*1da177e4SLinus Torvalds efe->modificationTime = cpu_to_lets(cpu_time); 1446*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode))) 1447*1da177e4SLinus Torvalds efe->createTime = cpu_to_lets(cpu_time); 1448*1da177e4SLinus Torvalds if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) 1449*1da177e4SLinus Torvalds efe->attrTime = cpu_to_lets(cpu_time); 1450*1da177e4SLinus Torvalds 1451*1da177e4SLinus Torvalds memset(&(efe->impIdent), 0, sizeof(regid)); 1452*1da177e4SLinus Torvalds strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); 1453*1da177e4SLinus Torvalds efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1454*1da177e4SLinus Torvalds efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1455*1da177e4SLinus Torvalds efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); 1456*1da177e4SLinus Torvalds efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); 1457*1da177e4SLinus Torvalds efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); 1458*1da177e4SLinus Torvalds efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); 1459*1da177e4SLinus Torvalds crclen = sizeof(struct extendedFileEntry); 1460*1da177e4SLinus Torvalds } 1461*1da177e4SLinus Torvalds if (UDF_I_STRAT4096(inode)) 1462*1da177e4SLinus Torvalds { 1463*1da177e4SLinus Torvalds fe->icbTag.strategyType = cpu_to_le16(4096); 1464*1da177e4SLinus Torvalds fe->icbTag.strategyParameter = cpu_to_le16(1); 1465*1da177e4SLinus Torvalds fe->icbTag.numEntries = cpu_to_le16(2); 1466*1da177e4SLinus Torvalds } 1467*1da177e4SLinus Torvalds else 1468*1da177e4SLinus Torvalds { 1469*1da177e4SLinus Torvalds fe->icbTag.strategyType = cpu_to_le16(4); 1470*1da177e4SLinus Torvalds fe->icbTag.numEntries = cpu_to_le16(1); 1471*1da177e4SLinus Torvalds } 1472*1da177e4SLinus Torvalds 1473*1da177e4SLinus Torvalds if (S_ISDIR(inode->i_mode)) 1474*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY; 1475*1da177e4SLinus Torvalds else if (S_ISREG(inode->i_mode)) 1476*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR; 1477*1da177e4SLinus Torvalds else if (S_ISLNK(inode->i_mode)) 1478*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK; 1479*1da177e4SLinus Torvalds else if (S_ISBLK(inode->i_mode)) 1480*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK; 1481*1da177e4SLinus Torvalds else if (S_ISCHR(inode->i_mode)) 1482*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR; 1483*1da177e4SLinus Torvalds else if (S_ISFIFO(inode->i_mode)) 1484*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO; 1485*1da177e4SLinus Torvalds else if (S_ISSOCK(inode->i_mode)) 1486*1da177e4SLinus Torvalds fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET; 1487*1da177e4SLinus Torvalds 1488*1da177e4SLinus Torvalds icbflags = UDF_I_ALLOCTYPE(inode) | 1489*1da177e4SLinus Torvalds ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) | 1490*1da177e4SLinus Torvalds ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) | 1491*1da177e4SLinus Torvalds ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) | 1492*1da177e4SLinus Torvalds (le16_to_cpu(fe->icbTag.flags) & 1493*1da177e4SLinus Torvalds ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID | 1494*1da177e4SLinus Torvalds ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY)); 1495*1da177e4SLinus Torvalds 1496*1da177e4SLinus Torvalds fe->icbTag.flags = cpu_to_le16(icbflags); 1497*1da177e4SLinus Torvalds if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) 1498*1da177e4SLinus Torvalds fe->descTag.descVersion = cpu_to_le16(3); 1499*1da177e4SLinus Torvalds else 1500*1da177e4SLinus Torvalds fe->descTag.descVersion = cpu_to_le16(2); 1501*1da177e4SLinus Torvalds fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); 1502*1da177e4SLinus Torvalds fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); 1503*1da177e4SLinus Torvalds crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag); 1504*1da177e4SLinus Torvalds fe->descTag.descCRCLength = cpu_to_le16(crclen); 1505*1da177e4SLinus Torvalds fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0)); 1506*1da177e4SLinus Torvalds 1507*1da177e4SLinus Torvalds fe->descTag.tagChecksum = 0; 1508*1da177e4SLinus Torvalds for (i=0; i<16; i++) 1509*1da177e4SLinus Torvalds if (i != 4) 1510*1da177e4SLinus Torvalds fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i]; 1511*1da177e4SLinus Torvalds 1512*1da177e4SLinus Torvalds /* write the data blocks */ 1513*1da177e4SLinus Torvalds mark_buffer_dirty(bh); 1514*1da177e4SLinus Torvalds if (do_sync) 1515*1da177e4SLinus Torvalds { 1516*1da177e4SLinus Torvalds sync_dirty_buffer(bh); 1517*1da177e4SLinus Torvalds if (buffer_req(bh) && !buffer_uptodate(bh)) 1518*1da177e4SLinus Torvalds { 1519*1da177e4SLinus Torvalds printk("IO error syncing udf inode [%s:%08lx]\n", 1520*1da177e4SLinus Torvalds inode->i_sb->s_id, inode->i_ino); 1521*1da177e4SLinus Torvalds err = -EIO; 1522*1da177e4SLinus Torvalds } 1523*1da177e4SLinus Torvalds } 1524*1da177e4SLinus Torvalds udf_release_data(bh); 1525*1da177e4SLinus Torvalds return err; 1526*1da177e4SLinus Torvalds } 1527*1da177e4SLinus Torvalds 1528*1da177e4SLinus Torvalds struct inode * 1529*1da177e4SLinus Torvalds udf_iget(struct super_block *sb, kernel_lb_addr ino) 1530*1da177e4SLinus Torvalds { 1531*1da177e4SLinus Torvalds unsigned long block = udf_get_lb_pblock(sb, ino, 0); 1532*1da177e4SLinus Torvalds struct inode *inode = iget_locked(sb, block); 1533*1da177e4SLinus Torvalds 1534*1da177e4SLinus Torvalds if (!inode) 1535*1da177e4SLinus Torvalds return NULL; 1536*1da177e4SLinus Torvalds 1537*1da177e4SLinus Torvalds if (inode->i_state & I_NEW) { 1538*1da177e4SLinus Torvalds memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr)); 1539*1da177e4SLinus Torvalds __udf_read_inode(inode); 1540*1da177e4SLinus Torvalds unlock_new_inode(inode); 1541*1da177e4SLinus Torvalds } 1542*1da177e4SLinus Torvalds 1543*1da177e4SLinus Torvalds if (is_bad_inode(inode)) 1544*1da177e4SLinus Torvalds goto out_iput; 1545*1da177e4SLinus Torvalds 1546*1da177e4SLinus Torvalds if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) { 1547*1da177e4SLinus Torvalds udf_debug("block=%d, partition=%d out of range\n", 1548*1da177e4SLinus Torvalds ino.logicalBlockNum, ino.partitionReferenceNum); 1549*1da177e4SLinus Torvalds make_bad_inode(inode); 1550*1da177e4SLinus Torvalds goto out_iput; 1551*1da177e4SLinus Torvalds } 1552*1da177e4SLinus Torvalds 1553*1da177e4SLinus Torvalds return inode; 1554*1da177e4SLinus Torvalds 1555*1da177e4SLinus Torvalds out_iput: 1556*1da177e4SLinus Torvalds iput(inode); 1557*1da177e4SLinus Torvalds return NULL; 1558*1da177e4SLinus Torvalds } 1559*1da177e4SLinus Torvalds 1560*1da177e4SLinus Torvalds int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, 1561*1da177e4SLinus Torvalds kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) 1562*1da177e4SLinus Torvalds { 1563*1da177e4SLinus Torvalds int adsize; 1564*1da177e4SLinus Torvalds short_ad *sad = NULL; 1565*1da177e4SLinus Torvalds long_ad *lad = NULL; 1566*1da177e4SLinus Torvalds struct allocExtDesc *aed; 1567*1da177e4SLinus Torvalds int8_t etype; 1568*1da177e4SLinus Torvalds uint8_t *ptr; 1569*1da177e4SLinus Torvalds 1570*1da177e4SLinus Torvalds if (!*bh) 1571*1da177e4SLinus Torvalds ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); 1572*1da177e4SLinus Torvalds else 1573*1da177e4SLinus Torvalds ptr = (*bh)->b_data + *extoffset; 1574*1da177e4SLinus Torvalds 1575*1da177e4SLinus Torvalds if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) 1576*1da177e4SLinus Torvalds adsize = sizeof(short_ad); 1577*1da177e4SLinus Torvalds else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) 1578*1da177e4SLinus Torvalds adsize = sizeof(long_ad); 1579*1da177e4SLinus Torvalds else 1580*1da177e4SLinus Torvalds return -1; 1581*1da177e4SLinus Torvalds 1582*1da177e4SLinus Torvalds if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) 1583*1da177e4SLinus Torvalds { 1584*1da177e4SLinus Torvalds char *sptr, *dptr; 1585*1da177e4SLinus Torvalds struct buffer_head *nbh; 1586*1da177e4SLinus Torvalds int err, loffset; 1587*1da177e4SLinus Torvalds kernel_lb_addr obloc = *bloc; 1588*1da177e4SLinus Torvalds 1589*1da177e4SLinus Torvalds if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, 1590*1da177e4SLinus Torvalds obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) 1591*1da177e4SLinus Torvalds { 1592*1da177e4SLinus Torvalds return -1; 1593*1da177e4SLinus Torvalds } 1594*1da177e4SLinus Torvalds if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, 1595*1da177e4SLinus Torvalds *bloc, 0)))) 1596*1da177e4SLinus Torvalds { 1597*1da177e4SLinus Torvalds return -1; 1598*1da177e4SLinus Torvalds } 1599*1da177e4SLinus Torvalds lock_buffer(nbh); 1600*1da177e4SLinus Torvalds memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); 1601*1da177e4SLinus Torvalds set_buffer_uptodate(nbh); 1602*1da177e4SLinus Torvalds unlock_buffer(nbh); 1603*1da177e4SLinus Torvalds mark_buffer_dirty_inode(nbh, inode); 1604*1da177e4SLinus Torvalds 1605*1da177e4SLinus Torvalds aed = (struct allocExtDesc *)(nbh->b_data); 1606*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) 1607*1da177e4SLinus Torvalds aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); 1608*1da177e4SLinus Torvalds if (*extoffset + adsize > inode->i_sb->s_blocksize) 1609*1da177e4SLinus Torvalds { 1610*1da177e4SLinus Torvalds loffset = *extoffset; 1611*1da177e4SLinus Torvalds aed->lengthAllocDescs = cpu_to_le32(adsize); 1612*1da177e4SLinus Torvalds sptr = ptr - adsize; 1613*1da177e4SLinus Torvalds dptr = nbh->b_data + sizeof(struct allocExtDesc); 1614*1da177e4SLinus Torvalds memcpy(dptr, sptr, adsize); 1615*1da177e4SLinus Torvalds *extoffset = sizeof(struct allocExtDesc) + adsize; 1616*1da177e4SLinus Torvalds } 1617*1da177e4SLinus Torvalds else 1618*1da177e4SLinus Torvalds { 1619*1da177e4SLinus Torvalds loffset = *extoffset + adsize; 1620*1da177e4SLinus Torvalds aed->lengthAllocDescs = cpu_to_le32(0); 1621*1da177e4SLinus Torvalds sptr = ptr; 1622*1da177e4SLinus Torvalds *extoffset = sizeof(struct allocExtDesc); 1623*1da177e4SLinus Torvalds 1624*1da177e4SLinus Torvalds if (*bh) 1625*1da177e4SLinus Torvalds { 1626*1da177e4SLinus Torvalds aed = (struct allocExtDesc *)(*bh)->b_data; 1627*1da177e4SLinus Torvalds aed->lengthAllocDescs = 1628*1da177e4SLinus Torvalds cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); 1629*1da177e4SLinus Torvalds } 1630*1da177e4SLinus Torvalds else 1631*1da177e4SLinus Torvalds { 1632*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) += adsize; 1633*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1634*1da177e4SLinus Torvalds } 1635*1da177e4SLinus Torvalds } 1636*1da177e4SLinus Torvalds if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) 1637*1da177e4SLinus Torvalds udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, 1638*1da177e4SLinus Torvalds bloc->logicalBlockNum, sizeof(tag)); 1639*1da177e4SLinus Torvalds else 1640*1da177e4SLinus Torvalds udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, 1641*1da177e4SLinus Torvalds bloc->logicalBlockNum, sizeof(tag)); 1642*1da177e4SLinus Torvalds switch (UDF_I_ALLOCTYPE(inode)) 1643*1da177e4SLinus Torvalds { 1644*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_SHORT: 1645*1da177e4SLinus Torvalds { 1646*1da177e4SLinus Torvalds sad = (short_ad *)sptr; 1647*1da177e4SLinus Torvalds sad->extLength = cpu_to_le32( 1648*1da177e4SLinus Torvalds EXT_NEXT_EXTENT_ALLOCDECS | 1649*1da177e4SLinus Torvalds inode->i_sb->s_blocksize); 1650*1da177e4SLinus Torvalds sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); 1651*1da177e4SLinus Torvalds break; 1652*1da177e4SLinus Torvalds } 1653*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_LONG: 1654*1da177e4SLinus Torvalds { 1655*1da177e4SLinus Torvalds lad = (long_ad *)sptr; 1656*1da177e4SLinus Torvalds lad->extLength = cpu_to_le32( 1657*1da177e4SLinus Torvalds EXT_NEXT_EXTENT_ALLOCDECS | 1658*1da177e4SLinus Torvalds inode->i_sb->s_blocksize); 1659*1da177e4SLinus Torvalds lad->extLocation = cpu_to_lelb(*bloc); 1660*1da177e4SLinus Torvalds memset(lad->impUse, 0x00, sizeof(lad->impUse)); 1661*1da177e4SLinus Torvalds break; 1662*1da177e4SLinus Torvalds } 1663*1da177e4SLinus Torvalds } 1664*1da177e4SLinus Torvalds if (*bh) 1665*1da177e4SLinus Torvalds { 1666*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 1667*1da177e4SLinus Torvalds udf_update_tag((*bh)->b_data, loffset); 1668*1da177e4SLinus Torvalds else 1669*1da177e4SLinus Torvalds udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); 1670*1da177e4SLinus Torvalds mark_buffer_dirty_inode(*bh, inode); 1671*1da177e4SLinus Torvalds udf_release_data(*bh); 1672*1da177e4SLinus Torvalds } 1673*1da177e4SLinus Torvalds else 1674*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1675*1da177e4SLinus Torvalds *bh = nbh; 1676*1da177e4SLinus Torvalds } 1677*1da177e4SLinus Torvalds 1678*1da177e4SLinus Torvalds etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc); 1679*1da177e4SLinus Torvalds 1680*1da177e4SLinus Torvalds if (!*bh) 1681*1da177e4SLinus Torvalds { 1682*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) += adsize; 1683*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1684*1da177e4SLinus Torvalds } 1685*1da177e4SLinus Torvalds else 1686*1da177e4SLinus Torvalds { 1687*1da177e4SLinus Torvalds aed = (struct allocExtDesc *)(*bh)->b_data; 1688*1da177e4SLinus Torvalds aed->lengthAllocDescs = 1689*1da177e4SLinus Torvalds cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); 1690*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 1691*1da177e4SLinus Torvalds udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); 1692*1da177e4SLinus Torvalds else 1693*1da177e4SLinus Torvalds udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); 1694*1da177e4SLinus Torvalds mark_buffer_dirty_inode(*bh, inode); 1695*1da177e4SLinus Torvalds } 1696*1da177e4SLinus Torvalds 1697*1da177e4SLinus Torvalds return etype; 1698*1da177e4SLinus Torvalds } 1699*1da177e4SLinus Torvalds 1700*1da177e4SLinus Torvalds int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, 1701*1da177e4SLinus Torvalds kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) 1702*1da177e4SLinus Torvalds { 1703*1da177e4SLinus Torvalds int adsize; 1704*1da177e4SLinus Torvalds uint8_t *ptr; 1705*1da177e4SLinus Torvalds 1706*1da177e4SLinus Torvalds if (!bh) 1707*1da177e4SLinus Torvalds ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); 1708*1da177e4SLinus Torvalds else 1709*1da177e4SLinus Torvalds { 1710*1da177e4SLinus Torvalds ptr = bh->b_data + *extoffset; 1711*1da177e4SLinus Torvalds atomic_inc(&bh->b_count); 1712*1da177e4SLinus Torvalds } 1713*1da177e4SLinus Torvalds 1714*1da177e4SLinus Torvalds switch (UDF_I_ALLOCTYPE(inode)) 1715*1da177e4SLinus Torvalds { 1716*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_SHORT: 1717*1da177e4SLinus Torvalds { 1718*1da177e4SLinus Torvalds short_ad *sad = (short_ad *)ptr; 1719*1da177e4SLinus Torvalds sad->extLength = cpu_to_le32(elen); 1720*1da177e4SLinus Torvalds sad->extPosition = cpu_to_le32(eloc.logicalBlockNum); 1721*1da177e4SLinus Torvalds adsize = sizeof(short_ad); 1722*1da177e4SLinus Torvalds break; 1723*1da177e4SLinus Torvalds } 1724*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_LONG: 1725*1da177e4SLinus Torvalds { 1726*1da177e4SLinus Torvalds long_ad *lad = (long_ad *)ptr; 1727*1da177e4SLinus Torvalds lad->extLength = cpu_to_le32(elen); 1728*1da177e4SLinus Torvalds lad->extLocation = cpu_to_lelb(eloc); 1729*1da177e4SLinus Torvalds memset(lad->impUse, 0x00, sizeof(lad->impUse)); 1730*1da177e4SLinus Torvalds adsize = sizeof(long_ad); 1731*1da177e4SLinus Torvalds break; 1732*1da177e4SLinus Torvalds } 1733*1da177e4SLinus Torvalds default: 1734*1da177e4SLinus Torvalds return -1; 1735*1da177e4SLinus Torvalds } 1736*1da177e4SLinus Torvalds 1737*1da177e4SLinus Torvalds if (bh) 1738*1da177e4SLinus Torvalds { 1739*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 1740*1da177e4SLinus Torvalds { 1741*1da177e4SLinus Torvalds struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data; 1742*1da177e4SLinus Torvalds udf_update_tag((bh)->b_data, 1743*1da177e4SLinus Torvalds le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); 1744*1da177e4SLinus Torvalds } 1745*1da177e4SLinus Torvalds mark_buffer_dirty_inode(bh, inode); 1746*1da177e4SLinus Torvalds udf_release_data(bh); 1747*1da177e4SLinus Torvalds } 1748*1da177e4SLinus Torvalds else 1749*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1750*1da177e4SLinus Torvalds 1751*1da177e4SLinus Torvalds if (inc) 1752*1da177e4SLinus Torvalds *extoffset += adsize; 1753*1da177e4SLinus Torvalds return (elen >> 30); 1754*1da177e4SLinus Torvalds } 1755*1da177e4SLinus Torvalds 1756*1da177e4SLinus Torvalds int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, 1757*1da177e4SLinus Torvalds kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) 1758*1da177e4SLinus Torvalds { 1759*1da177e4SLinus Torvalds int8_t etype; 1760*1da177e4SLinus Torvalds 1761*1da177e4SLinus Torvalds while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) == 1762*1da177e4SLinus Torvalds (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) 1763*1da177e4SLinus Torvalds { 1764*1da177e4SLinus Torvalds *bloc = *eloc; 1765*1da177e4SLinus Torvalds *extoffset = sizeof(struct allocExtDesc); 1766*1da177e4SLinus Torvalds udf_release_data(*bh); 1767*1da177e4SLinus Torvalds if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) 1768*1da177e4SLinus Torvalds { 1769*1da177e4SLinus Torvalds udf_debug("reading block %d failed!\n", 1770*1da177e4SLinus Torvalds udf_get_lb_pblock(inode->i_sb, *bloc, 0)); 1771*1da177e4SLinus Torvalds return -1; 1772*1da177e4SLinus Torvalds } 1773*1da177e4SLinus Torvalds } 1774*1da177e4SLinus Torvalds 1775*1da177e4SLinus Torvalds return etype; 1776*1da177e4SLinus Torvalds } 1777*1da177e4SLinus Torvalds 1778*1da177e4SLinus Torvalds int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, 1779*1da177e4SLinus Torvalds kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) 1780*1da177e4SLinus Torvalds { 1781*1da177e4SLinus Torvalds int alen; 1782*1da177e4SLinus Torvalds int8_t etype; 1783*1da177e4SLinus Torvalds uint8_t *ptr; 1784*1da177e4SLinus Torvalds 1785*1da177e4SLinus Torvalds if (!*bh) 1786*1da177e4SLinus Torvalds { 1787*1da177e4SLinus Torvalds if (!(*extoffset)) 1788*1da177e4SLinus Torvalds *extoffset = udf_file_entry_alloc_offset(inode); 1789*1da177e4SLinus Torvalds ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); 1790*1da177e4SLinus Torvalds alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); 1791*1da177e4SLinus Torvalds } 1792*1da177e4SLinus Torvalds else 1793*1da177e4SLinus Torvalds { 1794*1da177e4SLinus Torvalds if (!(*extoffset)) 1795*1da177e4SLinus Torvalds *extoffset = sizeof(struct allocExtDesc); 1796*1da177e4SLinus Torvalds ptr = (*bh)->b_data + *extoffset; 1797*1da177e4SLinus Torvalds alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); 1798*1da177e4SLinus Torvalds } 1799*1da177e4SLinus Torvalds 1800*1da177e4SLinus Torvalds switch (UDF_I_ALLOCTYPE(inode)) 1801*1da177e4SLinus Torvalds { 1802*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_SHORT: 1803*1da177e4SLinus Torvalds { 1804*1da177e4SLinus Torvalds short_ad *sad; 1805*1da177e4SLinus Torvalds 1806*1da177e4SLinus Torvalds if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) 1807*1da177e4SLinus Torvalds return -1; 1808*1da177e4SLinus Torvalds 1809*1da177e4SLinus Torvalds etype = le32_to_cpu(sad->extLength) >> 30; 1810*1da177e4SLinus Torvalds eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); 1811*1da177e4SLinus Torvalds eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; 1812*1da177e4SLinus Torvalds *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; 1813*1da177e4SLinus Torvalds break; 1814*1da177e4SLinus Torvalds } 1815*1da177e4SLinus Torvalds case ICBTAG_FLAG_AD_LONG: 1816*1da177e4SLinus Torvalds { 1817*1da177e4SLinus Torvalds long_ad *lad; 1818*1da177e4SLinus Torvalds 1819*1da177e4SLinus Torvalds if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) 1820*1da177e4SLinus Torvalds return -1; 1821*1da177e4SLinus Torvalds 1822*1da177e4SLinus Torvalds etype = le32_to_cpu(lad->extLength) >> 30; 1823*1da177e4SLinus Torvalds *eloc = lelb_to_cpu(lad->extLocation); 1824*1da177e4SLinus Torvalds *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; 1825*1da177e4SLinus Torvalds break; 1826*1da177e4SLinus Torvalds } 1827*1da177e4SLinus Torvalds default: 1828*1da177e4SLinus Torvalds { 1829*1da177e4SLinus Torvalds udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode)); 1830*1da177e4SLinus Torvalds return -1; 1831*1da177e4SLinus Torvalds } 1832*1da177e4SLinus Torvalds } 1833*1da177e4SLinus Torvalds 1834*1da177e4SLinus Torvalds return etype; 1835*1da177e4SLinus Torvalds } 1836*1da177e4SLinus Torvalds 1837*1da177e4SLinus Torvalds static int8_t 1838*1da177e4SLinus Torvalds udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, 1839*1da177e4SLinus Torvalds kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) 1840*1da177e4SLinus Torvalds { 1841*1da177e4SLinus Torvalds kernel_lb_addr oeloc; 1842*1da177e4SLinus Torvalds uint32_t oelen; 1843*1da177e4SLinus Torvalds int8_t etype; 1844*1da177e4SLinus Torvalds 1845*1da177e4SLinus Torvalds if (bh) 1846*1da177e4SLinus Torvalds atomic_inc(&bh->b_count); 1847*1da177e4SLinus Torvalds 1848*1da177e4SLinus Torvalds while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) 1849*1da177e4SLinus Torvalds { 1850*1da177e4SLinus Torvalds udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); 1851*1da177e4SLinus Torvalds 1852*1da177e4SLinus Torvalds neloc = oeloc; 1853*1da177e4SLinus Torvalds nelen = (etype << 30) | oelen; 1854*1da177e4SLinus Torvalds } 1855*1da177e4SLinus Torvalds udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); 1856*1da177e4SLinus Torvalds udf_release_data(bh); 1857*1da177e4SLinus Torvalds return (nelen >> 30); 1858*1da177e4SLinus Torvalds } 1859*1da177e4SLinus Torvalds 1860*1da177e4SLinus Torvalds int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, 1861*1da177e4SLinus Torvalds kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) 1862*1da177e4SLinus Torvalds { 1863*1da177e4SLinus Torvalds struct buffer_head *obh; 1864*1da177e4SLinus Torvalds kernel_lb_addr obloc; 1865*1da177e4SLinus Torvalds int oextoffset, adsize; 1866*1da177e4SLinus Torvalds int8_t etype; 1867*1da177e4SLinus Torvalds struct allocExtDesc *aed; 1868*1da177e4SLinus Torvalds 1869*1da177e4SLinus Torvalds if (nbh) 1870*1da177e4SLinus Torvalds { 1871*1da177e4SLinus Torvalds atomic_inc(&nbh->b_count); 1872*1da177e4SLinus Torvalds atomic_inc(&nbh->b_count); 1873*1da177e4SLinus Torvalds } 1874*1da177e4SLinus Torvalds 1875*1da177e4SLinus Torvalds if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) 1876*1da177e4SLinus Torvalds adsize = sizeof(short_ad); 1877*1da177e4SLinus Torvalds else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) 1878*1da177e4SLinus Torvalds adsize = sizeof(long_ad); 1879*1da177e4SLinus Torvalds else 1880*1da177e4SLinus Torvalds adsize = 0; 1881*1da177e4SLinus Torvalds 1882*1da177e4SLinus Torvalds obh = nbh; 1883*1da177e4SLinus Torvalds obloc = nbloc; 1884*1da177e4SLinus Torvalds oextoffset = nextoffset; 1885*1da177e4SLinus Torvalds 1886*1da177e4SLinus Torvalds if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) 1887*1da177e4SLinus Torvalds return -1; 1888*1da177e4SLinus Torvalds 1889*1da177e4SLinus Torvalds while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) 1890*1da177e4SLinus Torvalds { 1891*1da177e4SLinus Torvalds udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1); 1892*1da177e4SLinus Torvalds if (obh != nbh) 1893*1da177e4SLinus Torvalds { 1894*1da177e4SLinus Torvalds obloc = nbloc; 1895*1da177e4SLinus Torvalds udf_release_data(obh); 1896*1da177e4SLinus Torvalds atomic_inc(&nbh->b_count); 1897*1da177e4SLinus Torvalds obh = nbh; 1898*1da177e4SLinus Torvalds oextoffset = nextoffset - adsize; 1899*1da177e4SLinus Torvalds } 1900*1da177e4SLinus Torvalds } 1901*1da177e4SLinus Torvalds memset(&eloc, 0x00, sizeof(kernel_lb_addr)); 1902*1da177e4SLinus Torvalds elen = 0; 1903*1da177e4SLinus Torvalds 1904*1da177e4SLinus Torvalds if (nbh != obh) 1905*1da177e4SLinus Torvalds { 1906*1da177e4SLinus Torvalds udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); 1907*1da177e4SLinus Torvalds udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); 1908*1da177e4SLinus Torvalds udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); 1909*1da177e4SLinus Torvalds if (!obh) 1910*1da177e4SLinus Torvalds { 1911*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) -= (adsize * 2); 1912*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1913*1da177e4SLinus Torvalds } 1914*1da177e4SLinus Torvalds else 1915*1da177e4SLinus Torvalds { 1916*1da177e4SLinus Torvalds aed = (struct allocExtDesc *)(obh)->b_data; 1917*1da177e4SLinus Torvalds aed->lengthAllocDescs = 1918*1da177e4SLinus Torvalds cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); 1919*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 1920*1da177e4SLinus Torvalds udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); 1921*1da177e4SLinus Torvalds else 1922*1da177e4SLinus Torvalds udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); 1923*1da177e4SLinus Torvalds mark_buffer_dirty_inode(obh, inode); 1924*1da177e4SLinus Torvalds } 1925*1da177e4SLinus Torvalds } 1926*1da177e4SLinus Torvalds else 1927*1da177e4SLinus Torvalds { 1928*1da177e4SLinus Torvalds udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); 1929*1da177e4SLinus Torvalds if (!obh) 1930*1da177e4SLinus Torvalds { 1931*1da177e4SLinus Torvalds UDF_I_LENALLOC(inode) -= adsize; 1932*1da177e4SLinus Torvalds mark_inode_dirty(inode); 1933*1da177e4SLinus Torvalds } 1934*1da177e4SLinus Torvalds else 1935*1da177e4SLinus Torvalds { 1936*1da177e4SLinus Torvalds aed = (struct allocExtDesc *)(obh)->b_data; 1937*1da177e4SLinus Torvalds aed->lengthAllocDescs = 1938*1da177e4SLinus Torvalds cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); 1939*1da177e4SLinus Torvalds if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 1940*1da177e4SLinus Torvalds udf_update_tag((obh)->b_data, oextoffset - adsize); 1941*1da177e4SLinus Torvalds else 1942*1da177e4SLinus Torvalds udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); 1943*1da177e4SLinus Torvalds mark_buffer_dirty_inode(obh, inode); 1944*1da177e4SLinus Torvalds } 1945*1da177e4SLinus Torvalds } 1946*1da177e4SLinus Torvalds 1947*1da177e4SLinus Torvalds udf_release_data(nbh); 1948*1da177e4SLinus Torvalds udf_release_data(obh); 1949*1da177e4SLinus Torvalds return (elen >> 30); 1950*1da177e4SLinus Torvalds } 1951*1da177e4SLinus Torvalds 1952*1da177e4SLinus Torvalds int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset, 1953*1da177e4SLinus Torvalds kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) 1954*1da177e4SLinus Torvalds { 1955*1da177e4SLinus Torvalds uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits; 1956*1da177e4SLinus Torvalds int8_t etype; 1957*1da177e4SLinus Torvalds 1958*1da177e4SLinus Torvalds if (block < 0) 1959*1da177e4SLinus Torvalds { 1960*1da177e4SLinus Torvalds printk(KERN_ERR "udf: inode_bmap: block < 0\n"); 1961*1da177e4SLinus Torvalds return -1; 1962*1da177e4SLinus Torvalds } 1963*1da177e4SLinus Torvalds if (!inode) 1964*1da177e4SLinus Torvalds { 1965*1da177e4SLinus Torvalds printk(KERN_ERR "udf: inode_bmap: NULL inode\n"); 1966*1da177e4SLinus Torvalds return -1; 1967*1da177e4SLinus Torvalds } 1968*1da177e4SLinus Torvalds 1969*1da177e4SLinus Torvalds *extoffset = 0; 1970*1da177e4SLinus Torvalds *elen = 0; 1971*1da177e4SLinus Torvalds *bloc = UDF_I_LOCATION(inode); 1972*1da177e4SLinus Torvalds 1973*1da177e4SLinus Torvalds do 1974*1da177e4SLinus Torvalds { 1975*1da177e4SLinus Torvalds if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) 1976*1da177e4SLinus Torvalds { 1977*1da177e4SLinus Torvalds *offset = bcount - lbcount; 1978*1da177e4SLinus Torvalds UDF_I_LENEXTENTS(inode) = lbcount; 1979*1da177e4SLinus Torvalds return -1; 1980*1da177e4SLinus Torvalds } 1981*1da177e4SLinus Torvalds lbcount += *elen; 1982*1da177e4SLinus Torvalds } while (lbcount <= bcount); 1983*1da177e4SLinus Torvalds 1984*1da177e4SLinus Torvalds *offset = bcount + *elen - lbcount; 1985*1da177e4SLinus Torvalds 1986*1da177e4SLinus Torvalds return etype; 1987*1da177e4SLinus Torvalds } 1988*1da177e4SLinus Torvalds 1989*1da177e4SLinus Torvalds long udf_block_map(struct inode *inode, long block) 1990*1da177e4SLinus Torvalds { 1991*1da177e4SLinus Torvalds kernel_lb_addr eloc, bloc; 1992*1da177e4SLinus Torvalds uint32_t offset, extoffset, elen; 1993*1da177e4SLinus Torvalds struct buffer_head *bh = NULL; 1994*1da177e4SLinus Torvalds int ret; 1995*1da177e4SLinus Torvalds 1996*1da177e4SLinus Torvalds lock_kernel(); 1997*1da177e4SLinus Torvalds 1998*1da177e4SLinus Torvalds if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) 1999*1da177e4SLinus Torvalds ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits); 2000*1da177e4SLinus Torvalds else 2001*1da177e4SLinus Torvalds ret = 0; 2002*1da177e4SLinus Torvalds 2003*1da177e4SLinus Torvalds unlock_kernel(); 2004*1da177e4SLinus Torvalds udf_release_data(bh); 2005*1da177e4SLinus Torvalds 2006*1da177e4SLinus Torvalds if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) 2007*1da177e4SLinus Torvalds return udf_fixed_to_variable(ret); 2008*1da177e4SLinus Torvalds else 2009*1da177e4SLinus Torvalds return ret; 2010*1da177e4SLinus Torvalds } 2011