X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fudf%2Finode.c;h=2983afd5e7fd4932ca77cd24e95041f94b719062;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=f4724459a1a97a9f765678ed85e5f592ceaea537;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/udf/inode.c b/fs/udf/inode.c index f4724459a..2983afd5e 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -4,11 +4,6 @@ * PURPOSE * Inode handling routines for the OSTA-UDF(tm) filesystem. * - * CONTACTS - * E-mail regarding any portion of the Linux UDF file system should be - * directed to the development team mailing list (run by majordomo): - * linux_udf@hpesjro.fc.hp.com - * * COPYRIGHT * This file is distributed under the terms of the GNU General Public * License (GPL). Copies of the GPL can be obtained from: @@ -54,42 +49,21 @@ MODULE_LICENSE("GPL"); static mode_t udf_convert_permissions(struct fileEntry *); static int udf_update_inode(struct inode *, int); static void udf_fill_inode(struct inode *, struct buffer_head *); -static struct buffer_head *inode_getblk(struct inode *, long, int *, long *, int *); +static struct buffer_head *inode_getblk(struct inode *, long, int *, + long *, int *); +static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, + kernel_lb_addr, uint32_t, struct buffer_head *); static void udf_split_extents(struct inode *, int *, int, int, - long_ad [EXTENT_MERGE_SIZE], int *); + kernel_long_ad [EXTENT_MERGE_SIZE], int *); static void udf_prealloc_extents(struct inode *, int, int, - long_ad [EXTENT_MERGE_SIZE], int *); + kernel_long_ad [EXTENT_MERGE_SIZE], int *); static void udf_merge_extents(struct inode *, - long_ad [EXTENT_MERGE_SIZE], int *); + kernel_long_ad [EXTENT_MERGE_SIZE], int *); static void udf_update_extents(struct inode *, - long_ad [EXTENT_MERGE_SIZE], int, int, - lb_addr, uint32_t, struct buffer_head **); + kernel_long_ad [EXTENT_MERGE_SIZE], int, int, + kernel_lb_addr, uint32_t, struct buffer_head **); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); -/* - * udf_put_inode - * - * PURPOSE - * - * DESCRIPTION - * This routine is called whenever the kernel no longer needs the inode. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - * - * Called at each iput() - */ -void udf_put_inode(struct inode * inode) -{ - if (!(inode->i_sb->s_flags & MS_RDONLY)) - { - lock_kernel(); - udf_discard_prealloc(inode); - unlock_kernel(); - } -} - /* * udf_delete_inode * @@ -108,6 +82,8 @@ void udf_put_inode(struct inode * inode) */ void udf_delete_inode(struct inode * inode) { + truncate_inode_pages(&inode->i_data, 0); + if (is_bad_inode(inode)) goto no_delete; @@ -126,6 +102,12 @@ no_delete: void udf_clear_inode(struct inode *inode) { + if (!(inode->i_sb->s_flags & MS_RDONLY)) { + lock_kernel(); + udf_discard_prealloc(inode); + unlock_kernel(); + } + kfree(UDF_I_DATA(inode)); UDF_I_DATA(inode) = NULL; } @@ -182,8 +164,8 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) } page = grab_cache_page(inode->i_mapping, 0); - if (!PageLocked(page)) - PAGE_BUG(page); + BUG_ON(!PageLocked(page)); + if (!PageUptodate(page)) { kaddr = kmap(page); @@ -213,7 +195,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int { int newblock; struct buffer_head *sbh = NULL, *dbh = NULL; - lb_addr bloc, eloc; + kernel_lb_addr bloc, eloc; uint32_t elen, extoffset; uint8_t alloctype; @@ -268,12 +250,12 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int return NULL; } UDF_I_ALLOCTYPE(inode) = alloctype; - sfi->descTag.tagLocation = *block; + sfi->descTag.tagLocation = cpu_to_le32(*block); dfibh.soffset = dfibh.eoffset; dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset); if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse, - sfi->fileIdent + sfi->lengthOfImpUse)) + sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) { UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; udf_release_data(dbh); @@ -330,12 +312,10 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head err = 0; bh = inode_getblk(inode, block, &err, &phys, &new); - if (bh) - BUG(); + BUG_ON(bh); if (err) goto abort; - if (!phys) - BUG(); + BUG_ON(!phys); if (new) set_buffer_new(bh_result); @@ -349,8 +329,8 @@ abort_negative: goto abort; } -struct buffer_head * udf_getblk(struct inode * inode, long block, - int create, int * err) +static struct buffer_head * +udf_getblk(struct inode *inode, long block, int create, int *err) { struct buffer_head dummy; @@ -378,11 +358,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, int *err, long *phys, int *new) { struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; - long_ad laarr[EXTENT_MERGE_SIZE]; + kernel_long_ad laarr[EXTENT_MERGE_SIZE]; uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; int count = 0, startnum = 0, endnum = 0; uint32_t elen = 0; - lb_addr eloc, pbloc, cbloc, nbloc; + kernel_lb_addr eloc, pbloc, cbloc, nbloc; int c = 1; uint64_t lbcount = 0, b_off = 0; uint32_t newblocknum, newblock, offset = 0; @@ -476,7 +456,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, c = !c; laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | ((offset + 1) << inode->i_sb->s_blocksize_bits); - memset(&laarr[c].extLocation, 0x00, sizeof(lb_addr)); + memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); count ++; endnum ++; lastblock = 1; @@ -565,7 +545,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, *new = 1; UDF_I_NEXT_ALLOC_BLOCK(inode) = block; UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum; - inode->i_ctime = CURRENT_TIME; + inode->i_ctime = current_fs_time(inode->i_sb); if (IS_SYNC(inode)) udf_sync_inode(inode); @@ -575,7 +555,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, } static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum, - long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) + kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) || (laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) @@ -637,7 +617,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset, int newbl } static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, - long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) + kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { int start, length = 0, currlength = 0, i; @@ -729,7 +709,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, } static void udf_merge_extents(struct inode *inode, - long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) + kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { int i; @@ -814,11 +794,11 @@ static void udf_merge_extents(struct inode *inode, } static void udf_update_extents(struct inode *inode, - long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, - lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) + kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, + kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) { int start = 0, i; - lb_addr tmploc; + kernel_lb_addr tmploc; uint32_t tmplen; if (startnum > endnum) @@ -909,7 +889,7 @@ void udf_truncate(struct inode * inode) udf_truncate_extents(inode); } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); if (IS_SYNC(inode)) udf_sync_inode (inode); else @@ -917,31 +897,7 @@ void udf_truncate(struct inode * inode) unlock_kernel(); } -/* - * udf_read_inode - * - * PURPOSE - * Read an inode. - * - * DESCRIPTION - * This routine is called by iget() [which is called by udf_iget()] - * (clean_inode() will have been called first) - * when an inode is first read into memory. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - * - * 12/19/98 dgb Updated to fix size problems. - */ - -void -udf_read_inode(struct inode *inode) -{ - memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(lb_addr)); -} - -void +static void __udf_read_inode(struct inode *inode) { struct buffer_head *bh = NULL; @@ -994,7 +950,7 @@ __udf_read_inode(struct inode *inode) { if (ibh) { - lb_addr loc; + kernel_lb_addr loc; ie = (struct indirectEntry *)ibh->b_data; loc = lelb_to_cpu(ie->indirectICB.extLocation); @@ -1005,7 +961,7 @@ __udf_read_inode(struct inode *inode) if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) { - memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr)); + memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); udf_release_data(bh); udf_release_data(ibh); udf_release_data(nbh); @@ -1087,10 +1043,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) } inode->i_uid = le32_to_cpu(fe->uid); - if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; + if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_UID_IGNORE)) + inode->i_uid = UDF_SB(inode->i_sb)->s_uid; inode->i_gid = le32_to_cpu(fe->gid); - if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; + if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_GID_IGNORE)) + inode->i_gid = UDF_SB(inode->i_sb)->s_gid; inode->i_nlink = le16_to_cpu(fe->fileLinkCount); if (!inode->i_nlink) @@ -1313,11 +1273,13 @@ udf_convert_permissions(struct fileEntry *fe) * Written, tested, and released. */ -void udf_write_inode(struct inode * inode, int sync) +int udf_write_inode(struct inode * inode, int sync) { + int ret; lock_kernel(); - udf_update_inode(inode, sync); + ret = udf_update_inode(inode, sync); unlock_kernel(); + return ret; } int udf_sync_inode(struct inode * inode) @@ -1335,7 +1297,7 @@ udf_update_inode(struct inode *inode, int do_sync) uint16_t icbflags; uint16_t crclen; int i; - timestamp cpu_time; + kernel_timestamp cpu_time; int err = 0; bh = udf_tread(inode->i_sb, @@ -1375,11 +1337,13 @@ udf_update_inode(struct inode *inode, int do_sync) return err; } - if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) - fe->uid = cpu_to_le32(inode->i_uid); + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) + fe->uid = cpu_to_le32(-1); + else fe->uid = cpu_to_le32(inode->i_uid); - if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) - fe->gid = cpu_to_le32(inode->i_gid); + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) + fe->gid = cpu_to_le32(-1); + else fe->gid = cpu_to_le32(inode->i_gid); udfperms = ((inode->i_mode & S_IRWXO) ) | ((inode->i_mode & S_IRWXG) << 2) | @@ -1411,11 +1375,11 @@ udf_update_inode(struct inode *inode, int do_sync) udf_add_extendedattr(inode, sizeof(struct deviceSpec) + sizeof(regid), 12, 0x3); - dsea->attrType = 12; + dsea->attrType = cpu_to_le32(12); dsea->attrSubtype = 1; - dsea->attrLength = sizeof(struct deviceSpec) + - sizeof(regid); - dsea->impUseLength = sizeof(regid); + dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) + + sizeof(regid)); + dsea->impUseLength = cpu_to_le32(sizeof(regid)); } eid = (regid *)dsea->impUse; memset(eid, 0, sizeof(regid)); @@ -1446,7 +1410,7 @@ udf_update_inode(struct inode *inode, int do_sync) fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); - fe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_FE); + fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); crclen = sizeof(struct fileEntry); } else @@ -1492,7 +1456,7 @@ udf_update_inode(struct inode *inode, int do_sync) efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); - efe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_EFE); + efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); crclen = sizeof(struct extendedFileEntry); } if (UDF_I_STRAT4096(inode)) @@ -1562,70 +1526,40 @@ udf_update_inode(struct inode *inode, int do_sync) return err; } -/* - * udf_iget - * - * PURPOSE - * Get an inode. - * - * DESCRIPTION - * This routine replaces iget() and read_inode(). - * - * HISTORY - * October 3, 1997 - Andrew E. Mileski - * Written, tested, and released. - * - * 12/19/98 dgb Added semaphore and changed to be a wrapper of iget - */ struct inode * -udf_iget(struct super_block *sb, lb_addr ino) +udf_iget(struct super_block *sb, kernel_lb_addr ino) { - struct inode *inode; - unsigned long block; - - block = udf_get_lb_pblock(sb, ino, 0); - - /* Get the inode */ - - inode = iget(sb, block); - /* calls udf_read_inode() ! */ + unsigned long block = udf_get_lb_pblock(sb, ino, 0); + struct inode *inode = iget_locked(sb, block); if (!inode) - { - printk(KERN_ERR "udf: iget() failed\n"); return NULL; - } - else if (is_bad_inode(inode)) - { - iput(inode); - return NULL; - } - else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF && - UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF) - { - memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr)); + + if (inode->i_state & I_NEW) { + memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr)); __udf_read_inode(inode); - if (is_bad_inode(inode)) - { - iput(inode); - return NULL; - } + unlock_new_inode(inode); } - if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) ) - { + if (is_bad_inode(inode)) + goto out_iput; + + if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) { udf_debug("block=%d, partition=%d out of range\n", ino.logicalBlockNum, ino.partitionReferenceNum); make_bad_inode(inode); - iput(inode); - return NULL; - } + goto out_iput; + } return inode; + + out_iput: + iput(inode); + return NULL; } -int8_t udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, - lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) +int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, + kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) { int adsize; short_ad *sad = NULL; @@ -1651,7 +1585,7 @@ int8_t udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, char *sptr, *dptr; struct buffer_head *nbh; int err, loffset; - lb_addr obloc = *bloc; + kernel_lb_addr obloc = *bloc; if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) @@ -1764,8 +1698,8 @@ int8_t udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, return etype; } -int8_t udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset, - lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) +int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, + kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) { int adsize; uint8_t *ptr; @@ -1820,8 +1754,8 @@ int8_t udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset, return (elen >> 30); } -int8_t udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset, - lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) +int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, + kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) { int8_t etype; @@ -1842,8 +1776,8 @@ int8_t udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset, return etype; } -int8_t udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset, - lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) +int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, + kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) { int alen; int8_t etype; @@ -1901,10 +1835,11 @@ int8_t udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset, return etype; } -int8_t udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset, - lb_addr neloc, uint32_t nelen, struct buffer_head *bh) +static int8_t +udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, + kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) { - lb_addr oeloc; + kernel_lb_addr oeloc; uint32_t oelen; int8_t etype; @@ -1923,11 +1858,11 @@ int8_t udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset, return (nelen >> 30); } -int8_t udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset, - lb_addr eloc, uint32_t elen, struct buffer_head *nbh) +int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, + kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) { struct buffer_head *obh; - lb_addr obloc; + kernel_lb_addr obloc; int oextoffset, adsize; int8_t etype; struct allocExtDesc *aed; @@ -1964,7 +1899,7 @@ int8_t udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset, oextoffset = nextoffset - adsize; } } - memset(&eloc, 0x00, sizeof(lb_addr)); + memset(&eloc, 0x00, sizeof(kernel_lb_addr)); elen = 0; if (nbh != obh) @@ -2015,8 +1950,8 @@ int8_t udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset, return (elen >> 30); } -int8_t inode_bmap(struct inode *inode, int block, lb_addr *bloc, uint32_t *extoffset, - lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) +int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset, + kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) { uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits; int8_t etype; @@ -2026,11 +1961,6 @@ int8_t inode_bmap(struct inode *inode, int block, lb_addr *bloc, uint32_t *extof printk(KERN_ERR "udf: inode_bmap: block < 0\n"); return -1; } - if (!inode) - { - printk(KERN_ERR "udf: inode_bmap: NULL inode\n"); - return -1; - } *extoffset = 0; *elen = 0; @@ -2054,7 +1984,7 @@ int8_t inode_bmap(struct inode *inode, int block, lb_addr *bloc, uint32_t *extof long udf_block_map(struct inode *inode, long block) { - lb_addr eloc, bloc; + kernel_lb_addr eloc, bloc; uint32_t offset, extoffset, elen; struct buffer_head *bh = NULL; int ret;