1 /* 2 * dat.c - NILFS disk address translation. 3 * 4 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * Written by Koji Sato. 17 */ 18 19 #include <linux/types.h> 20 #include <linux/buffer_head.h> 21 #include <linux/string.h> 22 #include <linux/errno.h> 23 #include "nilfs.h" 24 #include "mdt.h" 25 #include "alloc.h" 26 #include "dat.h" 27 28 29 #define NILFS_CNO_MIN ((__u64)1) 30 #define NILFS_CNO_MAX (~(__u64)0) 31 32 /** 33 * struct nilfs_dat_info - on-memory private data of DAT file 34 * @mi: on-memory private data of metadata file 35 * @palloc_cache: persistent object allocator cache of DAT file 36 * @shadow: shadow map of DAT file 37 */ 38 struct nilfs_dat_info { 39 struct nilfs_mdt_info mi; 40 struct nilfs_palloc_cache palloc_cache; 41 struct nilfs_shadow_map shadow; 42 }; 43 44 static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat) 45 { 46 return (struct nilfs_dat_info *)NILFS_MDT(dat); 47 } 48 49 static int nilfs_dat_prepare_entry(struct inode *dat, 50 struct nilfs_palloc_req *req, int create) 51 { 52 return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr, 53 create, &req->pr_entry_bh); 54 } 55 56 static void nilfs_dat_commit_entry(struct inode *dat, 57 struct nilfs_palloc_req *req) 58 { 59 mark_buffer_dirty(req->pr_entry_bh); 60 nilfs_mdt_mark_dirty(dat); 61 brelse(req->pr_entry_bh); 62 } 63 64 static void nilfs_dat_abort_entry(struct inode *dat, 65 struct nilfs_palloc_req *req) 66 { 67 brelse(req->pr_entry_bh); 68 } 69 70 int nilfs_dat_prepare_alloc(struct inode *dat, struct nilfs_palloc_req *req) 71 { 72 int ret; 73 74 ret = nilfs_palloc_prepare_alloc_entry(dat, req); 75 if (ret < 0) 76 return ret; 77 78 ret = nilfs_dat_prepare_entry(dat, req, 1); 79 if (ret < 0) 80 nilfs_palloc_abort_alloc_entry(dat, req); 81 82 return ret; 83 } 84 85 void nilfs_dat_commit_alloc(struct inode *dat, struct nilfs_palloc_req *req) 86 { 87 struct nilfs_dat_entry *entry; 88 void *kaddr; 89 90 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 91 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 92 req->pr_entry_bh, kaddr); 93 entry->de_start = cpu_to_le64(NILFS_CNO_MIN); 94 entry->de_end = cpu_to_le64(NILFS_CNO_MAX); 95 entry->de_blocknr = cpu_to_le64(0); 96 kunmap_atomic(kaddr); 97 98 nilfs_palloc_commit_alloc_entry(dat, req); 99 nilfs_dat_commit_entry(dat, req); 100 } 101 102 void nilfs_dat_abort_alloc(struct inode *dat, struct nilfs_palloc_req *req) 103 { 104 nilfs_dat_abort_entry(dat, req); 105 nilfs_palloc_abort_alloc_entry(dat, req); 106 } 107 108 static void nilfs_dat_commit_free(struct inode *dat, 109 struct nilfs_palloc_req *req) 110 { 111 struct nilfs_dat_entry *entry; 112 void *kaddr; 113 114 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 115 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 116 req->pr_entry_bh, kaddr); 117 entry->de_start = cpu_to_le64(NILFS_CNO_MIN); 118 entry->de_end = cpu_to_le64(NILFS_CNO_MIN); 119 entry->de_blocknr = cpu_to_le64(0); 120 kunmap_atomic(kaddr); 121 122 nilfs_dat_commit_entry(dat, req); 123 nilfs_palloc_commit_free_entry(dat, req); 124 } 125 126 int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req) 127 { 128 int ret; 129 130 ret = nilfs_dat_prepare_entry(dat, req, 0); 131 WARN_ON(ret == -ENOENT); 132 return ret; 133 } 134 135 void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, 136 sector_t blocknr) 137 { 138 struct nilfs_dat_entry *entry; 139 void *kaddr; 140 141 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 142 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 143 req->pr_entry_bh, kaddr); 144 entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); 145 entry->de_blocknr = cpu_to_le64(blocknr); 146 kunmap_atomic(kaddr); 147 148 nilfs_dat_commit_entry(dat, req); 149 } 150 151 int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) 152 { 153 struct nilfs_dat_entry *entry; 154 sector_t blocknr; 155 void *kaddr; 156 int ret; 157 158 ret = nilfs_dat_prepare_entry(dat, req, 0); 159 if (ret < 0) { 160 WARN_ON(ret == -ENOENT); 161 return ret; 162 } 163 164 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 165 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 166 req->pr_entry_bh, kaddr); 167 blocknr = le64_to_cpu(entry->de_blocknr); 168 kunmap_atomic(kaddr); 169 170 if (blocknr == 0) { 171 ret = nilfs_palloc_prepare_free_entry(dat, req); 172 if (ret < 0) { 173 nilfs_dat_abort_entry(dat, req); 174 return ret; 175 } 176 } 177 178 return 0; 179 } 180 181 void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req, 182 int dead) 183 { 184 struct nilfs_dat_entry *entry; 185 __u64 start, end; 186 sector_t blocknr; 187 void *kaddr; 188 189 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 190 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 191 req->pr_entry_bh, kaddr); 192 end = start = le64_to_cpu(entry->de_start); 193 if (!dead) { 194 end = nilfs_mdt_cno(dat); 195 WARN_ON(start > end); 196 } 197 entry->de_end = cpu_to_le64(end); 198 blocknr = le64_to_cpu(entry->de_blocknr); 199 kunmap_atomic(kaddr); 200 201 if (blocknr == 0) 202 nilfs_dat_commit_free(dat, req); 203 else 204 nilfs_dat_commit_entry(dat, req); 205 } 206 207 void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req) 208 { 209 struct nilfs_dat_entry *entry; 210 __u64 start; 211 sector_t blocknr; 212 void *kaddr; 213 214 kaddr = kmap_atomic(req->pr_entry_bh->b_page); 215 entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, 216 req->pr_entry_bh, kaddr); 217 start = le64_to_cpu(entry->de_start); 218 blocknr = le64_to_cpu(entry->de_blocknr); 219 kunmap_atomic(kaddr); 220 221 if (start == nilfs_mdt_cno(dat) && blocknr == 0) 222 nilfs_palloc_abort_free_entry(dat, req); 223 nilfs_dat_abort_entry(dat, req); 224 } 225 226 int nilfs_dat_prepare_update(struct inode *dat, 227 struct nilfs_palloc_req *oldreq, 228 struct nilfs_palloc_req *newreq) 229 { 230 int ret; 231 232 ret = nilfs_dat_prepare_end(dat, oldreq); 233 if (!ret) { 234 ret = nilfs_dat_prepare_alloc(dat, newreq); 235 if (ret < 0) 236 nilfs_dat_abort_end(dat, oldreq); 237 } 238 return ret; 239 } 240 241 void nilfs_dat_commit_update(struct inode *dat, 242 struct nilfs_palloc_req *oldreq, 243 struct nilfs_palloc_req *newreq, int dead) 244 { 245 nilfs_dat_commit_end(dat, oldreq, dead); 246 nilfs_dat_commit_alloc(dat, newreq); 247 } 248 249 void nilfs_dat_abort_update(struct inode *dat, 250 struct nilfs_palloc_req *oldreq, 251 struct nilfs_palloc_req *newreq) 252 { 253 nilfs_dat_abort_end(dat, oldreq); 254 nilfs_dat_abort_alloc(dat, newreq); 255 } 256 257 /** 258 * nilfs_dat_mark_dirty - 259 * @dat: DAT file inode 260 * @vblocknr: virtual block number 261 * 262 * Description: 263 * 264 * Return Value: On success, 0 is returned. On error, one of the following 265 * negative error codes is returned. 266 * 267 * %-EIO - I/O error. 268 * 269 * %-ENOMEM - Insufficient amount of memory available. 270 */ 271 int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr) 272 { 273 struct nilfs_palloc_req req; 274 int ret; 275 276 req.pr_entry_nr = vblocknr; 277 ret = nilfs_dat_prepare_entry(dat, &req, 0); 278 if (ret == 0) 279 nilfs_dat_commit_entry(dat, &req); 280 return ret; 281 } 282 283 /** 284 * nilfs_dat_freev - free virtual block numbers 285 * @dat: DAT file inode 286 * @vblocknrs: array of virtual block numbers 287 * @nitems: number of virtual block numbers 288 * 289 * Description: nilfs_dat_freev() frees the virtual block numbers specified by 290 * @vblocknrs and @nitems. 291 * 292 * Return Value: On success, 0 is returned. On error, one of the following 293 * negative error codes is returned. 294 * 295 * %-EIO - I/O error. 296 * 297 * %-ENOMEM - Insufficient amount of memory available. 298 * 299 * %-ENOENT - The virtual block number have not been allocated. 300 */ 301 int nilfs_dat_freev(struct inode *dat, __u64 *vblocknrs, size_t nitems) 302 { 303 return nilfs_palloc_freev(dat, vblocknrs, nitems); 304 } 305 306 /** 307 * nilfs_dat_move - change a block number 308 * @dat: DAT file inode 309 * @vblocknr: virtual block number 310 * @blocknr: block number 311 * 312 * Description: nilfs_dat_move() changes the block number associated with 313 * @vblocknr to @blocknr. 314 * 315 * Return Value: On success, 0 is returned. On error, one of the following 316 * negative error codes is returned. 317 * 318 * %-EIO - I/O error. 319 * 320 * %-ENOMEM - Insufficient amount of memory available. 321 */ 322 int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr) 323 { 324 struct buffer_head *entry_bh; 325 struct nilfs_dat_entry *entry; 326 void *kaddr; 327 int ret; 328 329 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh); 330 if (ret < 0) 331 return ret; 332 333 /* 334 * The given disk block number (blocknr) is not yet written to 335 * the device at this point. 336 * 337 * To prevent nilfs_dat_translate() from returning the 338 * uncommitted block number, this makes a copy of the entry 339 * buffer and redirects nilfs_dat_translate() to the copy. 340 */ 341 if (!buffer_nilfs_redirected(entry_bh)) { 342 ret = nilfs_mdt_freeze_buffer(dat, entry_bh); 343 if (ret) { 344 brelse(entry_bh); 345 return ret; 346 } 347 } 348 349 kaddr = kmap_atomic(entry_bh->b_page); 350 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr); 351 if (unlikely(entry->de_blocknr == cpu_to_le64(0))) { 352 printk(KERN_CRIT "%s: vbn = %llu, [%llu, %llu)\n", __func__, 353 (unsigned long long)vblocknr, 354 (unsigned long long)le64_to_cpu(entry->de_start), 355 (unsigned long long)le64_to_cpu(entry->de_end)); 356 kunmap_atomic(kaddr); 357 brelse(entry_bh); 358 return -EINVAL; 359 } 360 WARN_ON(blocknr == 0); 361 entry->de_blocknr = cpu_to_le64(blocknr); 362 kunmap_atomic(kaddr); 363 364 mark_buffer_dirty(entry_bh); 365 nilfs_mdt_mark_dirty(dat); 366 367 brelse(entry_bh); 368 369 return 0; 370 } 371 372 /** 373 * nilfs_dat_translate - translate a virtual block number to a block number 374 * @dat: DAT file inode 375 * @vblocknr: virtual block number 376 * @blocknrp: pointer to a block number 377 * 378 * Description: nilfs_dat_translate() maps the virtual block number @vblocknr 379 * to the corresponding block number. 380 * 381 * Return Value: On success, 0 is returned and the block number associated 382 * with @vblocknr is stored in the place pointed by @blocknrp. On error, one 383 * of the following negative error codes is returned. 384 * 385 * %-EIO - I/O error. 386 * 387 * %-ENOMEM - Insufficient amount of memory available. 388 * 389 * %-ENOENT - A block number associated with @vblocknr does not exist. 390 */ 391 int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp) 392 { 393 struct buffer_head *entry_bh, *bh; 394 struct nilfs_dat_entry *entry; 395 sector_t blocknr; 396 void *kaddr; 397 int ret; 398 399 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh); 400 if (ret < 0) 401 return ret; 402 403 if (!nilfs_doing_gc() && buffer_nilfs_redirected(entry_bh)) { 404 bh = nilfs_mdt_get_frozen_buffer(dat, entry_bh); 405 if (bh) { 406 WARN_ON(!buffer_uptodate(bh)); 407 brelse(entry_bh); 408 entry_bh = bh; 409 } 410 } 411 412 kaddr = kmap_atomic(entry_bh->b_page); 413 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr); 414 blocknr = le64_to_cpu(entry->de_blocknr); 415 if (blocknr == 0) { 416 ret = -ENOENT; 417 goto out; 418 } 419 *blocknrp = blocknr; 420 421 out: 422 kunmap_atomic(kaddr); 423 brelse(entry_bh); 424 return ret; 425 } 426 427 ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned int visz, 428 size_t nvi) 429 { 430 struct buffer_head *entry_bh; 431 struct nilfs_dat_entry *entry; 432 struct nilfs_vinfo *vinfo = buf; 433 __u64 first, last; 434 void *kaddr; 435 unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block; 436 int i, j, n, ret; 437 438 for (i = 0; i < nvi; i += n) { 439 ret = nilfs_palloc_get_entry_block(dat, vinfo->vi_vblocknr, 440 0, &entry_bh); 441 if (ret < 0) 442 return ret; 443 kaddr = kmap_atomic(entry_bh->b_page); 444 /* last virtual block number in this block */ 445 first = vinfo->vi_vblocknr; 446 do_div(first, entries_per_block); 447 first *= entries_per_block; 448 last = first + entries_per_block - 1; 449 for (j = i, n = 0; 450 j < nvi && vinfo->vi_vblocknr >= first && 451 vinfo->vi_vblocknr <= last; 452 j++, n++, vinfo = (void *)vinfo + visz) { 453 entry = nilfs_palloc_block_get_entry( 454 dat, vinfo->vi_vblocknr, entry_bh, kaddr); 455 vinfo->vi_start = le64_to_cpu(entry->de_start); 456 vinfo->vi_end = le64_to_cpu(entry->de_end); 457 vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr); 458 } 459 kunmap_atomic(kaddr); 460 brelse(entry_bh); 461 } 462 463 return nvi; 464 } 465 466 /** 467 * nilfs_dat_read - read or get dat inode 468 * @sb: super block instance 469 * @entry_size: size of a dat entry 470 * @raw_inode: on-disk dat inode 471 * @inodep: buffer to store the inode 472 */ 473 int nilfs_dat_read(struct super_block *sb, size_t entry_size, 474 struct nilfs_inode *raw_inode, struct inode **inodep) 475 { 476 static struct lock_class_key dat_lock_key; 477 struct inode *dat; 478 struct nilfs_dat_info *di; 479 int err; 480 481 if (entry_size > sb->s_blocksize) { 482 printk(KERN_ERR 483 "NILFS: too large DAT entry size: %zu bytes.\n", 484 entry_size); 485 return -EINVAL; 486 } else if (entry_size < NILFS_MIN_DAT_ENTRY_SIZE) { 487 printk(KERN_ERR 488 "NILFS: too small DAT entry size: %zu bytes.\n", 489 entry_size); 490 return -EINVAL; 491 } 492 493 dat = nilfs_iget_locked(sb, NULL, NILFS_DAT_INO); 494 if (unlikely(!dat)) 495 return -ENOMEM; 496 if (!(dat->i_state & I_NEW)) 497 goto out; 498 499 err = nilfs_mdt_init(dat, NILFS_MDT_GFP, sizeof(*di)); 500 if (err) 501 goto failed; 502 503 err = nilfs_palloc_init_blockgroup(dat, entry_size); 504 if (err) 505 goto failed; 506 507 di = NILFS_DAT_I(dat); 508 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key); 509 nilfs_palloc_setup_cache(dat, &di->palloc_cache); 510 nilfs_mdt_setup_shadow_map(dat, &di->shadow); 511 512 err = nilfs_read_inode_common(dat, raw_inode); 513 if (err) 514 goto failed; 515 516 unlock_new_inode(dat); 517 out: 518 *inodep = dat; 519 return 0; 520 failed: 521 iget_failed(dat); 522 return err; 523 } 524