Skip to content

Commit b60c4dd

Browse files
committedFeb 14, 2025·
zoned: save superblock as json file
Signed-off-by: Ming Lei <[email protected]>
1 parent d56c9ca commit b60c4dd

File tree

1 file changed

+66
-26
lines changed

1 file changed

+66
-26
lines changed
 

‎src/zoned.rs

+66-26
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct TgtData {
105105
imp_close_zone_no: u32,
106106
}
107107

108-
#[derive(Debug, Default, Clone)]
108+
#[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone)]
109109
struct TgtCfg {
110110
size: u64,
111111
zone_size: u64,
@@ -163,6 +163,53 @@ impl TgtCfg {
163163

164164
Ok(tcfg)
165165
}
166+
167+
fn get_pre_alloc_size(zo: Option<&ZonedAddArgs>) -> anyhow::Result<u32> {
168+
let za = match zo {
169+
Some(a) => {
170+
let cfg = parse_size::Config::new().with_default_factor(1_048_576);
171+
(cfg.parse_size(a.pre_alloc_size.clone())? >> 20)
172+
.try_into()
173+
.unwrap()
174+
}
175+
_ => Self::DEF_ZONE_PRE_ALLOC_MB,
176+
};
177+
Ok(za)
178+
}
179+
180+
fn save_file_json(&self, p: &PathBuf) -> anyhow::Result<()> {
181+
let json_string = serde_json::to_string_pretty(self)?;
182+
let mut f = OpenOptions::new().create(true).write(true).open(p)?;
183+
f.write_all(json_string.as_bytes())?;
184+
let _ = f.flush();
185+
Ok(())
186+
}
187+
188+
fn is_parent_of(parent: &PathBuf, child: &PathBuf) -> bool {
189+
match child.parent() {
190+
Some(parent_dir) => parent_dir == parent,
191+
None => false,
192+
}
193+
}
194+
195+
fn from_file_json(p: &PathBuf, zo: Option<&ZonedAddArgs>) -> anyhow::Result<Self> {
196+
let f = OpenOptions::new().read(true).open(p)?;
197+
let reader = BufReader::new(f);
198+
let mut cfg: Self = serde_json::from_reader(reader)?;
199+
200+
let exp = match cfg.base {
201+
Some(ref base) => Self::is_parent_of(base, p),
202+
None => false,
203+
};
204+
205+
if !exp {
206+
bail!("base isn't match with --path {}", p.display());
207+
}
208+
209+
// pre-alloc-size can be overrided from command line
210+
cfg.pre_alloc_size = (Self::get_pre_alloc_size(zo)? as u64) << 20;
211+
Ok(cfg)
212+
}
166213
fn from_file(p: &PathBuf, zo: Option<&ZonedAddArgs>) -> anyhow::Result<Self> {
167214
let first_line = BufReader::new(File::open(p)?).lines().next();
168215
if let Some(Ok(l)) = first_line {
@@ -171,15 +218,7 @@ impl TgtCfg {
171218
.map(|s| s.parse().expect("fail"))
172219
.collect();
173220
let base = p.parent().expect("no parent?").to_path_buf();
174-
let za = match zo {
175-
Some(a) => {
176-
let cfg = parse_size::Config::new().with_default_factor(1_048_576);
177-
(cfg.parse_size(a.pre_alloc_size.clone())? >> 20)
178-
.try_into()
179-
.unwrap()
180-
}
181-
_ => Self::DEF_ZONE_PRE_ALLOC_MB,
182-
};
221+
let za = Self::get_pre_alloc_size(zo)?;
183222
let c = TgtCfg::new(n[0], n[1], n[2], n[3], n[4], Some(base), za);
184223
return Ok(c);
185224
}
@@ -1137,22 +1176,20 @@ fn parse_zone_params(zo: &ZonedAddArgs) -> anyhow::Result<(TgtCfg, bool)> {
11371176
return Err(anyhow::anyhow!("base dir doesn't exist"));
11381177
}
11391178
let zf = path.join("superblock");
1140-
if zf.exists() {
1141-
Ok((TgtCfg::from_file(&zf, Some(zo))?, false))
1179+
let zfj = path.join("superblock.json");
1180+
if zfj.exists() {
1181+
Ok((TgtCfg::from_file_json(&zfj, Some(zo))?, false))
11421182
} else {
1143-
//create superblock file with passed parameter
1144-
let cfg = TgtCfg::from_argument(zo)?;
1145-
let mut file = File::create(zf)?;
1146-
let zs = cfg.zone_size >> 20;
1147-
let s = cfg.size >> 20;
1148-
1149-
writeln!(
1150-
file,
1151-
"{} {} {} {} {}",
1152-
s, zs, zo.conv_zones, zo.max_open_zones, zo.max_active_zones
1153-
)?;
1154-
file.flush()?;
1155-
Ok((cfg, true))
1183+
if zf.exists() {
1184+
let c = TgtCfg::from_file(&zf, Some(zo))?;
1185+
c.save_file_json(&zfj)?;
1186+
std::fs::remove_file(zf)?;
1187+
Ok((c, false))
1188+
} else {
1189+
let c = TgtCfg::from_argument(zo)?;
1190+
c.save_file_json(&zfj)?;
1191+
Ok((c, true))
1192+
}
11561193
}
11571194
}
11581195
}
@@ -1171,7 +1208,10 @@ pub(crate) fn ublk_add_zoned(
11711208
let tgt_data: Result<ZoneJson, _> = serde_json::from_value(zoned.clone());
11721209

11731210
match tgt_data {
1174-
Ok(t) => (TgtCfg::from_file(&t.path.join("superblock"), None)?, false),
1211+
Ok(t) => {
1212+
let p = t.path.join("superblock.json");
1213+
(TgtCfg::from_file_json(&p, None)?, false)
1214+
}
11751215
Err(_) => return Err(anyhow::anyhow!("wrong json data")),
11761216
}
11771217
}

0 commit comments

Comments
 (0)
Please sign in to comment.