0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/string.h>
0012 #include <linux/errno.h>
0013 #include "nilfs.h"
0014 #include "bmap.h"
0015 #include "btree.h"
0016 #include "direct.h"
0017 #include "btnode.h"
0018 #include "mdt.h"
0019 #include "dat.h"
0020 #include "alloc.h"
0021
0022 struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
0023 {
0024 struct the_nilfs *nilfs = bmap->b_inode->i_sb->s_fs_info;
0025
0026 return nilfs->ns_dat;
0027 }
0028
0029 static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap,
0030 const char *fname, int err)
0031 {
0032 struct inode *inode = bmap->b_inode;
0033
0034 if (err == -EINVAL) {
0035 __nilfs_error(inode->i_sb, fname,
0036 "broken bmap (inode number=%lu)", inode->i_ino);
0037 err = -EIO;
0038 }
0039 return err;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
0063 __u64 *ptrp)
0064 {
0065 sector_t blocknr;
0066 int ret;
0067
0068 down_read(&bmap->b_sem);
0069 ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
0070 if (ret < 0) {
0071 ret = nilfs_bmap_convert_error(bmap, __func__, ret);
0072 goto out;
0073 }
0074 if (NILFS_BMAP_USE_VBN(bmap)) {
0075 ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
0076 &blocknr);
0077 if (!ret)
0078 *ptrp = blocknr;
0079 }
0080
0081 out:
0082 up_read(&bmap->b_sem);
0083 return ret;
0084 }
0085
0086 int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
0087 unsigned int maxblocks)
0088 {
0089 int ret;
0090
0091 down_read(&bmap->b_sem);
0092 ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
0093 up_read(&bmap->b_sem);
0094
0095 return nilfs_bmap_convert_error(bmap, __func__, ret);
0096 }
0097
0098 static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
0099 {
0100 __u64 keys[NILFS_BMAP_SMALL_HIGH + 1];
0101 __u64 ptrs[NILFS_BMAP_SMALL_HIGH + 1];
0102 int ret, n;
0103
0104 if (bmap->b_ops->bop_check_insert != NULL) {
0105 ret = bmap->b_ops->bop_check_insert(bmap, key);
0106 if (ret > 0) {
0107 n = bmap->b_ops->bop_gather_data(
0108 bmap, keys, ptrs, NILFS_BMAP_SMALL_HIGH + 1);
0109 if (n < 0)
0110 return n;
0111 ret = nilfs_btree_convert_and_insert(
0112 bmap, key, ptr, keys, ptrs, n);
0113 if (ret == 0)
0114 bmap->b_u.u_flags |= NILFS_BMAP_LARGE;
0115
0116 return ret;
0117 } else if (ret < 0)
0118 return ret;
0119 }
0120
0121 return bmap->b_ops->bop_insert(bmap, key, ptr);
0122 }
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec)
0143 {
0144 int ret;
0145
0146 down_write(&bmap->b_sem);
0147 ret = nilfs_bmap_do_insert(bmap, key, rec);
0148 up_write(&bmap->b_sem);
0149
0150 return nilfs_bmap_convert_error(bmap, __func__, ret);
0151 }
0152
0153 static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
0154 {
0155 __u64 keys[NILFS_BMAP_LARGE_LOW + 1];
0156 __u64 ptrs[NILFS_BMAP_LARGE_LOW + 1];
0157 int ret, n;
0158
0159 if (bmap->b_ops->bop_check_delete != NULL) {
0160 ret = bmap->b_ops->bop_check_delete(bmap, key);
0161 if (ret > 0) {
0162 n = bmap->b_ops->bop_gather_data(
0163 bmap, keys, ptrs, NILFS_BMAP_LARGE_LOW + 1);
0164 if (n < 0)
0165 return n;
0166 ret = nilfs_direct_delete_and_convert(
0167 bmap, key, keys, ptrs, n);
0168 if (ret == 0)
0169 bmap->b_u.u_flags &= ~NILFS_BMAP_LARGE;
0170
0171 return ret;
0172 } else if (ret < 0)
0173 return ret;
0174 }
0175
0176 return bmap->b_ops->bop_delete(bmap, key);
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp)
0198 {
0199 int ret;
0200
0201 down_read(&bmap->b_sem);
0202 ret = bmap->b_ops->bop_seek_key(bmap, start, keyp);
0203 up_read(&bmap->b_sem);
0204
0205 if (ret < 0)
0206 ret = nilfs_bmap_convert_error(bmap, __func__, ret);
0207 return ret;
0208 }
0209
0210 int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp)
0211 {
0212 int ret;
0213
0214 down_read(&bmap->b_sem);
0215 ret = bmap->b_ops->bop_last_key(bmap, keyp);
0216 up_read(&bmap->b_sem);
0217
0218 if (ret < 0)
0219 ret = nilfs_bmap_convert_error(bmap, __func__, ret);
0220 return ret;
0221 }
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key)
0241 {
0242 int ret;
0243
0244 down_write(&bmap->b_sem);
0245 ret = nilfs_bmap_do_delete(bmap, key);
0246 up_write(&bmap->b_sem);
0247
0248 return nilfs_bmap_convert_error(bmap, __func__, ret);
0249 }
0250
0251 static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, __u64 key)
0252 {
0253 __u64 lastkey;
0254 int ret;
0255
0256 ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
0257 if (ret < 0) {
0258 if (ret == -ENOENT)
0259 ret = 0;
0260 return ret;
0261 }
0262
0263 while (key <= lastkey) {
0264 ret = nilfs_bmap_do_delete(bmap, lastkey);
0265 if (ret < 0)
0266 return ret;
0267 ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
0268 if (ret < 0) {
0269 if (ret == -ENOENT)
0270 ret = 0;
0271 return ret;
0272 }
0273 }
0274 return 0;
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key)
0293 {
0294 int ret;
0295
0296 down_write(&bmap->b_sem);
0297 ret = nilfs_bmap_do_truncate(bmap, key);
0298 up_write(&bmap->b_sem);
0299
0300 return nilfs_bmap_convert_error(bmap, __func__, ret);
0301 }
0302
0303
0304
0305
0306
0307
0308
0309 void nilfs_bmap_clear(struct nilfs_bmap *bmap)
0310 {
0311 down_write(&bmap->b_sem);
0312 if (bmap->b_ops->bop_clear != NULL)
0313 bmap->b_ops->bop_clear(bmap);
0314 up_write(&bmap->b_sem);
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh)
0333 {
0334 int ret;
0335
0336 down_write(&bmap->b_sem);
0337 ret = bmap->b_ops->bop_propagate(bmap, bh);
0338 up_write(&bmap->b_sem);
0339
0340 return nilfs_bmap_convert_error(bmap, __func__, ret);
0341 }
0342
0343
0344
0345
0346
0347
0348 void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *bmap,
0349 struct list_head *listp)
0350 {
0351 if (bmap->b_ops->bop_lookup_dirty_buffers != NULL)
0352 bmap->b_ops->bop_lookup_dirty_buffers(bmap, listp);
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 int nilfs_bmap_assign(struct nilfs_bmap *bmap,
0375 struct buffer_head **bh,
0376 unsigned long blocknr,
0377 union nilfs_binfo *binfo)
0378 {
0379 int ret;
0380
0381 down_write(&bmap->b_sem);
0382 ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo);
0383 up_write(&bmap->b_sem);
0384
0385 return nilfs_bmap_convert_error(bmap, __func__, ret);
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level)
0405 {
0406 int ret;
0407
0408 if (bmap->b_ops->bop_mark == NULL)
0409 return 0;
0410
0411 down_write(&bmap->b_sem);
0412 ret = bmap->b_ops->bop_mark(bmap, key, level);
0413 up_write(&bmap->b_sem);
0414
0415 return nilfs_bmap_convert_error(bmap, __func__, ret);
0416 }
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
0428 {
0429 int ret;
0430
0431 down_write(&bmap->b_sem);
0432 ret = nilfs_bmap_dirty(bmap);
0433 nilfs_bmap_clear_dirty(bmap);
0434 up_write(&bmap->b_sem);
0435 return ret;
0436 }
0437
0438
0439
0440
0441
0442 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
0443 const struct buffer_head *bh)
0444 {
0445 struct buffer_head *pbh;
0446 __u64 key;
0447
0448 key = page_index(bh->b_page) << (PAGE_SHIFT -
0449 bmap->b_inode->i_blkbits);
0450 for (pbh = page_buffers(bh->b_page); pbh != bh; pbh = pbh->b_this_page)
0451 key++;
0452
0453 return key;
0454 }
0455
0456 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
0457 {
0458 __s64 diff;
0459
0460 diff = key - bmap->b_last_allocated_key;
0461 if ((nilfs_bmap_keydiff_abs(diff) < NILFS_INODE_BMAP_SIZE) &&
0462 (bmap->b_last_allocated_ptr != NILFS_BMAP_INVALID_PTR) &&
0463 (bmap->b_last_allocated_ptr + diff > 0))
0464 return bmap->b_last_allocated_ptr + diff;
0465 else
0466 return NILFS_BMAP_INVALID_PTR;
0467 }
0468
0469 #define NILFS_BMAP_GROUP_DIV 8
0470 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
0471 {
0472 struct inode *dat = nilfs_bmap_get_dat(bmap);
0473 unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
0474 unsigned long group = bmap->b_inode->i_ino / entries_per_group;
0475
0476 return group * entries_per_group +
0477 (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
0478 (entries_per_group / NILFS_BMAP_GROUP_DIV);
0479 }
0480
0481 static struct lock_class_key nilfs_bmap_dat_lock_key;
0482 static struct lock_class_key nilfs_bmap_mdt_lock_key;
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496 int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
0497 {
0498 if (raw_inode == NULL)
0499 memset(bmap->b_u.u_data, 0, NILFS_BMAP_SIZE);
0500 else
0501 memcpy(bmap->b_u.u_data, raw_inode->i_bmap, NILFS_BMAP_SIZE);
0502
0503 init_rwsem(&bmap->b_sem);
0504 bmap->b_state = 0;
0505 bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
0506 switch (bmap->b_inode->i_ino) {
0507 case NILFS_DAT_INO:
0508 bmap->b_ptr_type = NILFS_BMAP_PTR_P;
0509 bmap->b_last_allocated_key = 0;
0510 bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
0511 lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
0512 break;
0513 case NILFS_CPFILE_INO:
0514 case NILFS_SUFILE_INO:
0515 bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
0516 bmap->b_last_allocated_key = 0;
0517 bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
0518 lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key);
0519 break;
0520 case NILFS_IFILE_INO:
0521 lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key);
0522 fallthrough;
0523 default:
0524 bmap->b_ptr_type = NILFS_BMAP_PTR_VM;
0525 bmap->b_last_allocated_key = 0;
0526 bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
0527 break;
0528 }
0529
0530 return (bmap->b_u.u_flags & NILFS_BMAP_LARGE) ?
0531 nilfs_btree_init(bmap) : nilfs_direct_init(bmap);
0532 }
0533
0534
0535
0536
0537
0538
0539
0540
0541 void nilfs_bmap_write(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
0542 {
0543 down_write(&bmap->b_sem);
0544 memcpy(raw_inode->i_bmap, bmap->b_u.u_data,
0545 NILFS_INODE_BMAP_SIZE * sizeof(__le64));
0546 if (bmap->b_inode->i_ino == NILFS_DAT_INO)
0547 bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
0548
0549 up_write(&bmap->b_sem);
0550 }
0551
0552 void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
0553 {
0554 memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
0555 init_rwsem(&bmap->b_sem);
0556 bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
0557 bmap->b_ptr_type = NILFS_BMAP_PTR_U;
0558 bmap->b_last_allocated_key = 0;
0559 bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
0560 bmap->b_state = 0;
0561 nilfs_btree_init_gc(bmap);
0562 }
0563
0564 void nilfs_bmap_save(const struct nilfs_bmap *bmap,
0565 struct nilfs_bmap_store *store)
0566 {
0567 memcpy(store->data, bmap->b_u.u_data, sizeof(store->data));
0568 store->last_allocated_key = bmap->b_last_allocated_key;
0569 store->last_allocated_ptr = bmap->b_last_allocated_ptr;
0570 store->state = bmap->b_state;
0571 }
0572
0573 void nilfs_bmap_restore(struct nilfs_bmap *bmap,
0574 const struct nilfs_bmap_store *store)
0575 {
0576 memcpy(bmap->b_u.u_data, store->data, sizeof(store->data));
0577 bmap->b_last_allocated_key = store->last_allocated_key;
0578 bmap->b_last_allocated_ptr = store->last_allocated_ptr;
0579 bmap->b_state = store->state;
0580 }