📄 inode.c
字号:
if (memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr))) { aed = (struct AllocExtDesc *)(*bh)->b_data; aed->lengthAllocDescs = cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); } else { UDF_I_LENALLOC(inode) += adsize; mark_inode_dirty(inode); } } udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1, bloc->logicalBlockNum, sizeof(tag)); switch (UDF_I_ALLOCTYPE(inode)) { case ICB_FLAG_AD_SHORT: { sad = (short_ad *)sptr; sad->extLength = cpu_to_le32( EXTENT_NEXT_EXTENT_ALLOCDECS << 30 | inode->i_sb->s_blocksize); sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); break; } case ICB_FLAG_AD_LONG: { lad = (long_ad *)sptr; lad->extLength = cpu_to_le32( EXTENT_NEXT_EXTENT_ALLOCDECS << 30 | inode->i_sb->s_blocksize); lad->extLocation = cpu_to_lelb(*bloc); break; } } udf_update_tag((*bh)->b_data, loffset); mark_buffer_dirty(*bh); udf_release_data(*bh); *bh = nbh; } ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, bh, inc); if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr))) { UDF_I_LENALLOC(inode) += adsize; mark_inode_dirty(inode); } else { aed = (struct AllocExtDesc *)(*bh)->b_data; aed->lengthAllocDescs = cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); mark_buffer_dirty(*bh); } return ret;}int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset, lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc){ int adsize; short_ad *sad = NULL; long_ad *lad = NULL; if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0), inode->i_sb->s_blocksize))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, bloc, 0)); return -1; } } if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) adsize = sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) adsize = sizeof(long_ad); else return -1; switch (UDF_I_ALLOCTYPE(inode)) { case ICB_FLAG_AD_SHORT: { sad = (short_ad *)((*bh)->b_data + *extoffset); sad->extLength = cpu_to_le32(elen); sad->extPosition = cpu_to_le32(eloc.logicalBlockNum); break; } case ICB_FLAG_AD_LONG: { lad = (long_ad *)((*bh)->b_data + *extoffset); lad->extLength = cpu_to_le32(elen); lad->extLocation = cpu_to_lelb(eloc); break; } } if (memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr))) { struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data; udf_update_tag((*bh)->b_data, le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc)); } else mark_inode_dirty(inode); mark_buffer_dirty(*bh); if (inc) *extoffset += adsize; return (elen >> 30);}int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset, lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc){ int pos, alen; Uint8 etype; if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0), inode->i_sb->s_blocksize))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); return -1; } } if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr))) { pos = udf_file_entry_alloc_offset(inode); alen = UDF_I_LENALLOC(inode) + pos; } else { struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data; pos = sizeof(struct AllocExtDesc); alen = le32_to_cpu(aed->lengthAllocDescs) + pos; } if (!(*extoffset)) *extoffset = pos; switch (UDF_I_ALLOCTYPE(inode)) { case ICB_FLAG_AD_SHORT: { short_ad *sad; if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc))) return -1; if ((etype = le32_to_cpu(sad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS) { bloc->logicalBlockNum = le32_to_cpu(sad->extPosition); *extoffset = 0; udf_release_data(*bh); *bh = NULL; return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc); } else { eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; } break; } case ICB_FLAG_AD_LONG: { long_ad *lad; if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc))) return -1; if ((etype = le32_to_cpu(lad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS) { *bloc = lelb_to_cpu(lad->extLocation); *extoffset = 0; udf_release_data(*bh); *bh = NULL; return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc); } else { *eloc = lelb_to_cpu(lad->extLocation); *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; } break; } case ICB_FLAG_AD_IN_ICB: { if (UDF_I_LENALLOC(inode) == 0) return -1; etype = EXTENT_RECORDED_ALLOCATED; *eloc = UDF_I_LOCATION(inode); *elen = UDF_I_LENALLOC(inode); break; } default: { udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode)); return -1; } } if (*elen) return etype; udf_debug("Empty Extent, inode=%ld, alloctype=%d, eloc=%d, elen=%d, etype=%d, extoffset=%d\n", inode->i_ino, UDF_I_ALLOCTYPE(inode), eloc->logicalBlockNum, *elen, etype, *extoffset); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) *extoffset -= sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) *extoffset -= sizeof(long_ad); return -1;}int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset, lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc){ int pos, alen; Uint8 etype; if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0), inode->i_sb->s_blocksize))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); return -1; } } if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr))) { if (!(UDF_I_EXTENDED_FE(inode))) pos = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode); else pos = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode); alen = UDF_I_LENALLOC(inode) + pos; } else { struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data; pos = sizeof(struct AllocExtDesc); alen = le32_to_cpu(aed->lengthAllocDescs) + pos; } if (!(*extoffset)) *extoffset = pos; switch (UDF_I_ALLOCTYPE(inode)) { case ICB_FLAG_AD_SHORT: { short_ad *sad; if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc))) return -1; etype = le32_to_cpu(sad->extLength) >> 30; eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; break; } case ICB_FLAG_AD_LONG: { long_ad *lad; if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc))) return -1; etype = le32_to_cpu(lad->extLength) >> 30; *eloc = lelb_to_cpu(lad->extLocation); *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; break; } default: { udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode)); return -1; } } if (*elen) return etype; udf_debug("Empty Extent!\n"); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) *extoffset -= sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) *extoffset -= sizeof(long_ad); return -1;}int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset, lb_addr neloc, Uint32 nelen, struct buffer_head *bh){ lb_addr oeloc; Uint32 oelen; int type; if (!bh) { if (!(bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0), inode->i_sb->s_blocksize))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, bloc, 0)); return -1; } } else atomic_inc(&bh->b_count); while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) { udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 1); neloc = oeloc; nelen = (type << 30) | oelen; } udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); udf_release_data(bh); return (nelen >> 30);}int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset, lb_addr eloc, Uint32 elen, struct buffer_head *nbh){ struct buffer_head *obh; lb_addr obloc; int oextoffset, adsize; int type; struct AllocExtDesc *aed; if (!(nbh)) { if (!(nbh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, nbloc, 0), inode->i_sb->s_blocksize))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, nbloc, 0)); return -1; } } else atomic_inc(&nbh->b_count); atomic_inc(&nbh->b_count); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) adsize = sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) adsize = sizeof(long_ad); else adsize = 0; obh = nbh; obloc = nbloc; oextoffset = nextoffset; if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) return -1; while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) { udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, &obh, 1); if (memcmp(&nbloc, &obloc, sizeof(lb_addr))) { obloc = nbloc; udf_release_data(obh); atomic_inc(&nbh->b_count); obh = nbh; oextoffset = nextoffset - adsize; } } memset(&eloc, 0x00, sizeof(lb_addr)); elen = 0; if (memcmp(&nbloc, &obloc, sizeof(lb_addr))) { udf_free_blocks(inode, nbloc, 0, 1); udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1); udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1); if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr))) { UDF_I_LENALLOC(inode) -= (adsize * 2); mark_inode_dirty(inode); } else { aed = (struct AllocExtDesc *)(obh)->b_data; aed->lengthAllocDescs = cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); mark_buffer_dirty(obh); } } else { udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1); if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr))) { UDF_I_LENALLOC(inode) -= adsize; mark_inode_dirty(inode); } else { aed = (struct AllocExtDesc *)(obh)->b_data; aed->lengthAllocDescs = cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); udf_update_tag((obh)->b_data, oextoffset - adsize); mark_buffer_dirty(obh); } } udf_release_data(nbh); udf_release_data(obh); return (elen >> 30);}int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset, lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh){ int etype, lbcount = 0; if (block < 0) { 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; *bloc = UDF_I_LOCATION(inode); do { if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) { *offset = block - lbcount; return -1; } lbcount += ((*elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); } while (lbcount <= block); *offset = block + ((*elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits) - lbcount; return etype;}long udf_locked_block_map(struct inode *inode, long block){ lb_addr eloc, bloc; Uint32 offset, extoffset, elen; struct buffer_head *bh = NULL; int ret; if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED) ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); else ret = 0; if (bh) udf_release_data(bh); if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) return udf_fixed_to_variable(ret); else return ret;}long udf_block_map(struct inode *inode, long block){ int ret; lock_kernel(); ret = udf_locked_block_map(inode, block); unlock_kernel(); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -