580
/* A dirblock we have to add a trailer to */
581
struct tunefs_trailer_dirblock {
582
struct list_head db_list;
587
* These require a little explanation. They point to
588
* ocfs2_dir_entry structures inside db_buf.
590
* db_last is the entry we're going to *keep*. If the last
591
* entry in the dirblock has enough extra rec_len to allow the
592
* trailer, db_last points to it. We will shorten its rec_len
593
* and insert the trailer.
595
* However, if the last entry in the dirblock cannot be
596
* truncated, db_last points to the entry before that - the
597
* last entry we're keeping in this dirblock.
601
* - The last entry in the dirblock has a name_len of 1 and a
602
* rec_len of 128. We can easily change the rec_len to 64 and
603
* insert the trailer. db_last points to this entry.
605
* - The last entry in the dirblock has a name_len of 1 and a
606
* rec_len of 48. The previous entry has a name_len of 1 and a
607
* rec_len of 32. We have to move the last entry out. The
608
* second-to-last entry can have its rec_len truncated to 16, so
609
* we put it in db_last.
611
struct ocfs2_dir_entry *db_last;
614
void tunefs_trailer_context_free(struct tunefs_trailer_context *tc)
616
struct tunefs_trailer_dirblock *db;
617
struct list_head *n, *pos;
619
if (!list_empty(&tc->d_list))
620
list_del(&tc->d_list);
622
list_for_each_safe(pos, n, &tc->d_dirblocks) {
623
db = list_entry(pos, struct tunefs_trailer_dirblock, db_list);
624
list_del(&db->db_list);
625
ocfs2_free(&db->db_buf);
633
* We're calculating how many bytes we need to add to make space for
634
* the dir trailers. But we need to make sure that the added directory
635
* blocks also have room for a trailer.
637
static void add_bytes_needed(ocfs2_filesys *fs,
638
struct tunefs_trailer_context *tc,
639
unsigned int rec_len)
641
unsigned int toff = ocfs2_dir_trailer_blk_off(fs);
642
unsigned int block_offset = tc->d_bytes_needed % fs->fs_blocksize;
645
* If the current byte offset would put us into a trailer, push
646
* it out to the start of the next block. Remember, dirents have
647
* to be at least 16 bytes, which is why we check against the
650
if ((block_offset + rec_len) > (toff - OCFS2_DIR_REC_LEN(1)))
651
tc->d_bytes_needed += fs->fs_blocksize - block_offset;
653
tc->d_bytes_needed += rec_len;
654
tc->d_blocks_needed =
655
ocfs2_blocks_in_bytes(fs, tc->d_bytes_needed);
658
static errcode_t walk_dirblock(ocfs2_filesys *fs,
659
struct tunefs_trailer_context *tc,
660
struct tunefs_trailer_dirblock *db)
663
struct ocfs2_dir_entry *dirent, *prev = NULL;
664
unsigned int real_rec_len;
665
unsigned int offset = 0;
666
unsigned int toff = ocfs2_dir_trailer_blk_off(fs);
668
while (offset < fs->fs_blocksize) {
669
dirent = (struct ocfs2_dir_entry *) (db->db_buf + offset);
670
if (((offset + dirent->rec_len) > fs->fs_blocksize) ||
671
(dirent->rec_len < 8) ||
672
((dirent->rec_len % 4) != 0) ||
673
(((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
674
ret = OCFS2_ET_DIR_CORRUPTED;
678
real_rec_len = dirent->inode ?
679
OCFS2_DIR_REC_LEN(dirent->name_len) :
680
OCFS2_DIR_REC_LEN(1);
681
if ((offset + real_rec_len) <= toff)
685
* The first time through, we store off the last dirent
686
* before the trailer.
691
/* Only live dirents need to be moved */
694
"Will move dirent %.*s out of "
695
"directory block %"PRIu64" to make way "
697
dirent->name_len, dirent->name,
699
add_bytes_needed(fs, tc, real_rec_len);
704
offset += dirent->rec_len;
707
/* There were no dirents across the boundary */
714
static int dirblock_scan_iterate(ocfs2_filesys *fs, uint64_t blkno,
715
uint64_t bcount, uint16_t ext_flags,
719
struct tunefs_trailer_dirblock *db = NULL;
720
struct tunefs_trailer_context *tc = priv_data;
722
ret = ocfs2_malloc0(sizeof(struct tunefs_trailer_dirblock), &db);
726
ret = ocfs2_malloc_block(fs->fs_io, &db->db_buf);
730
db->db_blkno = blkno;
733
"Reading dinode %"PRIu64" dirblock %"PRIu64" at block "
735
tc->d_di->i_blkno, bcount, blkno);
736
ret = ocfs2_read_dir_block(fs, tc->d_di, blkno, db->db_buf);
740
ret = walk_dirblock(fs, tc, db);
744
list_add_tail(&db->db_list, &tc->d_dirblocks);
750
ocfs2_free(&db->db_buf);
756
return OCFS2_BLOCK_ABORT;
762
errcode_t tunefs_prepare_dir_trailer(ocfs2_filesys *fs,
763
struct ocfs2_dinode *di,
764
struct tunefs_trailer_context **tc_ret)
767
struct tunefs_trailer_context *tc = NULL;
769
if (ocfs2_dir_has_trailer(fs, di))
772
ret = ocfs2_malloc0(sizeof(struct tunefs_trailer_context), &tc);
776
tc->d_blkno = di->i_blkno;
778
INIT_LIST_HEAD(&tc->d_list);
779
INIT_LIST_HEAD(&tc->d_dirblocks);
781
ret = ocfs2_block_iterate_inode(fs, tc->d_di, 0,
782
dirblock_scan_iterate, tc);
793
tunefs_trailer_context_free(tc);
799
* We are hand-coding the directory expansion because we're going to
800
* build the new directory blocks ourselves. We can't just use
801
* ocfs2_expand_dir() and ocfs2_link(), because we're moving around
804
static errcode_t expand_dir_if_needed(ocfs2_filesys *fs,
805
struct ocfs2_dinode *di,
806
uint64_t blocks_needed)
809
uint64_t used_blocks, total_blocks;
810
uint32_t clusters_needed;
812
/* This relies on the fact that i_size of a directory is a
813
* multiple of blocksize */
814
used_blocks = ocfs2_blocks_in_bytes(fs, di->i_size);
815
total_blocks = ocfs2_clusters_to_blocks(fs, di->i_clusters);
816
if ((used_blocks + blocks_needed) <= total_blocks)
820
ocfs2_clusters_in_blocks(fs,
821
(used_blocks + blocks_needed) -
823
ret = ocfs2_extend_allocation(fs, di->i_blkno, clusters_needed);
827
/* Pick up changes to the inode */
828
ret = ocfs2_read_inode(fs, di->i_blkno, (char *)di);
834
static void shift_dirent(ocfs2_filesys *fs,
835
struct tunefs_trailer_context *tc,
836
struct ocfs2_dir_entry *dirent)
838
/* Using the real rec_len */
839
unsigned int rec_len = OCFS2_DIR_REC_LEN(dirent->name_len);
840
unsigned int offset, remain;
843
* If the current byte offset would put us into a trailer, push
844
* it out to the start of the next block. Remember, dirents have
845
* to be at least 16 bytes, which is why we check against the
848
if (rec_len > (tc->d_next_dirent->rec_len - OCFS2_DIR_REC_LEN(1))) {
849
tc->d_cur_block += fs->fs_blocksize;
850
tc->d_next_dirent = (struct ocfs2_dir_entry *)tc->d_cur_block;
853
assert(ocfs2_blocks_in_bytes(fs,
854
tc->d_cur_block - tc->d_new_blocks) <
855
tc->d_blocks_needed);
857
offset = (char *)(tc->d_next_dirent) - tc->d_cur_block;
858
remain = tc->d_next_dirent->rec_len - rec_len;
860
memcpy(tc->d_cur_block + offset, dirent, rec_len);
861
tc->d_next_dirent->rec_len = rec_len;
864
"Installed dirent %.*s at offset %u of new block "
865
"%"PRIu64", rec_len %u\n",
866
tc->d_next_dirent->name_len, tc->d_next_dirent->name,
868
ocfs2_blocks_in_bytes(fs, tc->d_cur_block - tc->d_new_blocks),
874
(struct ocfs2_dir_entry *)(tc->d_cur_block + offset);
875
tc->d_next_dirent->rec_len = remain;
878
"New block %"PRIu64" has its last dirent at %u, with %u "
880
ocfs2_blocks_in_bytes(fs, tc->d_cur_block - tc->d_new_blocks),
884
static errcode_t fixup_dirblock(ocfs2_filesys *fs,
885
struct tunefs_trailer_context *tc,
886
struct tunefs_trailer_dirblock *db)
889
struct ocfs2_dir_entry *dirent;
890
unsigned int real_rec_len;
892
unsigned int toff = ocfs2_dir_trailer_blk_off(fs);
895
* db_last is the last dirent we're *keeping*. So we need to
896
* move out every valid dirent *after* db_last.
898
* tunefs_prepare_dir_trailer() should have calculated this
901
offset = ((char *)db->db_last) - db->db_buf;
902
offset += db->db_last->rec_len;
903
while (offset < fs->fs_blocksize) {
904
dirent = (struct ocfs2_dir_entry *) (db->db_buf + offset);
905
if (((offset + dirent->rec_len) > fs->fs_blocksize) ||
906
(dirent->rec_len < 8) ||
907
((dirent->rec_len % 4) != 0) ||
908
(((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
909
ret = OCFS2_ET_DIR_CORRUPTED;
913
real_rec_len = dirent->inode ?
914
OCFS2_DIR_REC_LEN(dirent->name_len) :
915
OCFS2_DIR_REC_LEN(1);
917
assert((offset + real_rec_len) > toff);
919
/* Only live dirents need to be moved */
922
"Moving dirent %.*s out of directory "
923
"block %"PRIu64" to make way for the "
925
dirent->name_len, dirent->name,
927
shift_dirent(fs, tc, dirent);
930
offset += dirent->rec_len;
934
* Now that we've moved any dirents out of the way, we need to
935
* fix up db_last and install the trailer.
937
offset = ((char *)db->db_last) - db->db_buf;
939
"Last valid dirent of directory block %"PRIu64" "
940
"(\"%.*s\") is %u bytes in. Setting rec_len to %u and "
941
"installing the trailer\n",
942
db->db_blkno, db->db_last->name_len, db->db_last->name,
943
offset, toff - offset);
944
db->db_last->rec_len = toff - offset;
945
ocfs2_init_dir_trailer(fs, tc->d_di, db->db_blkno, db->db_buf);
950
static errcode_t run_dirblocks(ocfs2_filesys *fs,
951
struct tunefs_trailer_context *tc)
954
struct list_head *pos;
955
struct tunefs_trailer_dirblock *db;
957
list_for_each(pos, &tc->d_dirblocks) {
958
db = list_entry(pos, struct tunefs_trailer_dirblock, db_list);
959
ret = fixup_dirblock(fs, tc, db);
967
static errcode_t write_dirblocks(ocfs2_filesys *fs,
968
struct tunefs_trailer_context *tc)
971
struct list_head *pos;
972
struct tunefs_trailer_dirblock *db;
974
list_for_each(pos, &tc->d_dirblocks) {
975
db = list_entry(pos, struct tunefs_trailer_dirblock, db_list);
976
ret = ocfs2_write_dir_block(fs, tc->d_di, db->db_blkno,
980
"Error writing dirblock %"PRIu64"\n",
989
static errcode_t init_new_dirblocks(ocfs2_filesys *fs,
990
struct tunefs_trailer_context *tc)
995
uint64_t orig_block = ocfs2_blocks_in_bytes(fs, tc->d_di->i_size);
996
ocfs2_cached_inode *cinode;
998
struct ocfs2_dir_entry *first;
1000
ret = ocfs2_read_cached_inode(fs, tc->d_blkno, &cinode);
1003
assert(!memcmp(tc->d_di, cinode->ci_inode, fs->fs_blocksize));
1005
for (i = 0; i < tc->d_blocks_needed; i++) {
1006
ret = ocfs2_extent_map_get_blocks(cinode, orig_block + i,
1007
1, &blkno, NULL, NULL);
1010
blockptr = tc->d_new_blocks + (i * fs->fs_blocksize);
1011
memset(blockptr, 0, fs->fs_blocksize);
1012
first = (struct ocfs2_dir_entry *)blockptr;
1013
first->rec_len = ocfs2_dir_trailer_blk_off(fs);
1014
ocfs2_init_dir_trailer(fs, tc->d_di, blkno, blockptr);
1021
static errcode_t write_new_dirblocks(ocfs2_filesys *fs,
1022
struct tunefs_trailer_context *tc)
1027
uint64_t orig_block = ocfs2_blocks_in_bytes(fs, tc->d_di->i_size);
1028
ocfs2_cached_inode *cinode;
1031
ret = ocfs2_read_cached_inode(fs, tc->d_blkno, &cinode);
1034
assert(!memcmp(tc->d_di, cinode->ci_inode, fs->fs_blocksize));
1036
for (i = 0; i < tc->d_blocks_needed; i++) {
1037
ret = ocfs2_extent_map_get_blocks(cinode, orig_block + i,
1038
1, &blkno, NULL, NULL);
1041
blockptr = tc->d_new_blocks + (i * fs->fs_blocksize);
1042
ret = ocfs2_write_dir_block(fs, tc->d_di, blkno, blockptr);
1045
"Error writing dirblock %"PRIu64"\n",
1055
errcode_t tunefs_install_dir_trailer(ocfs2_filesys *fs,
1056
struct ocfs2_dinode *di,
1057
struct tunefs_trailer_context *tc)
1060
struct tunefs_trailer_context *our_tc = NULL;
1063
ret = tunefs_prepare_dir_trailer(fs, di, &our_tc);
1069
if (tc->d_di != di) {
1070
ret = OCFS2_ET_INVALID_ARGUMENT;
1074
if (tc->d_blocks_needed) {
1075
ret = ocfs2_malloc_blocks(fs->fs_io, tc->d_blocks_needed,
1080
tc->d_cur_block = tc->d_new_blocks;
1082
ret = expand_dir_if_needed(fs, di, tc->d_blocks_needed);
1086
ret = init_new_dirblocks(fs, tc);
1089
tc->d_next_dirent = (struct ocfs2_dir_entry *)tc->d_cur_block;
1090
verbosef(VL_DEBUG, "t_next_dirent has rec_len of %u\n",
1091
tc->d_next_dirent->rec_len);
1094
ret = run_dirblocks(fs, tc);
1099
* We write in a specific order. We write any new dirblocks first
1100
* so that they are on disk. Then we write the new i_size in the
1101
* inode. If we crash at this point, the directory has duplicate
1102
* entries but no lost entries. fsck can clean it up. Finally, we
1103
* write the modified dirblocks with trailers.
1105
if (tc->d_blocks_needed) {
1106
ret = write_new_dirblocks(fs, tc);
1110
di->i_size += ocfs2_blocks_to_bytes(fs, tc->d_blocks_needed);
1111
ret = ocfs2_write_inode(fs, di->i_blkno, (char *)di);
1116
ret = write_dirblocks(fs, tc);
1120
tunefs_trailer_context_free(our_tc);
582
1125
* Starting, opening, closing, and exiting.