Loading fs/udf/inode.c +29 −37 Original line number Diff line number Diff line Loading @@ -326,14 +326,12 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, udf_pblk_t newblock; struct buffer_head *dbh = NULL; struct kernel_lb_addr eloc; uint8_t alloctype; struct extent_position epos; struct udf_fileident_bh sfibh, dfibh; loff_t f_pos = udf_ext0_offset(inode); int size = udf_ext0_offset(inode) + inode->i_size; struct fileIdentDesc cfi, *sfi, *dfi; uint8_t alloctype; struct udf_inode_info *iinfo = UDF_I(inode); struct udf_fileident_iter iter; uint8_t *impuse; int ret; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) alloctype = ICBTAG_FLAG_AD_SHORT; Loading Loading @@ -361,38 +359,14 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, if (!dbh) return NULL; lock_buffer(dbh); memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize); memcpy(dbh->b_data, iinfo->i_data, inode->i_size); memset(dbh->b_data + inode->i_size, 0, inode->i_sb->s_blocksize - inode->i_size); set_buffer_uptodate(dbh); unlock_buffer(dbh); mark_buffer_dirty_inode(dbh, inode); sfibh.soffset = sfibh.eoffset = f_pos & (inode->i_sb->s_blocksize - 1); sfibh.sbh = sfibh.ebh = NULL; dfibh.soffset = dfibh.eoffset = 0; dfibh.sbh = dfibh.ebh = dbh; while (f_pos < size) { iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); if (!sfi) { brelse(dbh); return NULL; } iinfo->i_alloc_type = alloctype; 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, udf_get_fi_ident(sfi))) { iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; brelse(dbh); return NULL; } } mark_buffer_dirty_inode(dbh, inode); /* Drop inline data, add block instead */ iinfo->i_alloc_type = alloctype; memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc); iinfo->i_lenAlloc = 0; eloc.logicalBlockNum = *block; Loading @@ -403,10 +377,28 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, epos.block = iinfo->i_location; epos.offset = udf_file_entry_alloc_offset(inode); udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); /* UniqueID stuff */ brelse(epos.bh); mark_inode_dirty(inode); /* Now fixup tags in moved directory entries */ for (ret = udf_fiiter_init(&iter, inode, 0); !ret && iter.pos < inode->i_size; ret = udf_fiiter_advance(&iter)) { iter.fi.descTag.tagLocation = cpu_to_le32(*block); if (iter.fi.lengthOfImpUse != cpu_to_le16(0)) impuse = dbh->b_data + iter.pos + sizeof(struct fileIdentDesc); else impuse = NULL; udf_fiiter_write_fi(&iter, impuse); } /* * We don't expect the iteration to fail as the directory has been * already verified to be correct */ WARN_ON_ONCE(ret); udf_fiiter_release(&iter); return dbh; } Loading Loading
fs/udf/inode.c +29 −37 Original line number Diff line number Diff line Loading @@ -326,14 +326,12 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, udf_pblk_t newblock; struct buffer_head *dbh = NULL; struct kernel_lb_addr eloc; uint8_t alloctype; struct extent_position epos; struct udf_fileident_bh sfibh, dfibh; loff_t f_pos = udf_ext0_offset(inode); int size = udf_ext0_offset(inode) + inode->i_size; struct fileIdentDesc cfi, *sfi, *dfi; uint8_t alloctype; struct udf_inode_info *iinfo = UDF_I(inode); struct udf_fileident_iter iter; uint8_t *impuse; int ret; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) alloctype = ICBTAG_FLAG_AD_SHORT; Loading Loading @@ -361,38 +359,14 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, if (!dbh) return NULL; lock_buffer(dbh); memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize); memcpy(dbh->b_data, iinfo->i_data, inode->i_size); memset(dbh->b_data + inode->i_size, 0, inode->i_sb->s_blocksize - inode->i_size); set_buffer_uptodate(dbh); unlock_buffer(dbh); mark_buffer_dirty_inode(dbh, inode); sfibh.soffset = sfibh.eoffset = f_pos & (inode->i_sb->s_blocksize - 1); sfibh.sbh = sfibh.ebh = NULL; dfibh.soffset = dfibh.eoffset = 0; dfibh.sbh = dfibh.ebh = dbh; while (f_pos < size) { iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); if (!sfi) { brelse(dbh); return NULL; } iinfo->i_alloc_type = alloctype; 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, udf_get_fi_ident(sfi))) { iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; brelse(dbh); return NULL; } } mark_buffer_dirty_inode(dbh, inode); /* Drop inline data, add block instead */ iinfo->i_alloc_type = alloctype; memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc); iinfo->i_lenAlloc = 0; eloc.logicalBlockNum = *block; Loading @@ -403,10 +377,28 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, epos.block = iinfo->i_location; epos.offset = udf_file_entry_alloc_offset(inode); udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); /* UniqueID stuff */ brelse(epos.bh); mark_inode_dirty(inode); /* Now fixup tags in moved directory entries */ for (ret = udf_fiiter_init(&iter, inode, 0); !ret && iter.pos < inode->i_size; ret = udf_fiiter_advance(&iter)) { iter.fi.descTag.tagLocation = cpu_to_le32(*block); if (iter.fi.lengthOfImpUse != cpu_to_le16(0)) impuse = dbh->b_data + iter.pos + sizeof(struct fileIdentDesc); else impuse = NULL; udf_fiiter_write_fi(&iter, impuse); } /* * We don't expect the iteration to fail as the directory has been * already verified to be correct */ WARN_ON_ONCE(ret); udf_fiiter_release(&iter); return dbh; } Loading