Skip to content

Commit 823ae5b

Browse files
Qu Wenruomasoncl
authored andcommitted
btrfs: qgroup: Add function qgroup_update_counters().
Add function qgroup_update_counters(), which will update related qgroups' rfer/excl according to old/new_roots. This is one of the two core functions for the new qgroup implement. This is based on btrfs_adjust_coutners() but with clearer logic and comment. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
1 parent d810ef2 commit 823ae5b

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

fs/btrfs/qgroup.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,126 @@ static int qgroup_update_refcnt(struct btrfs_fs_info *fs_info,
18641864
return 0;
18651865
}
18661866

1867+
/*
1868+
* Update qgroup rfer/excl counters.
1869+
* Rfer update is easy, codes can explain themselves.
1870+
* Excl update is tricky, the update is split into 2 part.
1871+
* Part 1: Possible exclusive <-> sharing detect:
1872+
* | A | !A |
1873+
* -------------------------------------
1874+
* B | * | - |
1875+
* -------------------------------------
1876+
* !B | + | ** |
1877+
* -------------------------------------
1878+
*
1879+
* Conditions:
1880+
* A: cur_old_roots < nr_old_roots (not exclusive before)
1881+
* !A: cur_old_roots == nr_old_roots (possible exclusive before)
1882+
* B: cur_new_roots < nr_new_roots (not exclusive now)
1883+
* !B: cur_new_roots == nr_new_roots (possible exclsuive now)
1884+
*
1885+
* Results:
1886+
* +: Possible sharing -> exclusive -: Possible exclusive -> sharing
1887+
* *: Definitely not changed. **: Possible unchanged.
1888+
*
1889+
* For !A and !B condition, the exception is cur_old/new_roots == 0 case.
1890+
*
1891+
* To make the logic clear, we first use condition A and B to split
1892+
* combination into 4 results.
1893+
*
1894+
* Then, for result "+" and "-", check old/new_roots == 0 case, as in them
1895+
* only on variant maybe 0.
1896+
*
1897+
* Lastly, check result **, since there are 2 variants maybe 0, split them
1898+
* again(2x2).
1899+
* But this time we don't need to consider other things, the codes and logic
1900+
* is easy to understand now.
1901+
*/
1902+
static int qgroup_update_counters(struct btrfs_fs_info *fs_info,
1903+
struct ulist *qgroups,
1904+
u64 nr_old_roots,
1905+
u64 nr_new_roots,
1906+
u64 num_bytes, u64 seq)
1907+
{
1908+
struct ulist_node *unode;
1909+
struct ulist_iterator uiter;
1910+
struct btrfs_qgroup *qg;
1911+
u64 cur_new_count, cur_old_count;
1912+
1913+
ULIST_ITER_INIT(&uiter);
1914+
while ((unode = ulist_next(qgroups, &uiter))) {
1915+
bool dirty = false;
1916+
1917+
qg = u64_to_ptr(unode->aux);
1918+
cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq);
1919+
cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq);
1920+
1921+
/* Rfer update part */
1922+
if (cur_old_count == 0 && cur_new_count > 0) {
1923+
qg->rfer += num_bytes;
1924+
qg->rfer_cmpr += num_bytes;
1925+
dirty = true;
1926+
}
1927+
if (cur_old_count > 0 && cur_new_count == 0) {
1928+
qg->rfer -= num_bytes;
1929+
qg->rfer_cmpr -= num_bytes;
1930+
dirty = true;
1931+
}
1932+
1933+
/* Excl update part */
1934+
/* Exclusive/none -> shared case */
1935+
if (cur_old_count == nr_old_roots &&
1936+
cur_new_count < nr_new_roots) {
1937+
/* Exclusive -> shared */
1938+
if (cur_old_count != 0) {
1939+
qg->excl -= num_bytes;
1940+
qg->excl_cmpr -= num_bytes;
1941+
dirty = true;
1942+
}
1943+
}
1944+
1945+
/* Shared -> exclusive/none case */
1946+
if (cur_old_count < nr_old_roots &&
1947+
cur_new_count == nr_new_roots) {
1948+
/* Shared->exclusive */
1949+
if (cur_new_count != 0) {
1950+
qg->excl += num_bytes;
1951+
qg->excl_cmpr += num_bytes;
1952+
dirty = true;
1953+
}
1954+
}
1955+
1956+
/* Exclusive/none -> exclusive/none case */
1957+
if (cur_old_count == nr_old_roots &&
1958+
cur_new_count == nr_new_roots) {
1959+
if (cur_old_count == 0) {
1960+
/* None -> exclusive/none */
1961+
1962+
if (cur_new_count != 0) {
1963+
/* None -> exclusive */
1964+
qg->excl += num_bytes;
1965+
qg->excl_cmpr += num_bytes;
1966+
dirty = true;
1967+
}
1968+
/* None -> none, nothing changed */
1969+
} else {
1970+
/* Exclusive -> exclusive/none */
1971+
1972+
if (cur_new_count == 0) {
1973+
/* Exclusive -> none */
1974+
qg->excl -= num_bytes;
1975+
qg->excl_cmpr -= num_bytes;
1976+
dirty = true;
1977+
}
1978+
/* Exclusive -> exclusive, nothing changed */
1979+
}
1980+
}
1981+
if (dirty)
1982+
qgroup_dirty(fs_info, qg);
1983+
}
1984+
return 0;
1985+
}
1986+
18671987
/*
18681988
* This adjusts the counters for all referenced qgroups if need be.
18691989
*/

0 commit comments

Comments
 (0)