forked from pisilinux-rs/yali-rs
fix(partition): silinen alandan açılan "/", boş alan satırını gizlemiyordu
Kullanıcı raporu: "boş alan sorunu geri gelmiş bir alanı sildim boş
alan olarak doğru oku, sonrasında o boş alanı yeni bölüm diyerek /
dizin yaptım biçimlendir seçtim kaydettim ama boş alan duruyor
yerinde, yeni oluşturduğumda duruyor."
## Sebep — koşul YER YER yazılmıştı
Bu tablodaki bir hata üçüncü kez yaşanıyor ve üçü de aynı sebepten:
`has_symbolic` kontrolü satırın YALNIZCA BİR basış yerine eklenmişti.
1. `else if` dalı vardı → tanım varsa satır hiç basılmıyordu
2. `else if` düzeltildi, DÖNGÜ İÇİ basış unutuldu
3. döngü içi de ayrı ayrı yazıldı → yine kaçırılabilir
Senaryo: sdb2 silindi → boş alan DOĞRU göründü → o alandan "Yeni
Bölüm" ile `/` açıldı. `/` "Kalan Alan" olduğu için SEMBOLİKTİR ve
alanın tamamını alır. Ama silinen bölümün yerine basılan satır
sembolik tanımı görmüyordu ve diskin tamamını "boş" göstermeye
devam etti — kullanıcının o satırın sağında gördüğü.
## Düzeltme — koşul tek yerde
let show_free = free_total_mb > 0 && !has_symbolic;
`show_free` artık ÜÇ basış yerinin de ortak koşulu:
döngü içi (silinen grubun sonu), döngü sonu (sonda işaretli), sondaki
`else if` (disk sonu).
Koşulu üç yere ayrı ayrı yazmayı bırakmak bu sınıf hatayı
kaçınılmaz kılıyordu; aynı hatanın üçüncü kez yaşanması bunun
kanıtı.
## Testler (143 → 145)
- ⭐ kullanıcının senaryosu: silinen bölümün yerine sembolik `/`
açıldı → boş alan satırı KAYBOLUR, 2 satır kalır
- aynı senaryo ama SABİT boyutlu bölüm → boş alan satırı kalır ve
miktar doğru düşer (500000 − 50000 = 450000)
İkinci test önemli: satırın kaybolmaması da bir hata olurdu —
sabit boyutlu bölüm gerçekten yer bırakıyor.
cargo check --all-targets : 0 hata, 0 uyarı
cargo test : 145/145
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -319,7 +319,7 @@ boş alandan düşmedi"* — 20 GB'lik disk 39 GB kullanıyor gibi görünüyord
|
||||
| Yer | Kural |
|
||||
|---|---|
|
||||
| `has_symbolic_remaining(parts, disk)` | **TEK KAYNAK.** `!delete && size_mb == 0 && orig_device.is_empty()` |
|
||||
| tablo (`build_table_rows`) | sembolik varsa boş alan satırı **çizilmez** — o alan o tanıma ait |
|
||||
| tablo (`build_table_rows`) | sembolik varsa boş alan satırı **çizilmez** — o alan o tanıma ait. Koşul **`show_free`** adıyla TEK yerde tanımlı ve **üç basış yerinin de** ortak koşulu (aşağıdaki REGRESYON 3'e bak) |
|
||||
| çubuk (`manual_dual_bars`) | sembolik varsa serbest segment **eklenmez** |
|
||||
| `manual_capacity_error` | sembolik varsa `fixed_mb >= cap_mb` reddedilir |
|
||||
|
||||
@@ -331,6 +331,28 @@ kalanın tamamını alır, ikincisine hiç yer kalmaz.
|
||||
`orig_device` dolu (taranmış) 0 boyutlu bölüm sembolik **DEĞİLDİR**:
|
||||
sıfır boyut "kalanın tamamı" anlamına gelmez.
|
||||
|
||||
#### ⭐ Koşul YER YER yazılırsa bu sınıf hata tekrarlar
|
||||
|
||||
Bu tabloda bir hata **üç kez** yaşandı ve üçü de aynı sebepten:
|
||||
`has_symbolic` kontrolü satırın **yalnızca bir** basış yerine
|
||||
eklenmişti.
|
||||
|
||||
1. `else if` dalı vardı, diskte tanım yokken çalışıyordu →
|
||||
tanım varsa satır hiç basılmıyordu (`sda1` + 15 GB boş)
|
||||
2. `else if` düzeltildi, **döngü içindeki** basış unutuldu →
|
||||
`19.8 GB` bölüm + `19.8 GB` boş alan
|
||||
3. döngü içi de düzeltildi ama **koşul üç yere ayrı ayrı yazıldı**
|
||||
|
||||
**Ders:** aynı koşulu birden çok yerde yazma. Tek bir
|
||||
`show_free = free_total_mb > 0 && !has_symbolic` değişkeni hesaplanıp
|
||||
**üç basış yerinin de** koşulu olarak kullanılıyor. Kural tek
|
||||
yerde; onu atlamak ya da çoğaltmak imkânsız.
|
||||
|
||||
> Bu, "sabit bir sayıyı 3 yere yazma" değil — "bir *koşulu* 3
|
||||
> yere yazma". Sabit sayıyı çoğaltmak hataya açıktır ama en azından
|
||||
> yanlışsa sayı yanlış görünür; koşulu çoğaltmak bazı basış
|
||||
> yerlerinde **sessizce yanlış** davranış üretir.
|
||||
|
||||
### ⭐ Bağlanmayan dosya sistemleri — mountpoint isteğe bağlı
|
||||
|
||||
`mountpoint_required(editing, fstype)` üç dosya sisteminde `false`
|
||||
@@ -669,11 +691,11 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu.
|
||||
|
||||
```
|
||||
cargo check --all-targets : 0 hata, 0 uyarı
|
||||
cargo test : 143/143 (test modülü sayısı arttıkça güncel tut)
|
||||
cargo test : 145/145 (test modülü sayısı arttıkça güncel tut)
|
||||
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
||||
```
|
||||
|
||||
Bu oturumda 1 → 143 test. Test modülü olmayan dosyalar (`users.rs`,
|
||||
Bu oturumda 1 → 145 test. Test modülü olmayan dosyalar (`users.rs`,
|
||||
`location.rs`, `rescue.rs`, `funct.rs`, `autoinstall/mod.rs`, `main.rs`)
|
||||
içine modüller eklendi. Çoklu test modülü paylaşılan yardımcıları
|
||||
`steps/partition.rs::testutil` altındadır (`disk()`, `part()`).
|
||||
|
||||
+82
-10
@@ -762,8 +762,12 @@ fn build_table_rows<'a>(
|
||||
.map(|p| p.size_mb)
|
||||
.sum();
|
||||
let free_total_mb = disk_mb.saturating_sub(used_total);
|
||||
// "Kalan Alan" tanımı kalanın tamamını alır → boş alan satırı çizilmez.
|
||||
// "Kalan Alan" tanımı kalanın tamamını alır → boş alan satırı
|
||||
// çizilmez. ⚠️ Bu koşul ÜÇ basış yerinin de ORTAK koşuludur.
|
||||
// Sadece sondakine uygulanırsa diğer ikisi sembolik tanımı
|
||||
// görmez (aşağıdaki REGRESYON 3).
|
||||
let has_symbolic = has_symbolic_remaining(parts, active_disk);
|
||||
let show_free = free_total_mb > 0 && !has_symbolic;
|
||||
|
||||
let mut fs_first: Option<usize> = None;
|
||||
// Boş alan satırı disk başına TEK'tir (GParted tarzı: silinenler
|
||||
@@ -779,7 +783,7 @@ fn build_table_rows<'a>(
|
||||
}
|
||||
// İşaret bloğunun bittiği yerde boş-alan satırını bas
|
||||
if let Some(first) = fs_first.take() {
|
||||
if free_total_mb > 0 {
|
||||
if show_free {
|
||||
visible_rows.push(TableRow::FreeSpace {
|
||||
disk: active_disk.to_string(),
|
||||
total_mb: free_total_mb,
|
||||
@@ -794,14 +798,14 @@ fn build_table_rows<'a>(
|
||||
if let Some(first) = fs_first.take() {
|
||||
// Son ifade olduğu için `free_row_shown` burada güncellenmez;
|
||||
// zaten sonrasında okunacak bir dal yok.
|
||||
if free_total_mb > 0 {
|
||||
if show_free {
|
||||
visible_rows.push(TableRow::FreeSpace {
|
||||
disk: active_disk.to_string(),
|
||||
total_mb: free_total_mb,
|
||||
first_idx: Some(first),
|
||||
});
|
||||
}
|
||||
} else if free_total_mb > 0 && !free_row_shown && !has_symbolic {
|
||||
} else if show_free && !free_row_shown {
|
||||
// Disk SONUNDAKİ boş alan — diskte tanım olsun ya da olmasın.
|
||||
//
|
||||
// REGRESYON: koşul `all(|p| p.disk != active_disk)` idi, yani
|
||||
@@ -809,14 +813,27 @@ fn build_table_rows<'a>(
|
||||
// Diskte tanım var ama hiçbiri silinmek işaretli değilse
|
||||
// (`sda1` + 15 GB boş) satır hiç basılmıyordu.
|
||||
//
|
||||
// `has_symbolic` kuralı: "Kalan Alan" tanımı varsa boş alan o
|
||||
// tanıma aittir. REGRESYON 2: sembolik tanım (`size_mb == 0`)
|
||||
// hiçbir hesaba katılmadığı için hem bölüm satırı hem boş alan
|
||||
// satırı kalanın tamamını gösteriyordu — 20 GB'lik disk
|
||||
// 39 GB kullanıyormuş gibi görünüyordu. Kullanıcı raporu:
|
||||
// "eklenen bölümün 19.8 gb demesine rağmen bunu boş alandan
|
||||
// REGRESYON 2: sembolik tanım (`size_mb == 0`) hiçbir hesaba
|
||||
// katılmadığı için hem bölüm satırı hem boş alan satırı
|
||||
// kalanın tamamını gösteriyordu — 20 GB'lik disk 39 GB
|
||||
// kullanıyor gibi görünüyordu. Kullanıcı raporu:
|
||||
// düşmedi".
|
||||
//
|
||||
// düşmedi".
|
||||
//
|
||||
// REGRESYON 3 (kullanıcı: "bir alanı sildim boş alan olarak
|
||||
// doğru okudu, sonrasında o boş alanı yeni bölüm diyerek /
|
||||
// dizin yaptım… ama boş alan duruyor yerinde, yeni oluşturduğumda
|
||||
// duruyor"): REGRESYON 2'nin düzeltmesi YALNIZCA bu `else if`
|
||||
// dalına uygulanmıştı. Silinen bölümün yerine **döngü içinde**
|
||||
// basılan satır `has_symbolic`'e BAKMIYORDU. `/` "Kalan Alan"
|
||||
// olduğu için semboliktir ve alanın tamamını alır; buna rağmen
|
||||
// satır diskin tamamını "boş" gösteriyordu.
|
||||
//
|
||||
// Çözüm: `show_free` TEK koşul ve üç basış yerinin de ortak
|
||||
// koşulu. Koşulu yer yer yazmak bu sınıf hatayı kaçınılmaz
|
||||
// kılıyordu — üçüncü kez düzeltmek zorunda kaldık.
|
||||
//
|
||||
// `first_idx: None` burada "seçilemez" DEĞİL demektir; yalnızca
|
||||
// temsil ettiği silinmiş bir tanım yoktur. Tıklanabilirdir
|
||||
// (`global_idx == None` dalı `selected_free` tutar ve
|
||||
@@ -4027,6 +4044,61 @@ mod free_space_tests {
|
||||
|
||||
// ── "Kalan Alan" (sembolik) tanımlar ───────────────────────
|
||||
|
||||
/// ⭐ Kullanıcının senaryosu: bir alanı sildi → boş alan DOĞRU
|
||||
/// göründü → o boş alandan "Yeni Bölüm" ile `/` yaptı → boş alan
|
||||
/// **yerinde durdu**, hem de yeni bölümün yanında.
|
||||
///
|
||||
/// REGRESYON: sembolik tanım kuralı (`has_symbolic`) yalnızca
|
||||
/// sondaki `else if` dalına uygulanmıştı. Silinen bölümün yerine
|
||||
/// **döngü içinde** basılan satır kuralı görmüyordu. `/` "Kalan
|
||||
/// Alan" olduğu için semboliktir (alanın tamamını alır) ama satır
|
||||
/// yine de diskin tamamını "boş" gösteriyordu.
|
||||
#[test]
|
||||
fn creating_root_in_a_freed_area_consumes_the_free_row() {
|
||||
let mut dead = part("/dev/sdb2", 100_000, FsType::Ext4, "/");
|
||||
dead.delete = true; // kullanıcı sildi
|
||||
let mut root = part("/dev/sdb3", 0, FsType::Ext4, "/");
|
||||
root.orig_device = String::new(); // "Kalan Alan" → sembolik
|
||||
let parts = vec![
|
||||
part("/dev/sdb1", 1_024, FsType::Fat32, "/boot/efi"),
|
||||
dead,
|
||||
root,
|
||||
];
|
||||
let rows = build_table_rows(&parts, "/dev/sdb", 500_000);
|
||||
|
||||
assert!(
|
||||
free_mb_of(&rows).is_empty(),
|
||||
"sembolik / alanın tamamını alıyor, boş alan satırı kalmamalı: {:?}",
|
||||
free_mb_of(&rows)
|
||||
);
|
||||
assert_eq!(
|
||||
rows.len(),
|
||||
2,
|
||||
"sdb1 + yeni / olmalı, boş alan satırı olmamalı: {}",
|
||||
rows.len()
|
||||
);
|
||||
}
|
||||
|
||||
/// Aynı senaryo ama yerine SABİT boyutlu bölüm konursa boş alan
|
||||
/// **kalır** ve miktar doğru düşer — sembolik değil, gerçek yer
|
||||
/// vardır.
|
||||
#[test]
|
||||
fn fixed_size_partition_in_a_freed_area_keeps_a_correct_free_row() {
|
||||
let mut dead = part("/dev/sdb2", 100_000, FsType::Ext4, "/");
|
||||
dead.delete = true;
|
||||
let mut data = part("/dev/sdb3", 50_000, FsType::Ntfs, "");
|
||||
data.orig_device = String::new();
|
||||
let parts = vec![dead, data];
|
||||
let rows = build_table_rows(&parts, "/dev/sdb", 500_000);
|
||||
|
||||
// 500_000 − 50_000 = 450_000 boş kalmalı
|
||||
assert_eq!(
|
||||
free_mb_of(&rows),
|
||||
vec![450_000],
|
||||
"sabit boyutlu bölüm boş alanı düşürmeli, satır kalmalı"
|
||||
);
|
||||
}
|
||||
|
||||
/// Kullanıcı raporu: "eklenen bölümün 19.8 gb demesine rağmen
|
||||
/// bunu boş alandan düşmedi".
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user