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