|
@@ -403,6 +403,37 @@ cache:
|
|
|
up_write(&nm_i->nat_tree_lock);
|
|
|
}
|
|
|
|
|
|
+pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs)
|
|
|
+{
|
|
|
+ const long direct_index = ADDRS_PER_INODE(dn->inode);
|
|
|
+ const long direct_blks = ADDRS_PER_BLOCK;
|
|
|
+ const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
|
|
|
+ unsigned int skipped_unit = ADDRS_PER_BLOCK;
|
|
|
+ int cur_level = dn->cur_level;
|
|
|
+ int max_level = dn->max_level;
|
|
|
+ pgoff_t base = 0;
|
|
|
+
|
|
|
+ if (!dn->max_level)
|
|
|
+ return pgofs + 1;
|
|
|
+
|
|
|
+ while (max_level-- > cur_level)
|
|
|
+ skipped_unit *= NIDS_PER_BLOCK;
|
|
|
+
|
|
|
+ switch (dn->max_level) {
|
|
|
+ case 3:
|
|
|
+ base += 2 * indirect_blks;
|
|
|
+ case 2:
|
|
|
+ base += 2 * direct_blks;
|
|
|
+ case 1:
|
|
|
+ base += direct_index;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ f2fs_bug_on(F2FS_I_SB(dn->inode), 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ((pgofs - base) / skipped_unit + 1) * skipped_unit + base;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* The maximum depth is four.
|
|
|
* Offset[0] will have raw inode offset.
|
|
@@ -495,7 +526,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
|
|
|
int offset[4];
|
|
|
unsigned int noffset[4];
|
|
|
nid_t nids[4];
|
|
|
- int level, i;
|
|
|
+ int level, i = 0;
|
|
|
int err = 0;
|
|
|
|
|
|
level = get_node_path(dn->inode, index, offset, noffset);
|
|
@@ -585,6 +616,10 @@ release_pages:
|
|
|
release_out:
|
|
|
dn->inode_page = NULL;
|
|
|
dn->node_page = NULL;
|
|
|
+ if (err == -ENOENT) {
|
|
|
+ dn->cur_level = i;
|
|
|
+ dn->max_level = level;
|
|
|
+ }
|
|
|
return err;
|
|
|
}
|
|
|
|