41
46
uint64_t ref_blkno, int ref_recno,
44
uint32_t len, new_i_clusters = *(uint32_t *)priv_data;
49
struct truncate_ctxt *ctxt = (struct truncate_ctxt *)priv_data;
50
uint32_t len = 0, new_size_in_clusters = ctxt->new_size_in_clusters;
45
51
uint64_t start = 0;
53
int func_ret = OCFS2_EXTENT_ERROR;
55
struct ocfs2_extent_list *el = NULL;
48
if ((rec->e_cpos + rec->e_clusters) <= new_i_clusters)
57
if ((rec->e_cpos + ocfs2_rec_clusters(tree_depth, rec)) <=
51
if (rec->e_cpos >= new_i_clusters) {
61
if (rec->e_cpos >= new_size_in_clusters) {
52
62
/* the rec is entirely outside the new size, free it */
54
64
start = rec->e_blkno;
55
len = rec->e_clusters;
65
len = ocfs2_rec_clusters(tree_depth, rec);
57
67
/* here we meet with a full empty extent block, delete
58
68
* it. The extent list it contains should already be
76
memset(rec, 0, sizeof(struct ocfs2_extent_rec));
70
78
/* we're truncating into the middle of the rec */
71
len = rec->e_cpos + rec->e_clusters;
72
len -= new_i_clusters;
73
rec->e_clusters = new_i_clusters - rec->e_cpos;
80
ocfs2_rec_clusters(tree_depth, rec);
81
len -= new_size_in_clusters;
83
ocfs2_set_rec_clusters(tree_depth, rec,
84
new_size_in_clusters - rec->e_cpos);
75
85
start = rec->e_blkno +
76
ocfs2_clusters_to_blocks(fs, rec->e_clusters);
86
ocfs2_clusters_to_blocks(fs,
87
ocfs2_rec_clusters(tree_depth,
90
ocfs2_set_rec_clusters(tree_depth, rec,
91
new_size_in_clusters - rec->e_cpos);
93
* For a sparse file, we may meet with another
95
* The start of the left most extent rec is greater
96
* than the new size we truncate the file to, but the
97
* start of the extent block is less than that size.
98
* In this case, actually all the extent records in
99
* this extent block have been removed. So we have
100
* to remove the extent block also.
101
* In this function, we have to reread the extent list
102
* to see whether the extent block is empty or not.
104
ret = ocfs2_malloc_block(fs->fs_io, &buf);
108
ret = ocfs2_read_extent_block(fs, rec->e_blkno, buf);
112
el = &((struct ocfs2_extent_block *)buf)->h_list;
113
if (el->l_next_free_rec == 0) {
114
ret = ocfs2_delete_extent_block(fs, rec->e_blkno);
117
memset(rec, 0, sizeof(struct ocfs2_extent_rec));
80
123
ret = ocfs2_free_clusters(fs, len, start);
126
ctxt->new_i_clusters -= len;
85
return OCFS2_EXTENT_CHANGED;
129
func_ret = OCFS2_EXTENT_CHANGED;
87
return OCFS2_EXTENT_ERROR;
137
* Zero the area past i_size but still within an allocated
138
* cluster. This avoids exposing nonzero data on subsequent file
141
static errcode_t ocfs2_zero_tail_for_truncate(ocfs2_cached_inode *ci,
146
ocfs2_filesys *fs = ci->ci_fs;
147
uint64_t start_blk, p_blkno, contig_blocks, start_off;
148
int count, byte_counts, bpc = fs->fs_clustersize /fs->fs_blocksize;
153
start_blk = new_size / fs->fs_blocksize;
155
ret = ocfs2_extent_map_get_blocks(ci, start_blk, 1,
156
&p_blkno, &contig_blocks, NULL);
160
/* Tail is a hole. */
164
/* calculate the total blocks we need to empty. */
165
count = bpc - (p_blkno & (bpc - 1));
166
ret = ocfs2_malloc_blocks(fs->fs_io, count, &buf);
170
ret = io_read_block(fs->fs_io, p_blkno, count, buf);
174
/* empty the content after the new_size and within the same cluster. */
175
start_off = new_size % fs->fs_blocksize;
176
byte_counts = count * fs->fs_blocksize - start_off;
177
memset(buf + start_off, 0, byte_counts);
179
ret = io_write_block(fs->fs_io, p_blkno, count, buf);
90
187
/* XXX care about zeroing new clusters and final partially truncated
92
189
errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size)
96
struct ocfs2_dinode *di;
97
uint32_t new_i_clusters;
98
uint64_t new_i_blocks;
100
ret = ocfs2_malloc_block(fs->fs_io, &buf);
104
ret = ocfs2_read_inode(fs, ino, buf);
107
di = (struct ocfs2_dinode *)buf;
109
if (di->i_size == new_i_size)
112
new_i_blocks = ocfs2_blocks_in_bytes(fs, new_i_size);
113
new_i_clusters = ocfs2_clusters_in_blocks(fs, new_i_blocks);
115
if (di->i_clusters < new_i_clusters) {
116
ret = ocfs2_extend_allocation(fs, ino,
117
new_i_clusters - di->i_clusters);
121
/* the information of dinode has been changed, and we need to
124
ret = ocfs2_read_inode(fs, ino, buf);
128
ret = ocfs2_extent_iterate_inode(fs, di,
129
OCFS2_EXTENT_FLAG_DEPTH_TRAVERSE,
130
NULL, truncate_iterate,
192
uint32_t new_clusters;
193
ocfs2_cached_inode *ci = NULL;
195
ret = ocfs2_read_cached_inode(fs, ino, &ci);
199
if (ci->ci_inode->i_size == new_i_size)
202
if (ci->ci_inode->i_size < new_i_size)
203
ret = ocfs2_extend_file(fs, ino, new_i_size);
205
ret = ocfs2_zero_tail_and_truncate(fs, ci, new_i_size,
210
ci->ci_inode->i_clusters = new_clusters;
135
212
/* now all the clusters and extent blocks are freed.
136
213
* only when the file's content is empty, should the tree depth
139
if (new_i_clusters == 0)
140
di->id2.i_list.l_tree_depth = 0;
216
if (new_clusters == 0)
217
ci->ci_inode->id2.i_list.l_tree_depth = 0;
219
ci->ci_inode->i_size = new_i_size;
220
ret = ocfs2_write_cached_inode(fs, ci);
144
di->i_clusters = new_i_clusters;
145
di->i_size = new_i_size;
146
ret = ocfs2_write_inode(fs, ino, buf);
224
ocfs2_free_cached_inode(fs, ci);
229
* This fucntion will truncate the file's cluster which exceeds
230
* the cluster where new_size resides in and empty all the
231
* bytes in the same cluster which exceeds new_size.
233
errcode_t ocfs2_zero_tail_and_truncate(ocfs2_filesys *fs,
234
ocfs2_cached_inode *ci,
236
uint32_t *new_clusters)
239
uint64_t new_size_in_blocks;
240
struct truncate_ctxt ctxt;
242
new_size_in_blocks = ocfs2_blocks_in_bytes(fs, new_i_size);
243
ctxt.new_i_clusters = ci->ci_inode->i_clusters;
244
ctxt.new_size_in_clusters =
245
ocfs2_clusters_in_blocks(fs, new_size_in_blocks);
247
ret = ocfs2_extent_iterate_inode(fs, ci->ci_inode,
248
OCFS2_EXTENT_FLAG_DEPTH_TRAVERSE,
249
NULL, truncate_iterate,
254
ret = ocfs2_zero_tail_for_truncate(ci, new_i_size);
259
*new_clusters = ctxt.new_i_clusters;