~daniel-mehrmann/e2fsprogs/master

« back to all changes in this revision

Viewing changes to lib/ext2fs/extent.c

  • Committer: Package Import Robot
  • Author(s): Michael Vogt
  • Date: 2014-10-27 09:44:27 UTC
  • mfrom: (8.4.29 sid)
  • Revision ID: package-import@ubuntu.com-20141027094427-g56dce6sg7pasdgm
Tags: 1.42.12-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - debian/rules:
      Block pkg-create-dbgsym from operating on this package.
      Build without dietlibc-dev, which is in universe 
      Use the autotools-dev dh addon to update config.guess/config.sub for new
      ports.
  - debian/control:
      Regenerate with ./debian/rules debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "ext2fsP.h"
30
30
#include "e2image.h"
31
31
 
 
32
#undef DEBUG
 
33
 
32
34
/*
33
35
 * Definitions to be dropped in lib/ext2fs/ext2fs.h
34
36
 */
121
123
 
122
124
}
123
125
 
 
126
static void dump_path(const char *tag, struct ext2_extent_handle *handle,
 
127
                      struct extent_path *path)
 
128
{
 
129
        struct extent_path *ppp = path;
 
130
        printf("%s: level=%d\n", tag, handle->level);
 
131
 
 
132
        do {
 
133
                printf("%s: path=%ld buf=%p entries=%d max_entries=%d left=%d "
 
134
                       "visit_num=%d flags=0x%x end_blk=%llu curr=%p(%ld)\n",
 
135
                       tag, (ppp - handle->path), ppp->buf, ppp->entries,
 
136
                       ppp->max_entries, ppp->left, ppp->visit_num, ppp->flags,
 
137
                       ppp->end_blk, ppp->curr, ppp->curr - (void *)ppp->buf);
 
138
                printf("  ");
 
139
                dbg_show_header((struct ext3_extent_header *)ppp->buf);
 
140
                if (ppp->curr) {
 
141
                        printf("  ");
 
142
                        dbg_show_index(ppp->curr);
 
143
                        printf("  ");
 
144
                        dbg_show_extent(ppp->curr);
 
145
                }
 
146
                ppp--;
 
147
        } while (ppp >= handle->path);
 
148
        fflush(stdout);
 
149
 
 
150
        return;
 
151
}
 
152
 
124
153
#else
125
154
#define dbg_show_header(eh) do { } while (0)
126
155
#define dbg_show_index(ix) do { } while (0)
127
156
#define dbg_show_extent(ex) do { } while (0)
128
157
#define dbg_print_extent(desc, ex) do { } while (0)
 
158
#define dump_path(tag, handle, path) do { } while (0)
129
159
#endif
130
160
 
131
161
/*
814
844
        return 0;
815
845
}
816
846
 
 
847
static int splitting_at_eof(struct ext2_extent_handle *handle,
 
848
                            struct extent_path *path)
 
849
{
 
850
        struct extent_path *ppp = path;
 
851
        dump_path(__func__, handle, path);
 
852
 
 
853
        if (handle->level == 0)
 
854
                return 0;
 
855
 
 
856
        do {
 
857
                if (ppp->left)
 
858
                        return 0;
 
859
                ppp--;
 
860
        } while (ppp >= handle->path);
 
861
 
 
862
        return 1;
 
863
}
 
864
 
817
865
/*
818
866
 * allocate a new block, move half the current node to it, and update parent
819
867
 *
820
868
 * handle will be left pointing at original record.
821
869
 */
822
 
errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle)
 
870
static errcode_t extent_node_split(ext2_extent_handle_t handle,
 
871
                                   int expand_allowed)
823
872
{
824
873
        errcode_t                       retval = 0;
825
874
        blk64_t                         new_node_pblk;
834
883
        int                             tocopy;
835
884
        int                             new_root = 0;
836
885
        struct ext2_extent_info         info;
 
886
        int                             no_balance;
837
887
 
838
888
        /* basic sanity */
839
889
        EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
874
924
                        goto done;
875
925
                goal_blk = extent.e_pblk;
876
926
 
877
 
                retval = ext2fs_extent_node_split(handle);
 
927
                retval = extent_node_split(handle, expand_allowed);
878
928
                if (retval)
879
929
                        goto done;
880
930
 
889
939
        if (!path->curr)
890
940
                return EXT2_ET_NO_CURRENT_NODE;
891
941
 
 
942
        /*
 
943
         * Normally, we try to split a full node in half.  This doesn't turn
 
944
         * out so well if we're tacking extents on the end of the file because
 
945
         * then we're stuck with a tree of half-full extent blocks.  This of
 
946
         * course doesn't apply to the root level.
 
947
         */
 
948
        no_balance = expand_allowed ? splitting_at_eof(handle, path) : 0;
 
949
 
892
950
        /* extent header of the current node we'll split */
893
951
        eh = (struct ext3_extent_header *)path->buf;
894
952
 
904
962
                memset(newpath, 0,
905
963
                       ((handle->max_depth+2) * sizeof(struct extent_path)));
906
964
        } else {
907
 
                tocopy = ext2fs_le16_to_cpu(eh->eh_entries) / 2;
 
965
                if (no_balance)
 
966
                        tocopy = 1;
 
967
                else
 
968
                        tocopy = ext2fs_le16_to_cpu(eh->eh_entries) / 2;
908
969
        }
909
970
 
910
971
#ifdef DEBUG
913
974
                                handle->level);
914
975
#endif
915
976
 
916
 
        if (!tocopy) {
 
977
        if (!tocopy && !no_balance) {
917
978
#ifdef DEBUG
918
979
                printf("Nothing to copy to new block!\n");
919
980
#endif
1032
1093
                goto done;
1033
1094
 
1034
1095
        /* new node hooked in, so update inode block count (do this here?) */
1035
 
        handle->inode->i_blocks += (handle->fs->blocksize *
1036
 
                                    EXT2FS_CLUSTER_RATIO(handle->fs)) / 512;
 
1096
        ext2fs_iblk_add_blocks(handle->fs, handle->inode, 1);
1037
1097
        retval = ext2fs_write_inode(handle->fs, handle->ino,
1038
1098
                                    handle->inode);
1039
1099
        if (retval)
1047
1107
        return retval;
1048
1108
}
1049
1109
 
 
1110
errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle)
 
1111
{
 
1112
        return extent_node_split(handle, 0);
 
1113
}
 
1114
 
1050
1115
errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
1051
1116
                                      struct ext2fs_extent *extent)
1052
1117
{
1078
1143
                        printf("node full (level %d) - splitting\n",
1079
1144
                                   handle->level);
1080
1145
#endif
1081
 
                        retval = ext2fs_extent_node_split(handle);
 
1146
                        retval = extent_node_split(handle, 1);
1082
1147
                        if (retval)
1083
1148
                                return retval;
1084
1149
                        path = handle->path + handle->level;