4 * Many parts of codes are copied from Linux kernel/fs/f2fs.
6 * Copyright (C) 2015 Huawei Ltd.
8 * Hou Pengyang <houpengyang@huawei.com>
9 * Liu Shuoran <liushuoran@huawei.com>
10 * Jaegeuk Kim <jaegeuk@kernel.org>
11 * Copyright (c) 2020 Google Inc.
12 * Robin Hsu <robinhsu@google.com>
13 * : add sload compression support
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
23 int reserve_new_block(struct f2fs_sb_info *sbi, block_t *to,
24 struct f2fs_summary *sum, int type, bool is_inode)
26 struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
29 u64 old_blkaddr = *to;
30 bool is_node = IS_NODESEG(type);
33 if (old_blkaddr == NULL_ADDR) {
35 if (fsck->chk.valid_blk_cnt >= sbi->user_block_count) {
36 ERR_MSG("Not enough space\n");
39 if (is_node && fsck->chk.valid_node_cnt >=
40 sbi->total_valid_node_count) {
41 ERR_MSG("Not enough space for node block\n");
45 if (sbi->total_valid_block_count >=
46 sbi->user_block_count) {
47 ERR_MSG("Not enough space\n");
50 if (is_node && sbi->total_valid_node_count >=
51 sbi->total_node_count) {
52 ERR_MSG("Not enough space for node block\n");
58 blkaddr = SM_I(sbi)->main_blkaddr;
60 if (sbi->raw_super->feature & cpu_to_le32(F2FS_FEATURE_RO)) {
61 if (IS_NODESEG(type)) {
62 type = CURSEG_HOT_NODE;
63 blkaddr = __end_block_addr(sbi);
65 } else if (IS_DATASEG(type)) {
66 type = CURSEG_HOT_DATA;
67 blkaddr = SM_I(sbi)->main_blkaddr;
72 if (find_next_free_block(sbi, &blkaddr, left, type, false)) {
73 ERR_MSG("Can't find free block");
77 se = get_seg_entry(sbi, GET_SEGNO(sbi, blkaddr));
78 offset = OFFSET_IN_SEG(sbi, blkaddr);
81 f2fs_set_bit(offset, (char *)se->cur_valid_map);
82 if (need_fsync_data_record(sbi)) {
84 se->ckpt_valid_blocks++;
85 f2fs_set_bit(offset, (char *)se->ckpt_valid_map);
88 f2fs_set_main_bitmap(sbi, blkaddr, type);
89 f2fs_set_sit_bitmap(sbi, blkaddr);
92 if (old_blkaddr == NULL_ADDR) {
93 sbi->total_valid_block_count++;
95 sbi->total_valid_node_count++;
97 sbi->total_valid_inode_count++;
100 fsck->chk.valid_blk_cnt++;
102 fsck->chk.valid_node_cnt++;
104 fsck->chk.valid_inode_cnt++;
111 *to = (block_t)blkaddr;
112 update_sum_entry(sbi, *to, sum);
117 int new_data_block(struct f2fs_sb_info *sbi, void *block,
118 struct dnode_of_data *dn, int type)
120 struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
121 struct f2fs_summary sum;
123 unsigned int blkaddr = datablock_addr(dn->node_blk, dn->ofs_in_node);
126 if ((get_sb(feature) & cpu_to_le32(F2FS_FEATURE_RO)) &&
127 type != CURSEG_HOT_DATA)
128 type = CURSEG_HOT_DATA;
130 ASSERT(dn->node_blk);
131 memset(block, 0, BLOCK_SZ);
133 get_node_info(sbi, dn->nid, &ni);
134 set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
136 dn->data_blkaddr = blkaddr;
137 ret = reserve_new_block(sbi, &dn->data_blkaddr, &sum, type, 0);
143 if (blkaddr == NULL_ADDR)
144 inc_inode_blocks(dn);
145 else if (blkaddr == NEW_ADDR)
147 set_data_blkaddr(dn);
151 u64 f2fs_quota_size(struct quota_file *qf)
154 struct f2fs_node *inode;
157 inode = (struct f2fs_node *) calloc(BLOCK_SZ, 1);
161 get_node_info(qf->sbi, qf->ino, &ni);
162 ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
163 ASSERT(S_ISREG(le16_to_cpu(inode->i.i_mode)));
165 filesize = le64_to_cpu(inode->i.i_size);
170 u64 f2fs_read(struct f2fs_sb_info *sbi, nid_t ino, u8 *buffer,
171 u64 count, pgoff_t offset)
173 struct dnode_of_data dn;
175 struct f2fs_node *inode;
181 u64 remained_blkentries;
183 void *index_node = NULL;
185 memset(&dn, 0, sizeof(dn));
187 /* Memory allocation for block buffer and inode. */
188 blk_buffer = calloc(BLOCK_SZ, 2);
190 inode = (struct f2fs_node*)(blk_buffer + BLOCK_SZ);
193 get_node_info(sbi, ino, &ni);
194 ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
195 ASSERT(!S_ISDIR(le16_to_cpu(inode->i.i_mode)));
196 ASSERT(!S_ISLNK(le16_to_cpu(inode->i.i_mode)));
198 /* Adjust count with file length. */
199 filesize = le64_to_cpu(inode->i.i_size);
200 if (offset > filesize)
202 else if (count + offset > filesize)
203 count = filesize - offset;
205 /* Main loop for file blocks */
206 read_count = remained_blkentries = 0;
208 if (remained_blkentries == 0) {
209 set_new_dnode(&dn, inode, NULL, ino);
210 get_dnode_of_data(sbi, &dn, F2FS_BYTES_TO_BLK(offset),
214 index_node = (dn.node_blk == dn.inode_blk) ?
216 remained_blkentries = ADDRS_PER_PAGE(sbi,
217 dn.node_blk, dn.inode_blk);
219 ASSERT(remained_blkentries > 0);
221 blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node);
222 if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR)
225 off_in_blk = offset % BLOCK_SZ;
226 len_in_blk = BLOCK_SZ - off_in_blk;
227 if (len_in_blk > count)
230 /* Read data from single block. */
231 if (len_in_blk < BLOCK_SZ) {
232 ASSERT(dev_read_block(blk_buffer, blkaddr) >= 0);
233 memcpy(buffer, blk_buffer + off_in_blk, len_in_blk);
236 ASSERT(dev_read_block(buffer, blkaddr) >= 0);
239 offset += len_in_blk;
241 buffer += len_in_blk;
242 read_count += len_in_blk;
245 remained_blkentries--;
255 * Do not call this function directly. Instead, call one of the following:
257 * u64 f2fs_write_compress_data();
258 * u64 f2fs_write_addrtag();
260 static u64 f2fs_write_ex(struct f2fs_sb_info *sbi, nid_t ino, u8 *buffer,
261 u64 count, pgoff_t offset, enum wr_addr_type addr_type)
263 struct dnode_of_data dn;
265 struct f2fs_node *inode;
270 u64 remained_blkentries;
272 void* index_node = NULL;
275 bool has_data = (addr_type == WR_NORMAL
276 || addr_type == WR_COMPRESS_DATA);
282 * Enforce calling from f2fs_write(), f2fs_write_compress_data(),
283 * and f2fs_write_addrtag(). Beside, check if is properly called.
285 ASSERT((!has_data && buffer == NULL) || (has_data && buffer != NULL));
286 if (addr_type != WR_NORMAL)
287 ASSERT(offset % F2FS_BLKSIZE == 0); /* block boundary only */
289 /* Memory allocation for block buffer and inode. */
290 blk_buffer = calloc(BLOCK_SZ, 2);
292 inode = (struct f2fs_node*)(blk_buffer + BLOCK_SZ);
295 get_node_info(sbi, ino, &ni);
296 ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
297 ASSERT(!S_ISDIR(le16_to_cpu(inode->i.i_mode)));
298 ASSERT(!S_ISLNK(le16_to_cpu(inode->i.i_mode)));
300 /* Main loop for file blocks */
301 written_count = remained_blkentries = 0;
303 if (remained_blkentries == 0) {
304 set_new_dnode(&dn, inode, NULL, ino);
305 err = get_dnode_of_data(sbi, &dn,
306 F2FS_BYTES_TO_BLK(offset), ALLOC_NODE);
311 index_node = (dn.node_blk == dn.inode_blk) ?
313 remained_blkentries = ADDRS_PER_PAGE(sbi,
314 dn.node_blk, dn.inode_blk) -
317 ASSERT(remained_blkentries > 0);
320 dn.data_blkaddr = addr_type;
321 set_data_blkaddr(&dn);
324 ASSERT(dev_write_block(dn.node_blk,
325 dn.node_blkaddr) >= 0);
330 blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node);
331 if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) {
332 err = new_data_block(sbi, blk_buffer,
333 &dn, CURSEG_WARM_DATA);
336 blkaddr = dn.data_blkaddr;
340 off_in_blk = offset % BLOCK_SZ;
341 len_in_blk = BLOCK_SZ - off_in_blk;
342 if (len_in_blk > count)
345 /* Write data to single block. */
346 if (len_in_blk < BLOCK_SZ) {
347 ASSERT(dev_read_block(blk_buffer, blkaddr) >= 0);
348 memcpy(blk_buffer + off_in_blk, buffer, len_in_blk);
349 ASSERT(dev_write_block(blk_buffer, blkaddr) >= 0);
352 ASSERT(dev_write_block(buffer, blkaddr) >= 0);
355 offset += len_in_blk;
357 buffer += len_in_blk;
358 written_count += len_in_blk;
361 if ((--remained_blkentries == 0 || count == 0) && (dn.ndirty))
362 ASSERT(dev_write_block(dn.node_blk, dn.node_blkaddr)
365 if (addr_type == WR_NORMAL && offset > le64_to_cpu(inode->i.i_size)) {
366 inode->i.i_size = cpu_to_le64(offset);
370 ASSERT(inode == dn.inode_blk);
371 ASSERT(write_inode(inode, ni.blk_addr) >= 0);
377 return written_count;
380 u64 f2fs_write(struct f2fs_sb_info *sbi, nid_t ino, u8 *buffer,
381 u64 count, pgoff_t offset)
383 return f2fs_write_ex(sbi, ino, buffer, count, offset, WR_NORMAL);
386 u64 f2fs_write_compress_data(struct f2fs_sb_info *sbi, nid_t ino, u8 *buffer,
387 u64 count, pgoff_t offset)
389 return f2fs_write_ex(sbi, ino, buffer, count, offset, WR_COMPRESS_DATA);
392 u64 f2fs_write_addrtag(struct f2fs_sb_info *sbi, nid_t ino, pgoff_t offset,
393 unsigned int addrtag)
395 ASSERT(addrtag == COMPRESS_ADDR || addrtag == NEW_ADDR
396 || addrtag == NULL_ADDR);
397 return f2fs_write_ex(sbi, ino, NULL, F2FS_BLKSIZE, offset, addrtag);
400 /* This function updates only inode->i.i_size */
401 void f2fs_filesize_update(struct f2fs_sb_info *sbi, nid_t ino, u64 filesize)
404 struct f2fs_node *inode;
406 inode = calloc(BLOCK_SZ, 1);
408 get_node_info(sbi, ino, &ni);
410 ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
411 ASSERT(!S_ISDIR(le16_to_cpu(inode->i.i_mode)));
412 ASSERT(!S_ISLNK(le16_to_cpu(inode->i.i_mode)));
414 inode->i.i_size = cpu_to_le64(filesize);
416 ASSERT(write_inode(inode, ni.blk_addr) >= 0);
420 #define MAX_BULKR_RETRY 5
421 int bulkread(int fd, void *rbuf, size_t rsize, bool *eof)
424 int retry = MAX_BULKR_RETRY;
432 while (rsize && (cur = read(fd, rbuf, rsize)) != 0) {
434 if (errno == EINTR && retry--)
438 retry = MAX_BULKR_RETRY;
448 u64 f2fs_fix_mutable(struct f2fs_sb_info *sbi, nid_t ino, pgoff_t offset,
449 unsigned int compressed)
454 if (c.compress.readonly)
457 for (i = 0; i < compressed - 1; i++) {
458 wlen = f2fs_write_addrtag(sbi, ino,
459 offset + (i << F2FS_BLKSIZE_BITS), NEW_ADDR);
466 static inline int is_consecutive(u32 prev_addr, u32 cur_addr)
468 if (is_valid_data_blkaddr(cur_addr) && (cur_addr == prev_addr + 1))
473 static inline void copy_extent_info(struct extent_info *t_ext,
474 struct extent_info *s_ext)
476 t_ext->fofs = s_ext->fofs;
477 t_ext->blk = s_ext->blk;
478 t_ext->len = s_ext->len;
481 static inline void update_extent_info(struct f2fs_node *inode,
482 struct extent_info *ext)
484 inode->i.i_ext.fofs = cpu_to_le32(ext->fofs);
485 inode->i.i_ext.blk_addr = cpu_to_le32(ext->blk);
486 inode->i.i_ext.len = cpu_to_le32(ext->len);
489 static void update_largest_extent(struct f2fs_sb_info *sbi, nid_t ino)
491 struct dnode_of_data dn;
493 struct f2fs_node *inode;
494 u32 blkaddr, prev_blkaddr, cur_blk = 0, end_blk;
495 struct extent_info largest_ext, cur_ext;
496 u64 remained_blkentries = 0;
499 void *index_node = NULL;
501 memset(&dn, 0, sizeof(dn));
502 largest_ext.len = cur_ext.len = 0;
504 inode = (struct f2fs_node *) calloc(BLOCK_SZ, 1);
507 /* Read inode info */
508 get_node_info(sbi, ino, &ni);
509 ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
510 cluster_size = 1 << inode->i.i_log_cluster_size;
512 if (inode->i.i_inline & F2FS_INLINE_DATA)
515 end_blk = f2fs_max_file_offset(&inode->i) >> F2FS_BLKSIZE_BITS;
517 while (cur_blk <= end_blk) {
518 if (remained_blkentries == 0) {
519 set_new_dnode(&dn, inode, NULL, ino);
520 get_dnode_of_data(sbi, &dn, cur_blk, LOOKUP_NODE);
523 index_node = (dn.node_blk == dn.inode_blk) ?
525 remained_blkentries = ADDRS_PER_PAGE(sbi,
526 dn.node_blk, dn.inode_blk);
528 ASSERT(remained_blkentries > 0);
530 blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node);
531 if (cur_ext.len > 0) {
532 if (is_consecutive(prev_blkaddr, blkaddr))
535 if (cur_ext.len > largest_ext.len)
536 copy_extent_info(&largest_ext,
542 if (cur_ext.len == 0 && is_valid_data_blkaddr(blkaddr)) {
543 cur_ext.fofs = cur_blk;
545 cur_ext.blk = blkaddr;
548 prev_blkaddr = blkaddr;
549 count = blkaddr == COMPRESS_ADDR ? cluster_size : 1;
551 dn.ofs_in_node += count;
552 remained_blkentries -= count;
556 if (cur_ext.len > largest_ext.len)
557 copy_extent_info(&largest_ext, &cur_ext);
558 if (largest_ext.len > 0) {
559 update_extent_info(inode, &largest_ext);
560 ASSERT(write_inode(inode, ni.blk_addr) >= 0);
568 int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
574 struct f2fs_node *node_blk;
579 if (de->from_devino) {
580 struct hardlink_cache_entry *found_hardlink;
582 found_hardlink = f2fs_search_hardlink(sbi, de);
583 if (found_hardlink && found_hardlink->to_ino &&
584 found_hardlink->nbuild)
587 found_hardlink->nbuild++;
590 fd = open(de->full_path, O_RDONLY);
592 MSG(0, "Skip: Fail to open %s\n", de->full_path);
596 /* inline_data support */
597 if (de->size <= DEF_MAX_INLINE_DATA) {
600 get_node_info(sbi, de->ino, &ni);
602 node_blk = calloc(BLOCK_SZ, 1);
605 ret = dev_read_block(node_blk, ni.blk_addr);
608 node_blk->i.i_inline |= F2FS_INLINE_DATA;
609 node_blk->i.i_inline |= F2FS_DATA_EXIST;
611 if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
612 node_blk->i.i_inline |= F2FS_EXTRA_ATTR;
613 node_blk->i.i_extra_isize =
614 cpu_to_le16(calc_extra_isize());
616 n = read(fd, buffer, BLOCK_SZ);
617 ASSERT((unsigned long)n == de->size);
618 memcpy(inline_data_addr(node_blk), buffer, de->size);
619 node_blk->i.i_size = cpu_to_le64(de->size);
620 ASSERT(write_inode(node_blk, ni.blk_addr) >= 0);
623 } else if (c.func == SLOAD && c.compress.enabled &&
624 c.compress.filter_ops->filter(de->full_path)) {
626 u8 *rbuf = c.compress.cc.rbuf;
627 unsigned int cblocks = 0;
629 node_blk = calloc(BLOCK_SZ, 1);
633 get_node_info(sbi, de->ino, &ni);
634 ASSERT(dev_read_block(node_blk, ni.blk_addr) >= 0);
635 /* update inode meta */
636 node_blk->i.i_compress_algrithm = c.compress.alg;
637 node_blk->i.i_log_cluster_size =
638 c.compress.cc.log_cluster_size;
639 node_blk->i.i_flags = cpu_to_le32(F2FS_COMPR_FL);
640 if (c.compress.readonly)
641 node_blk->i.i_inline |= F2FS_COMPRESS_RELEASED;
642 ASSERT(write_inode(node_blk, ni.blk_addr) >= 0);
644 while (!eof && (n = bulkread(fd, rbuf, c.compress.cc.rlen,
646 int ret = c.compress.ops->compress(&c.compress.cc);
648 u32 csize = ALIGN_UP(c.compress.cc.clen +
649 COMPRESS_HEADER_SIZE, BLOCK_SZ);
650 unsigned int cur_cblk;
652 if (ret || n < c.compress.cc.rlen ||
653 n < (int)(csize + BLOCK_SZ *
654 c.compress.min_blocks)) {
655 wlen = f2fs_write(sbi, de->ino, rbuf, n, off);
656 ASSERT((int)wlen == n);
658 wlen = f2fs_write_addrtag(sbi, de->ino, off,
661 wlen = f2fs_write_compress_data(sbi, de->ino,
662 (u8 *)c.compress.cc.cbuf,
663 csize, off + BLOCK_SZ);
664 ASSERT(wlen == csize);
665 c.compress.ops->reset(&c.compress.cc);
666 cur_cblk = (c.compress.cc.rlen - csize) /
669 wlen = f2fs_fix_mutable(sbi, de->ino,
670 off + BLOCK_SZ + csize,
677 fprintf(stderr, "Load file '%s' failed: ",
682 get_node_info(sbi, de->ino, &ni);
683 ASSERT(dev_read_block(node_blk, ni.blk_addr) >= 0);
684 /* update inode meta */
685 node_blk->i.i_size = cpu_to_le64(off);
686 if (!c.compress.readonly) {
687 node_blk->i.i_compr_blocks = cpu_to_le64(cblocks);
688 node_blk->i.i_blocks += cpu_to_le64(cblocks);
690 ASSERT(write_inode(node_blk, ni.blk_addr) >= 0);
693 if (!c.compress.readonly) {
694 sbi->total_valid_block_count += cblocks;
695 if (sbi->total_valid_block_count >=
696 sbi->user_block_count) {
697 ERR_MSG("Not enough space\n");
703 while ((n = read(fd, buffer, BLOCK_SZ)) > 0) {
704 f2fs_write(sbi, de->ino, buffer, n, off);
713 if (!c.compress.enabled || (c.feature & cpu_to_le32(F2FS_FEATURE_RO)))
714 update_largest_extent(sbi, de->ino);
715 update_free_segments(sbi);
717 MSG(1, "Info: Create %s -> %s\n"
718 " -- ino=%x, type=%x, mode=%x, uid=%x, "
719 "gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
720 de->full_path, de->path,
721 de->ino, de->file_type, de->mode,
722 de->uid, de->gid, de->capabilities, de->size, de->pino);