0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/fs.h>
0032 #include <linux/buffer_head.h>
0033 #include <linux/pagemap.h>
0034 #include <linux/quotaops.h>
0035 #include <linux/slab.h>
0036
0037 #include "jfs_incore.h"
0038 #include "jfs_inode.h"
0039 #include "jfs_filsys.h"
0040 #include "jfs_dinode.h"
0041 #include "jfs_dmap.h"
0042 #include "jfs_imap.h"
0043 #include "jfs_metapage.h"
0044 #include "jfs_superblock.h"
0045 #include "jfs_debug.h"
0046
0047
0048
0049
0050
0051 #define IAGFREE_LOCK_INIT(imap) mutex_init(&imap->im_freelock)
0052 #define IAGFREE_LOCK(imap) mutex_lock(&imap->im_freelock)
0053 #define IAGFREE_UNLOCK(imap) mutex_unlock(&imap->im_freelock)
0054
0055
0056 #define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
0057 #define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
0058 #define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
0059
0060
0061
0062
0063 static int diAllocAG(struct inomap *, int, bool, struct inode *);
0064 static int diAllocAny(struct inomap *, int, bool, struct inode *);
0065 static int diAllocBit(struct inomap *, struct iag *, int);
0066 static int diAllocExt(struct inomap *, int, struct inode *);
0067 static int diAllocIno(struct inomap *, int, struct inode *);
0068 static int diFindFree(u32, int);
0069 static int diNewExt(struct inomap *, struct iag *, int);
0070 static int diNewIAG(struct inomap *, int *, int, struct metapage **);
0071 static void duplicateIXtree(struct super_block *, s64, int, s64 *);
0072
0073 static int diIAGRead(struct inomap * imap, int, struct metapage **);
0074 static int copy_from_dinode(struct dinode *, struct inode *);
0075 static void copy_to_dinode(struct dinode *, struct inode *);
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 int diMount(struct inode *ipimap)
0095 {
0096 struct inomap *imap;
0097 struct metapage *mp;
0098 int index;
0099 struct dinomap_disk *dinom_le;
0100
0101
0102
0103
0104
0105 imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
0106 if (imap == NULL)
0107 return -ENOMEM;
0108
0109
0110
0111 mp = read_metapage(ipimap,
0112 IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
0113 PSIZE, 0);
0114 if (mp == NULL) {
0115 kfree(imap);
0116 return -EIO;
0117 }
0118
0119
0120 dinom_le = (struct dinomap_disk *) mp->data;
0121 imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag);
0122 imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag);
0123 atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos));
0124 atomic_set(&imap->im_numfree, le32_to_cpu(dinom_le->in_numfree));
0125 imap->im_nbperiext = le32_to_cpu(dinom_le->in_nbperiext);
0126 imap->im_l2nbperiext = le32_to_cpu(dinom_le->in_l2nbperiext);
0127 for (index = 0; index < MAXAG; index++) {
0128 imap->im_agctl[index].inofree =
0129 le32_to_cpu(dinom_le->in_agctl[index].inofree);
0130 imap->im_agctl[index].extfree =
0131 le32_to_cpu(dinom_le->in_agctl[index].extfree);
0132 imap->im_agctl[index].numinos =
0133 le32_to_cpu(dinom_le->in_agctl[index].numinos);
0134 imap->im_agctl[index].numfree =
0135 le32_to_cpu(dinom_le->in_agctl[index].numfree);
0136 }
0137
0138
0139 release_metapage(mp);
0140
0141
0142
0143
0144
0145 IAGFREE_LOCK_INIT(imap);
0146
0147
0148 for (index = 0; index < MAXAG; index++) {
0149 AG_LOCK_INIT(imap, index);
0150 }
0151
0152
0153
0154
0155 imap->im_ipimap = ipimap;
0156 JFS_IP(ipimap)->i_imap = imap;
0157
0158 return (0);
0159 }
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 int diUnmount(struct inode *ipimap, int mounterror)
0177 {
0178 struct inomap *imap = JFS_IP(ipimap)->i_imap;
0179
0180
0181
0182
0183
0184 if (!(mounterror || isReadOnly(ipimap)))
0185 diSync(ipimap);
0186
0187
0188
0189
0190 truncate_inode_pages(ipimap->i_mapping, 0);
0191
0192
0193
0194
0195 kfree(imap);
0196
0197 return (0);
0198 }
0199
0200
0201
0202
0203
0204 int diSync(struct inode *ipimap)
0205 {
0206 struct dinomap_disk *dinom_le;
0207 struct inomap *imp = JFS_IP(ipimap)->i_imap;
0208 struct metapage *mp;
0209 int index;
0210
0211
0212
0213
0214
0215 mp = get_metapage(ipimap,
0216 IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
0217 PSIZE, 0);
0218 if (mp == NULL) {
0219 jfs_err("diSync: get_metapage failed!");
0220 return -EIO;
0221 }
0222
0223
0224 dinom_le = (struct dinomap_disk *) mp->data;
0225 dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag);
0226 dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag);
0227 dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos));
0228 dinom_le->in_numfree = cpu_to_le32(atomic_read(&imp->im_numfree));
0229 dinom_le->in_nbperiext = cpu_to_le32(imp->im_nbperiext);
0230 dinom_le->in_l2nbperiext = cpu_to_le32(imp->im_l2nbperiext);
0231 for (index = 0; index < MAXAG; index++) {
0232 dinom_le->in_agctl[index].inofree =
0233 cpu_to_le32(imp->im_agctl[index].inofree);
0234 dinom_le->in_agctl[index].extfree =
0235 cpu_to_le32(imp->im_agctl[index].extfree);
0236 dinom_le->in_agctl[index].numinos =
0237 cpu_to_le32(imp->im_agctl[index].numinos);
0238 dinom_le->in_agctl[index].numfree =
0239 cpu_to_le32(imp->im_agctl[index].numfree);
0240 }
0241
0242
0243 write_metapage(mp);
0244
0245
0246
0247
0248 filemap_write_and_wait(ipimap->i_mapping);
0249
0250 diWriteSpecial(ipimap, 0);
0251
0252 return (0);
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 int diRead(struct inode *ip)
0290 {
0291 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
0292 int iagno, ino, extno, rc;
0293 struct inode *ipimap;
0294 struct dinode *dp;
0295 struct iag *iagp;
0296 struct metapage *mp;
0297 s64 blkno, agstart;
0298 struct inomap *imap;
0299 int block_offset;
0300 int inodes_left;
0301 unsigned long pageno;
0302 int rel_inode;
0303
0304 jfs_info("diRead: ino = %ld", ip->i_ino);
0305
0306 ipimap = sbi->ipimap;
0307 JFS_IP(ip)->ipimap = ipimap;
0308
0309
0310 iagno = INOTOIAG(ip->i_ino);
0311
0312
0313 imap = JFS_IP(ipimap)->i_imap;
0314 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
0315 rc = diIAGRead(imap, iagno, &mp);
0316 IREAD_UNLOCK(ipimap);
0317 if (rc) {
0318 jfs_err("diRead: diIAGRead returned %d", rc);
0319 return (rc);
0320 }
0321
0322 iagp = (struct iag *) mp->data;
0323
0324
0325 ino = ip->i_ino & (INOSPERIAG - 1);
0326 extno = ino >> L2INOSPEREXT;
0327
0328 if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) ||
0329 (addressPXD(&iagp->inoext[extno]) == 0)) {
0330 release_metapage(mp);
0331 return -ESTALE;
0332 }
0333
0334
0335
0336
0337 blkno = INOPBLK(&iagp->inoext[extno], ino, sbi->l2nbperpage);
0338
0339
0340 agstart = le64_to_cpu(iagp->agstart);
0341
0342 release_metapage(mp);
0343
0344 rel_inode = (ino & (INOSPERPAGE - 1));
0345 pageno = blkno >> sbi->l2nbperpage;
0346
0347 if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
0348
0349
0350
0351 inodes_left =
0352 (sbi->nbperpage - block_offset) << sbi->l2niperblk;
0353
0354 if (rel_inode < inodes_left)
0355 rel_inode += block_offset << sbi->l2niperblk;
0356 else {
0357 pageno += 1;
0358 rel_inode -= inodes_left;
0359 }
0360 }
0361
0362
0363 mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
0364 if (!mp) {
0365 jfs_err("diRead: read_metapage failed");
0366 return -EIO;
0367 }
0368
0369
0370 dp = (struct dinode *) mp->data;
0371 dp += rel_inode;
0372
0373 if (ip->i_ino != le32_to_cpu(dp->di_number)) {
0374 jfs_error(ip->i_sb, "i_ino != di_number\n");
0375 rc = -EIO;
0376 } else if (le32_to_cpu(dp->di_nlink) == 0)
0377 rc = -ESTALE;
0378 else
0379
0380 rc = copy_from_dinode(dp, ip);
0381
0382 release_metapage(mp);
0383
0384
0385 JFS_IP(ip)->agstart = agstart;
0386 JFS_IP(ip)->active_ag = -1;
0387
0388 return (rc);
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
0415 {
0416 struct jfs_sb_info *sbi = JFS_SBI(sb);
0417 uint address;
0418 struct dinode *dp;
0419 struct inode *ip;
0420 struct metapage *mp;
0421
0422 ip = new_inode(sb);
0423 if (ip == NULL) {
0424 jfs_err("diReadSpecial: new_inode returned NULL!");
0425 return ip;
0426 }
0427
0428 if (secondary) {
0429 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
0430 JFS_IP(ip)->ipimap = sbi->ipaimap2;
0431 } else {
0432 address = AITBL_OFF >> L2PSIZE;
0433 JFS_IP(ip)->ipimap = sbi->ipaimap;
0434 }
0435
0436 ASSERT(inum < INOSPEREXT);
0437
0438 ip->i_ino = inum;
0439
0440 address += inum >> 3;
0441
0442
0443 mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
0444 if (mp == NULL) {
0445 set_nlink(ip, 1);
0446 iput(ip);
0447 return (NULL);
0448 }
0449
0450
0451 dp = (struct dinode *) (mp->data);
0452 dp += inum % 8;
0453
0454
0455 if ((copy_from_dinode(dp, ip)) != 0) {
0456
0457 set_nlink(ip, 1);
0458 iput(ip);
0459
0460 release_metapage(mp);
0461 return (NULL);
0462
0463 }
0464
0465 ip->i_mapping->a_ops = &jfs_metapage_aops;
0466 mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
0467
0468
0469 ip->i_flags |= S_NOQUOTA;
0470
0471 if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
0472 sbi->gengen = le32_to_cpu(dp->di_gengen);
0473 sbi->inostamp = le32_to_cpu(dp->di_inostamp);
0474 }
0475
0476
0477 release_metapage(mp);
0478
0479 inode_fake_hash(ip);
0480
0481 return (ip);
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496 void diWriteSpecial(struct inode *ip, int secondary)
0497 {
0498 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
0499 uint address;
0500 struct dinode *dp;
0501 ino_t inum = ip->i_ino;
0502 struct metapage *mp;
0503
0504 if (secondary)
0505 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
0506 else
0507 address = AITBL_OFF >> L2PSIZE;
0508
0509 ASSERT(inum < INOSPEREXT);
0510
0511 address += inum >> 3;
0512
0513
0514 mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
0515 if (mp == NULL) {
0516 jfs_err("diWriteSpecial: failed to read aggregate inode extent!");
0517 return;
0518 }
0519
0520
0521 dp = (struct dinode *) (mp->data);
0522 dp += inum % 8;
0523
0524
0525 copy_to_dinode(dp, ip);
0526 memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);
0527
0528 if (inum == FILESYSTEM_I)
0529 dp->di_gengen = cpu_to_le32(sbi->gengen);
0530
0531
0532 write_metapage(mp);
0533 }
0534
0535
0536
0537
0538
0539
0540 void diFreeSpecial(struct inode *ip)
0541 {
0542 if (ip == NULL) {
0543 jfs_err("diFreeSpecial called with NULL ip!");
0544 return;
0545 }
0546 filemap_write_and_wait(ip->i_mapping);
0547 truncate_inode_pages(ip->i_mapping, 0);
0548 iput(ip);
0549 }
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577 int diWrite(tid_t tid, struct inode *ip)
0578 {
0579 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
0580 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
0581 int rc = 0;
0582 s32 ino;
0583 struct dinode *dp;
0584 s64 blkno;
0585 int block_offset;
0586 int inodes_left;
0587 struct metapage *mp;
0588 unsigned long pageno;
0589 int rel_inode;
0590 int dioffset;
0591 struct inode *ipimap;
0592 uint type;
0593 lid_t lid;
0594 struct tlock *ditlck, *tlck;
0595 struct linelock *dilinelock, *ilinelock;
0596 struct lv *lv;
0597 int n;
0598
0599 ipimap = jfs_ip->ipimap;
0600
0601 ino = ip->i_ino & (INOSPERIAG - 1);
0602
0603 if (!addressPXD(&(jfs_ip->ixpxd)) ||
0604 (lengthPXD(&(jfs_ip->ixpxd)) !=
0605 JFS_IP(ipimap)->i_imap->im_nbperiext)) {
0606 jfs_error(ip->i_sb, "ixpxd invalid\n");
0607 return -EIO;
0608 }
0609
0610
0611
0612
0613
0614 blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);
0615
0616 rel_inode = (ino & (INOSPERPAGE - 1));
0617 pageno = blkno >> sbi->l2nbperpage;
0618
0619 if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
0620
0621
0622
0623 inodes_left =
0624 (sbi->nbperpage - block_offset) << sbi->l2niperblk;
0625
0626 if (rel_inode < inodes_left)
0627 rel_inode += block_offset << sbi->l2niperblk;
0628 else {
0629 pageno += 1;
0630 rel_inode -= inodes_left;
0631 }
0632 }
0633
0634 retry:
0635 mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
0636 if (!mp)
0637 return -EIO;
0638
0639
0640 dp = (struct dinode *) mp->data;
0641 dp += rel_inode;
0642
0643 dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
0644
0645
0646
0647
0648
0649 if ((ditlck =
0650 txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
0651 goto retry;
0652 dilinelock = (struct linelock *) & ditlck->lock;
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {
0668
0669
0670
0671
0672 xtpage_t *p, *xp;
0673 xad_t *xad;
0674
0675 jfs_ip->xtlid = 0;
0676 tlck = lid_to_tlock(lid);
0677 assert(tlck->type & tlckXTREE);
0678 tlck->type |= tlckBTROOT;
0679 tlck->mp = mp;
0680 ilinelock = (struct linelock *) & tlck->lock;
0681
0682
0683
0684
0685 p = &jfs_ip->i_xtroot;
0686 xp = (xtpage_t *) &dp->di_dirtable;
0687 lv = ilinelock->lv;
0688 for (n = 0; n < ilinelock->index; n++, lv++) {
0689 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
0690 lv->length << L2XTSLOTSIZE);
0691 }
0692
0693
0694 xad = &xp->xad[XTENTRYSTART];
0695 for (n = XTENTRYSTART;
0696 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
0697 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
0698 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
0699 }
0700
0701 if ((lid = jfs_ip->blid) == 0)
0702 goto inlineData;
0703 jfs_ip->blid = 0;
0704
0705 tlck = lid_to_tlock(lid);
0706 type = tlck->type;
0707 tlck->type |= tlckBTROOT;
0708 tlck->mp = mp;
0709 ilinelock = (struct linelock *) & tlck->lock;
0710
0711
0712
0713
0714 if (type & tlckXTREE) {
0715 xtpage_t *p, *xp;
0716 xad_t *xad;
0717
0718
0719
0720
0721 p = &jfs_ip->i_xtroot;
0722 xp = &dp->di_xtroot;
0723 lv = ilinelock->lv;
0724 for (n = 0; n < ilinelock->index; n++, lv++) {
0725 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
0726 lv->length << L2XTSLOTSIZE);
0727 }
0728
0729
0730 xad = &xp->xad[XTENTRYSTART];
0731 for (n = XTENTRYSTART;
0732 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
0733 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
0734 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
0735 }
0736
0737
0738
0739 else if (type & tlckDTREE) {
0740 dtpage_t *p, *xp;
0741
0742
0743
0744
0745 p = (dtpage_t *) &jfs_ip->i_dtroot;
0746 xp = (dtpage_t *) & dp->di_dtroot;
0747 lv = ilinelock->lv;
0748 for (n = 0; n < ilinelock->index; n++, lv++) {
0749 memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
0750 lv->length << L2DTSLOTSIZE);
0751 }
0752 } else {
0753 jfs_err("diWrite: UFO tlock");
0754 }
0755
0756 inlineData:
0757
0758
0759
0760 if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
0761 lv = & dilinelock->lv[dilinelock->index];
0762 lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
0763 lv->length = 2;
0764 memcpy(&dp->di_inline_all, jfs_ip->i_inline_all, IDATASIZE);
0765 dilinelock->index++;
0766 }
0767
0768
0769
0770
0771 if (test_cflag(COMMIT_Inlineea, ip)) {
0772 lv = & dilinelock->lv[dilinelock->index];
0773 lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
0774 lv->length = 1;
0775 memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);
0776 dilinelock->index++;
0777
0778 clear_cflag(COMMIT_Inlineea, ip);
0779 }
0780
0781
0782
0783
0784 lv = & dilinelock->lv[dilinelock->index];
0785 lv->offset = dioffset >> L2INODESLOTSIZE;
0786 copy_to_dinode(dp, ip);
0787 if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
0788 lv->length = 2;
0789 memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);
0790 } else
0791 lv->length = 1;
0792 dilinelock->index++;
0793
0794
0795
0796
0797 write_metapage(mp);
0798
0799 return (rc);
0800 }
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841 int diFree(struct inode *ip)
0842 {
0843 int rc;
0844 ino_t inum = ip->i_ino;
0845 struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;
0846 struct metapage *mp, *amp, *bmp, *cmp, *dmp;
0847 int iagno, ino, extno, bitno, sword, agno;
0848 int back, fwd;
0849 u32 bitmap, mask;
0850 struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
0851 struct inomap *imap = JFS_IP(ipimap)->i_imap;
0852 pxd_t freepxd;
0853 tid_t tid;
0854 struct inode *iplist[3];
0855 struct tlock *tlck;
0856 struct pxd_lock *pxdlock;
0857
0858
0859
0860
0861
0862 aiagp = biagp = ciagp = diagp = NULL;
0863
0864
0865
0866 iagno = INOTOIAG(inum);
0867
0868
0869
0870
0871 if (iagno >= imap->im_nextiag) {
0872 print_hex_dump(KERN_ERR, "imap: ", DUMP_PREFIX_ADDRESS, 16, 4,
0873 imap, 32, 0);
0874 jfs_error(ip->i_sb, "inum = %d, iagno = %d, nextiag = %d\n",
0875 (uint) inum, iagno, imap->im_nextiag);
0876 return -EIO;
0877 }
0878
0879
0880
0881 agno = BLKTOAG(JFS_IP(ip)->agstart, JFS_SBI(ip->i_sb));
0882
0883
0884
0885 AG_LOCK(imap, agno);
0886
0887
0888
0889
0890 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
0891
0892
0893
0894 if ((rc = diIAGRead(imap, iagno, &mp))) {
0895 IREAD_UNLOCK(ipimap);
0896 AG_UNLOCK(imap, agno);
0897 return (rc);
0898 }
0899 iagp = (struct iag *) mp->data;
0900
0901
0902
0903
0904 ino = inum & (INOSPERIAG - 1);
0905 extno = ino >> L2INOSPEREXT;
0906 bitno = ino & (INOSPEREXT - 1);
0907 mask = HIGHORDER >> bitno;
0908
0909 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
0910 jfs_error(ip->i_sb, "wmap shows inode already free\n");
0911 }
0912
0913 if (!addressPXD(&iagp->inoext[extno])) {
0914 release_metapage(mp);
0915 IREAD_UNLOCK(ipimap);
0916 AG_UNLOCK(imap, agno);
0917 jfs_error(ip->i_sb, "invalid inoext\n");
0918 return -EIO;
0919 }
0920
0921
0922
0923 bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
0924
0925 if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
0926 release_metapage(mp);
0927 IREAD_UNLOCK(ipimap);
0928 AG_UNLOCK(imap, agno);
0929 jfs_error(ip->i_sb, "numfree > numinos\n");
0930 return -EIO;
0931 }
0932
0933
0934
0935
0936 if (bitmap ||
0937 imap->im_agctl[agno].numfree < 96 ||
0938 (imap->im_agctl[agno].numfree < 288 &&
0939 (((imap->im_agctl[agno].numfree * 100) /
0940 imap->im_agctl[agno].numinos) <= 25))) {
0941
0942
0943
0944
0945 if (iagp->nfreeinos == 0) {
0946
0947
0948
0949
0950
0951 if ((fwd = imap->im_agctl[agno].inofree) >= 0) {
0952
0953
0954
0955 if ((rc = diIAGRead(imap, fwd, &))) {
0956 IREAD_UNLOCK(ipimap);
0957 AG_UNLOCK(imap, agno);
0958 release_metapage(mp);
0959 return (rc);
0960 }
0961 aiagp = (struct iag *) amp->data;
0962
0963
0964
0965 aiagp->inofreeback = cpu_to_le32(iagno);
0966
0967 write_metapage(amp);
0968 }
0969
0970
0971
0972
0973 iagp->inofreefwd =
0974 cpu_to_le32(imap->im_agctl[agno].inofree);
0975 iagp->inofreeback = cpu_to_le32(-1);
0976 imap->im_agctl[agno].inofree = iagno;
0977 }
0978 IREAD_UNLOCK(ipimap);
0979
0980
0981
0982
0983
0984
0985 if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
0986 sword = extno >> L2EXTSPERSUM;
0987 bitno = extno & (EXTSPERSUM - 1);
0988 iagp->inosmap[sword] &=
0989 cpu_to_le32(~(HIGHORDER >> bitno));
0990 }
0991
0992
0993
0994 iagp->wmap[extno] = cpu_to_le32(bitmap);
0995
0996
0997
0998
0999 le32_add_cpu(&iagp->nfreeinos, 1);
1000 imap->im_agctl[agno].numfree += 1;
1001 atomic_inc(&imap->im_numfree);
1002
1003
1004
1005 AG_UNLOCK(imap, agno);
1006
1007
1008 write_metapage(mp);
1009
1010 return (0);
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 amp = bmp = cmp = dmp = NULL;
1023 fwd = back = -1;
1024
1025
1026
1027
1028 if (iagp->nfreeexts == 0) {
1029
1030
1031
1032
1033
1034
1035 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
1036 if ((rc = diIAGRead(imap, fwd, &)))
1037 goto error_out;
1038 aiagp = (struct iag *) amp->data;
1039 }
1040 } else {
1041
1042
1043
1044
1045
1046 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1047
1048
1049
1050
1051
1052 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
1053 if ((rc = diIAGRead(imap, fwd, &)))
1054 goto error_out;
1055 aiagp = (struct iag *) amp->data;
1056 }
1057
1058 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
1059 if ((rc = diIAGRead(imap, back, &bmp)))
1060 goto error_out;
1061 biagp = (struct iag *) bmp->data;
1062 }
1063 }
1064 }
1065
1066
1067
1068
1069 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1070 int inofreeback = le32_to_cpu(iagp->inofreeback);
1071 int inofreefwd = le32_to_cpu(iagp->inofreefwd);
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 if (inofreefwd >= 0) {
1082
1083 if (inofreefwd == fwd)
1084 ciagp = (struct iag *) amp->data;
1085 else if (inofreefwd == back)
1086 ciagp = (struct iag *) bmp->data;
1087 else {
1088 if ((rc =
1089 diIAGRead(imap, inofreefwd, &cmp)))
1090 goto error_out;
1091 ciagp = (struct iag *) cmp->data;
1092 }
1093 assert(ciagp != NULL);
1094 }
1095
1096 if (inofreeback >= 0) {
1097 if (inofreeback == fwd)
1098 diagp = (struct iag *) amp->data;
1099 else if (inofreeback == back)
1100 diagp = (struct iag *) bmp->data;
1101 else {
1102 if ((rc =
1103 diIAGRead(imap, inofreeback, &dmp)))
1104 goto error_out;
1105 diagp = (struct iag *) dmp->data;
1106 }
1107 assert(diagp != NULL);
1108 }
1109 }
1110
1111 IREAD_UNLOCK(ipimap);
1112
1113
1114
1115
1116 freepxd = iagp->inoext[extno];
1117 invalidate_pxd_metapages(ip, freepxd);
1118
1119
1120
1121
1122
1123
1124
1125 if (iagp->nfreeexts == 0) {
1126 if (fwd >= 0)
1127 aiagp->extfreeback = cpu_to_le32(iagno);
1128
1129 iagp->extfreefwd =
1130 cpu_to_le32(imap->im_agctl[agno].extfree);
1131 iagp->extfreeback = cpu_to_le32(-1);
1132 imap->im_agctl[agno].extfree = iagno;
1133 } else {
1134
1135
1136
1137 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1138 if (fwd >= 0)
1139 aiagp->extfreeback = iagp->extfreeback;
1140
1141 if (back >= 0)
1142 biagp->extfreefwd = iagp->extfreefwd;
1143 else
1144 imap->im_agctl[agno].extfree =
1145 le32_to_cpu(iagp->extfreefwd);
1146
1147 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
1148
1149 IAGFREE_LOCK(imap);
1150 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
1151 imap->im_freeiag = iagno;
1152 IAGFREE_UNLOCK(imap);
1153 }
1154 }
1155
1156
1157
1158
1159 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1160 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0)
1161 ciagp->inofreeback = iagp->inofreeback;
1162
1163 if ((int) le32_to_cpu(iagp->inofreeback) >= 0)
1164 diagp->inofreefwd = iagp->inofreefwd;
1165 else
1166 imap->im_agctl[agno].inofree =
1167 le32_to_cpu(iagp->inofreefwd);
1168
1169 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
1170 }
1171
1172
1173
1174
1175
1176
1177 if (iagp->pmap[extno] != 0) {
1178 jfs_error(ip->i_sb, "the pmap does not show inode free\n");
1179 }
1180 iagp->wmap[extno] = 0;
1181 PXDlength(&iagp->inoext[extno], 0);
1182 PXDaddress(&iagp->inoext[extno], 0);
1183
1184
1185
1186
1187
1188
1189 sword = extno >> L2EXTSPERSUM;
1190 bitno = extno & (EXTSPERSUM - 1);
1191 mask = HIGHORDER >> bitno;
1192 iagp->inosmap[sword] |= cpu_to_le32(mask);
1193 iagp->extsmap[sword] &= cpu_to_le32(~mask);
1194
1195
1196
1197
1198 le32_add_cpu(&iagp->nfreeinos, -(INOSPEREXT - 1));
1199 le32_add_cpu(&iagp->nfreeexts, 1);
1200
1201
1202
1203
1204 imap->im_agctl[agno].numfree -= (INOSPEREXT - 1);
1205 imap->im_agctl[agno].numinos -= INOSPEREXT;
1206 atomic_sub(INOSPEREXT - 1, &imap->im_numfree);
1207 atomic_sub(INOSPEREXT, &imap->im_numinos);
1208
1209 if (amp)
1210 write_metapage(amp);
1211 if (bmp)
1212 write_metapage(bmp);
1213 if (cmp)
1214 write_metapage(cmp);
1215 if (dmp)
1216 write_metapage(dmp);
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
1228 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
1229
1230
1231
1232
1233
1234
1235
1236
1237 tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
1238 pxdlock = (struct pxd_lock *) & tlck->lock;
1239 pxdlock->flag = mlckFREEPXD;
1240 pxdlock->pxd = freepxd;
1241 pxdlock->index = 1;
1242
1243 write_metapage(mp);
1244
1245 iplist[0] = ipimap;
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 iplist[1] = (struct inode *) (size_t)iagno;
1256 iplist[2] = (struct inode *) (size_t)extno;
1257
1258 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1259
1260 txEnd(tid);
1261 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
1262
1263
1264 AG_UNLOCK(imap, agno);
1265
1266 return (0);
1267
1268 error_out:
1269 IREAD_UNLOCK(ipimap);
1270
1271 if (amp)
1272 release_metapage(amp);
1273 if (bmp)
1274 release_metapage(bmp);
1275 if (cmp)
1276 release_metapage(cmp);
1277 if (dmp)
1278 release_metapage(dmp);
1279
1280 AG_UNLOCK(imap, agno);
1281
1282 release_metapage(mp);
1283
1284 return (rc);
1285 }
1286
1287
1288
1289
1290
1291 static inline void
1292 diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
1293 {
1294 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
1295
1296 ip->i_ino = (iagno << L2INOSPERIAG) + ino;
1297 jfs_ip->ixpxd = iagp->inoext[extno];
1298 jfs_ip->agstart = le64_to_cpu(iagp->agstart);
1299 jfs_ip->active_ag = -1;
1300 }
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319 int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1320 {
1321 int rc, ino, iagno, addext, extno, bitno, sword;
1322 int nwords, rem, i, agno;
1323 u32 mask, inosmap, extsmap;
1324 struct inode *ipimap;
1325 struct metapage *mp;
1326 ino_t inum;
1327 struct iag *iagp;
1328 struct inomap *imap;
1329
1330
1331
1332
1333 ipimap = JFS_SBI(pip->i_sb)->ipimap;
1334 imap = JFS_IP(ipimap)->i_imap;
1335 JFS_IP(ip)->ipimap = ipimap;
1336 JFS_IP(ip)->fileset = FILESYSTEM_I;
1337
1338
1339
1340
1341 if (dir) {
1342 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1343 AG_LOCK(imap, agno);
1344 goto tryag;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb));
1358
1359 if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
1360
1361
1362
1363
1364
1365 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1366 AG_LOCK(imap, agno);
1367 goto tryag;
1368 }
1369
1370 inum = pip->i_ino + 1;
1371 ino = inum & (INOSPERIAG - 1);
1372
1373
1374 if (ino == 0)
1375 inum = pip->i_ino;
1376
1377
1378 AG_LOCK(imap, agno);
1379
1380
1381 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
1382
1383
1384 iagno = INOTOIAG(inum);
1385 if ((rc = diIAGRead(imap, iagno, &mp))) {
1386 IREAD_UNLOCK(ipimap);
1387 AG_UNLOCK(imap, agno);
1388 return (rc);
1389 }
1390 iagp = (struct iag *) mp->data;
1391
1392
1393
1394
1395
1396 addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
1397
1398
1399
1400
1401
1402
1403
1404 if (iagp->nfreeinos || addext) {
1405
1406
1407 extno = ino >> L2INOSPEREXT;
1408
1409
1410
1411
1412 if (addressPXD(&iagp->inoext[extno])) {
1413 bitno = ino & (INOSPEREXT - 1);
1414 if ((bitno =
1415 diFindFree(le32_to_cpu(iagp->wmap[extno]),
1416 bitno))
1417 < INOSPEREXT) {
1418 ino = (extno << L2INOSPEREXT) + bitno;
1419
1420
1421
1422
1423 rc = diAllocBit(imap, iagp, ino);
1424 IREAD_UNLOCK(ipimap);
1425 if (rc) {
1426 assert(rc == -EIO);
1427 } else {
1428
1429
1430
1431 diInitInode(ip, iagno, ino, extno,
1432 iagp);
1433 mark_metapage_dirty(mp);
1434 }
1435 release_metapage(mp);
1436
1437
1438
1439 AG_UNLOCK(imap, agno);
1440 return (rc);
1441 }
1442
1443 if (!addext)
1444 extno =
1445 (extno ==
1446 EXTSPERIAG - 1) ? 0 : extno + 1;
1447 }
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465 bitno = extno & (EXTSPERSUM - 1);
1466 nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1;
1467 sword = extno >> L2EXTSPERSUM;
1468
1469
1470
1471
1472 mask = (bitno == 0) ? 0 : (ONES << (EXTSPERSUM - bitno));
1473 inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask;
1474 extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask;
1475
1476
1477
1478
1479 for (i = 0; i < nwords; i++) {
1480
1481
1482
1483 if (~inosmap) {
1484
1485
1486
1487
1488 rem = diFindFree(inosmap, 0);
1489 extno = (sword << L2EXTSPERSUM) + rem;
1490 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]),
1491 0);
1492 if (rem >= INOSPEREXT) {
1493 IREAD_UNLOCK(ipimap);
1494 release_metapage(mp);
1495 AG_UNLOCK(imap, agno);
1496 jfs_error(ip->i_sb,
1497 "can't find free bit in wmap\n");
1498 return -EIO;
1499 }
1500
1501
1502
1503
1504
1505 ino = (extno << L2INOSPEREXT) + rem;
1506 rc = diAllocBit(imap, iagp, ino);
1507 IREAD_UNLOCK(ipimap);
1508 if (rc)
1509 assert(rc == -EIO);
1510 else {
1511
1512
1513
1514 diInitInode(ip, iagno, ino, extno,
1515 iagp);
1516 mark_metapage_dirty(mp);
1517 }
1518 release_metapage(mp);
1519
1520
1521
1522 AG_UNLOCK(imap, agno);
1523 return (rc);
1524
1525 }
1526
1527
1528
1529
1530
1531 if (addext && ~extsmap) {
1532
1533
1534
1535 rem = diFindFree(extsmap, 0);
1536 extno = (sword << L2EXTSPERSUM) + rem;
1537
1538
1539
1540 if ((rc = diNewExt(imap, iagp, extno))) {
1541
1542
1543
1544
1545 if (rc == -ENOSPC)
1546 break;
1547
1548 assert(rc == -EIO);
1549 } else {
1550
1551
1552
1553 diInitInode(ip, iagno,
1554 extno << L2INOSPEREXT,
1555 extno, iagp);
1556 mark_metapage_dirty(mp);
1557 }
1558 release_metapage(mp);
1559
1560
1561 IREAD_UNLOCK(ipimap);
1562 AG_UNLOCK(imap, agno);
1563 return (rc);
1564 }
1565
1566
1567
1568 sword = (sword == SMAPSZ - 1) ? 0 : sword + 1;
1569 inosmap = le32_to_cpu(iagp->inosmap[sword]);
1570 extsmap = le32_to_cpu(iagp->extsmap[sword]);
1571 }
1572 }
1573
1574 IREAD_UNLOCK(ipimap);
1575
1576
1577 release_metapage(mp);
1578
1579 tryag:
1580
1581
1582
1583 rc = diAllocAG(imap, agno, dir, ip);
1584
1585 AG_UNLOCK(imap, agno);
1586
1587 if (rc != -ENOSPC)
1588 return (rc);
1589
1590
1591
1592
1593 return (diAllocAny(imap, agno, dir, ip));
1594 }
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626 static int
1627 diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
1628 {
1629 int rc, addext, numfree, numinos;
1630
1631
1632
1633
1634 numfree = imap->im_agctl[agno].numfree;
1635 numinos = imap->im_agctl[agno].numinos;
1636
1637 if (numfree > numinos) {
1638 jfs_error(ip->i_sb, "numfree > numinos\n");
1639 return -EIO;
1640 }
1641
1642
1643
1644
1645
1646
1647 if (dir)
1648 addext = (numfree < 64 ||
1649 (numfree < 256
1650 && ((numfree * 100) / numinos) <= 20));
1651 else
1652 addext = (numfree == 0);
1653
1654
1655
1656
1657 if (addext) {
1658
1659
1660
1661
1662 if ((rc = diAllocExt(imap, agno, ip)) != -ENOSPC)
1663 return (rc);
1664 }
1665
1666
1667
1668
1669 return (diAllocIno(imap, agno, ip));
1670 }
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696 static int
1697 diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
1698 {
1699 int ag, rc;
1700 int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
1701
1702
1703
1704
1705
1706 for (ag = agno + 1; ag <= maxag; ag++) {
1707 AG_LOCK(imap, ag);
1708
1709 rc = diAllocAG(imap, ag, dir, ip);
1710
1711 AG_UNLOCK(imap, ag);
1712
1713 if (rc != -ENOSPC)
1714 return (rc);
1715 }
1716
1717
1718
1719 for (ag = 0; ag < agno; ag++) {
1720 AG_LOCK(imap, ag);
1721
1722 rc = diAllocAG(imap, ag, dir, ip);
1723
1724 AG_UNLOCK(imap, ag);
1725
1726 if (rc != -ENOSPC)
1727 return (rc);
1728 }
1729
1730
1731
1732 return -ENOSPC;
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761 static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1762 {
1763 int iagno, ino, rc, rem, extno, sword;
1764 struct metapage *mp;
1765 struct iag *iagp;
1766
1767
1768
1769 if ((iagno = imap->im_agctl[agno].inofree) < 0)
1770 return -ENOSPC;
1771
1772
1773 IREAD_LOCK(imap->im_ipimap, RDWRLOCK_IMAP);
1774
1775
1776
1777 if ((rc = diIAGRead(imap, iagno, &mp))) {
1778 IREAD_UNLOCK(imap->im_ipimap);
1779 return (rc);
1780 }
1781 iagp = (struct iag *) mp->data;
1782
1783
1784
1785
1786 if (!iagp->nfreeinos) {
1787 IREAD_UNLOCK(imap->im_ipimap);
1788 release_metapage(mp);
1789 jfs_error(ip->i_sb, "nfreeinos = 0, but iag on freelist\n");
1790 return -EIO;
1791 }
1792
1793
1794
1795
1796 for (sword = 0;; sword++) {
1797 if (sword >= SMAPSZ) {
1798 IREAD_UNLOCK(imap->im_ipimap);
1799 release_metapage(mp);
1800 jfs_error(ip->i_sb,
1801 "free inode not found in summary map\n");
1802 return -EIO;
1803 }
1804
1805 if (~iagp->inosmap[sword])
1806 break;
1807 }
1808
1809
1810
1811
1812 rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0);
1813 if (rem >= EXTSPERSUM) {
1814 IREAD_UNLOCK(imap->im_ipimap);
1815 release_metapage(mp);
1816 jfs_error(ip->i_sb, "no free extent found\n");
1817 return -EIO;
1818 }
1819 extno = (sword << L2EXTSPERSUM) + rem;
1820
1821
1822
1823 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0);
1824 if (rem >= INOSPEREXT) {
1825 IREAD_UNLOCK(imap->im_ipimap);
1826 release_metapage(mp);
1827 jfs_error(ip->i_sb, "free inode not found\n");
1828 return -EIO;
1829 }
1830
1831
1832
1833 ino = (extno << L2INOSPEREXT) + rem;
1834
1835
1836
1837 rc = diAllocBit(imap, iagp, ino);
1838 IREAD_UNLOCK(imap->im_ipimap);
1839 if (rc) {
1840 release_metapage(mp);
1841 return (rc);
1842 }
1843
1844
1845
1846 diInitInode(ip, iagno, ino, extno, iagp);
1847 write_metapage(mp);
1848
1849 return (0);
1850 }
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
1886 {
1887 int rem, iagno, sword, extno, rc;
1888 struct metapage *mp;
1889 struct iag *iagp;
1890
1891
1892
1893
1894 if ((iagno = imap->im_agctl[agno].extfree) < 0) {
1895
1896
1897
1898 if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
1899 return (rc);
1900 }
1901 iagp = (struct iag *) mp->data;
1902
1903
1904
1905 iagp->agstart =
1906 cpu_to_le64(AGTOBLK(agno, imap->im_ipimap));
1907 } else {
1908
1909
1910 IREAD_LOCK(imap->im_ipimap, RDWRLOCK_IMAP);
1911 if ((rc = diIAGRead(imap, iagno, &mp))) {
1912 IREAD_UNLOCK(imap->im_ipimap);
1913 jfs_error(ip->i_sb, "error reading iag\n");
1914 return rc;
1915 }
1916 iagp = (struct iag *) mp->data;
1917 }
1918
1919
1920
1921 for (sword = 0;; sword++) {
1922 if (sword >= SMAPSZ) {
1923 release_metapage(mp);
1924 IREAD_UNLOCK(imap->im_ipimap);
1925 jfs_error(ip->i_sb, "free ext summary map not found\n");
1926 return -EIO;
1927 }
1928 if (~iagp->extsmap[sword])
1929 break;
1930 }
1931
1932
1933
1934 rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0);
1935 if (rem >= EXTSPERSUM) {
1936 release_metapage(mp);
1937 IREAD_UNLOCK(imap->im_ipimap);
1938 jfs_error(ip->i_sb, "free extent not found\n");
1939 return -EIO;
1940 }
1941 extno = (sword << L2EXTSPERSUM) + rem;
1942
1943
1944
1945 rc = diNewExt(imap, iagp, extno);
1946 IREAD_UNLOCK(imap->im_ipimap);
1947 if (rc) {
1948
1949
1950
1951
1952 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
1953 IAGFREE_LOCK(imap);
1954 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
1955 imap->im_freeiag = iagno;
1956 IAGFREE_UNLOCK(imap);
1957 }
1958 write_metapage(mp);
1959 return (rc);
1960 }
1961
1962
1963
1964 diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp);
1965
1966 write_metapage(mp);
1967
1968 return (0);
1969 }
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002 static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2003 {
2004 int extno, bitno, agno, sword, rc;
2005 struct metapage *amp = NULL, *bmp = NULL;
2006 struct iag *aiagp = NULL, *biagp = NULL;
2007 u32 mask;
2008
2009
2010
2011
2012
2013
2014 if (iagp->nfreeinos == cpu_to_le32(1)) {
2015 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
2016 if ((rc =
2017 diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
2018 &)))
2019 return (rc);
2020 aiagp = (struct iag *) amp->data;
2021 }
2022
2023 if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
2024 if ((rc =
2025 diIAGRead(imap,
2026 le32_to_cpu(iagp->inofreeback),
2027 &bmp))) {
2028 if (amp)
2029 release_metapage(amp);
2030 return (rc);
2031 }
2032 biagp = (struct iag *) bmp->data;
2033 }
2034 }
2035
2036
2037
2038
2039 agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb));
2040 extno = ino >> L2INOSPEREXT;
2041 bitno = ino & (INOSPEREXT - 1);
2042
2043
2044
2045 mask = HIGHORDER >> bitno;
2046
2047
2048
2049 if (((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) ||
2050 ((le32_to_cpu(iagp->wmap[extno]) & mask) != 0) ||
2051 (addressPXD(&iagp->inoext[extno]) == 0)) {
2052 if (amp)
2053 release_metapage(amp);
2054 if (bmp)
2055 release_metapage(bmp);
2056
2057 jfs_error(imap->im_ipimap->i_sb, "iag inconsistent\n");
2058 return -EIO;
2059 }
2060
2061
2062
2063 iagp->wmap[extno] |= cpu_to_le32(mask);
2064
2065
2066
2067
2068
2069 if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
2070 sword = extno >> L2EXTSPERSUM;
2071 bitno = extno & (EXTSPERSUM - 1);
2072 iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno);
2073 }
2074
2075
2076
2077
2078 if (iagp->nfreeinos == cpu_to_le32(1)) {
2079 if (amp) {
2080 aiagp->inofreeback = iagp->inofreeback;
2081 write_metapage(amp);
2082 }
2083
2084 if (bmp) {
2085 biagp->inofreefwd = iagp->inofreefwd;
2086 write_metapage(bmp);
2087 } else {
2088 imap->im_agctl[agno].inofree =
2089 le32_to_cpu(iagp->inofreefwd);
2090 }
2091 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
2092 }
2093
2094
2095
2096
2097 le32_add_cpu(&iagp->nfreeinos, -1);
2098 imap->im_agctl[agno].numfree -= 1;
2099 atomic_dec(&imap->im_numfree);
2100
2101 return (0);
2102 }
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2149 {
2150 int agno, iagno, fwd, back, freei = 0, sword, rc;
2151 struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL;
2152 struct metapage *amp, *bmp, *cmp, *dmp;
2153 struct inode *ipimap;
2154 s64 blkno, hint;
2155 int i, j;
2156 u32 mask;
2157 ino_t ino;
2158 struct dinode *dp;
2159 struct jfs_sb_info *sbi;
2160
2161
2162
2163 if (!iagp->nfreeexts) {
2164 jfs_error(imap->im_ipimap->i_sb, "no free extents\n");
2165 return -EIO;
2166 }
2167
2168
2169
2170 ipimap = imap->im_ipimap;
2171 sbi = JFS_SBI(ipimap->i_sb);
2172
2173 amp = bmp = cmp = NULL;
2174
2175
2176
2177 agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
2178 iagno = le32_to_cpu(iagp->iagnum);
2179
2180
2181
2182
2183
2184
2185 if (iagp->nfreeexts == cpu_to_le32(1)) {
2186 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
2187 if ((rc = diIAGRead(imap, fwd, &)))
2188 return (rc);
2189 aiagp = (struct iag *) amp->data;
2190 }
2191
2192 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
2193 if ((rc = diIAGRead(imap, back, &bmp)))
2194 goto error_out;
2195 biagp = (struct iag *) bmp->data;
2196 }
2197 } else {
2198
2199
2200
2201
2202
2203
2204 fwd = back = -1;
2205 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2206 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
2207 if ((rc = diIAGRead(imap, fwd, &)))
2208 goto error_out;
2209 aiagp = (struct iag *) amp->data;
2210 }
2211 }
2212 }
2213
2214
2215
2216
2217
2218
2219
2220
2221 if (iagp->nfreeinos == 0) {
2222 freei = imap->im_agctl[agno].inofree;
2223
2224 if (freei >= 0) {
2225 if (freei == fwd) {
2226 ciagp = aiagp;
2227 } else if (freei == back) {
2228 ciagp = biagp;
2229 } else {
2230 if ((rc = diIAGRead(imap, freei, &cmp)))
2231 goto error_out;
2232 ciagp = (struct iag *) cmp->data;
2233 }
2234 if (ciagp == NULL) {
2235 jfs_error(imap->im_ipimap->i_sb,
2236 "ciagp == NULL\n");
2237 rc = -EIO;
2238 goto error_out;
2239 }
2240 }
2241 }
2242
2243
2244
2245 if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0))
2246 hint = ((s64) agno << sbi->bmap->db_agl2size) - 1;
2247 else
2248 hint = addressPXD(&iagp->inoext[extno - 1]) +
2249 lengthPXD(&iagp->inoext[extno - 1]) - 1;
2250
2251 if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno)))
2252 goto error_out;
2253
2254
2255
2256
2257 ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT);
2258
2259
2260
2261
2262 for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) {
2263
2264
2265 dmp = get_metapage(ipimap, blkno + i, PSIZE, 1);
2266 if (dmp == NULL) {
2267 rc = -EIO;
2268 goto error_out;
2269 }
2270 dp = (struct dinode *) dmp->data;
2271
2272
2273
2274
2275 for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) {
2276 dp->di_inostamp = cpu_to_le32(sbi->inostamp);
2277 dp->di_number = cpu_to_le32(ino);
2278 dp->di_fileset = cpu_to_le32(FILESYSTEM_I);
2279 dp->di_mode = 0;
2280 dp->di_nlink = 0;
2281 PXDaddress(&(dp->di_ixpxd), blkno);
2282 PXDlength(&(dp->di_ixpxd), imap->im_nbperiext);
2283 }
2284 write_metapage(dmp);
2285 }
2286
2287
2288
2289
2290 if (iagp->nfreeexts == cpu_to_le32(1)) {
2291 if (fwd >= 0)
2292 aiagp->extfreeback = iagp->extfreeback;
2293
2294 if (back >= 0)
2295 biagp->extfreefwd = iagp->extfreefwd;
2296 else
2297 imap->im_agctl[agno].extfree =
2298 le32_to_cpu(iagp->extfreefwd);
2299
2300 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
2301 } else {
2302
2303
2304
2305 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2306 if (fwd >= 0)
2307 aiagp->extfreeback = cpu_to_le32(iagno);
2308
2309 iagp->extfreefwd = cpu_to_le32(fwd);
2310 iagp->extfreeback = cpu_to_le32(-1);
2311 imap->im_agctl[agno].extfree = iagno;
2312 }
2313 }
2314
2315
2316
2317
2318 if (iagp->nfreeinos == 0) {
2319 if (freei >= 0)
2320 ciagp->inofreeback = cpu_to_le32(iagno);
2321
2322 iagp->inofreefwd =
2323 cpu_to_le32(imap->im_agctl[agno].inofree);
2324 iagp->inofreeback = cpu_to_le32(-1);
2325 imap->im_agctl[agno].inofree = iagno;
2326 }
2327
2328
2329 PXDlength(&iagp->inoext[extno], imap->im_nbperiext);
2330 PXDaddress(&iagp->inoext[extno], blkno);
2331
2332
2333
2334
2335
2336 iagp->wmap[extno] = cpu_to_le32(HIGHORDER);
2337 iagp->pmap[extno] = 0;
2338
2339
2340
2341
2342
2343 sword = extno >> L2EXTSPERSUM;
2344 mask = HIGHORDER >> (extno & (EXTSPERSUM - 1));
2345 iagp->extsmap[sword] |= cpu_to_le32(mask);
2346 iagp->inosmap[sword] &= cpu_to_le32(~mask);
2347
2348
2349
2350
2351 le32_add_cpu(&iagp->nfreeinos, (INOSPEREXT - 1));
2352 le32_add_cpu(&iagp->nfreeexts, -1);
2353
2354
2355
2356 imap->im_agctl[agno].numfree += (INOSPEREXT - 1);
2357 imap->im_agctl[agno].numinos += INOSPEREXT;
2358
2359
2360
2361 atomic_add(INOSPEREXT - 1, &imap->im_numfree);
2362 atomic_add(INOSPEREXT, &imap->im_numinos);
2363
2364
2365
2366 if (amp)
2367 write_metapage(amp);
2368 if (bmp)
2369 write_metapage(bmp);
2370 if (cmp)
2371 write_metapage(cmp);
2372
2373 return (0);
2374
2375 error_out:
2376
2377
2378
2379 if (amp)
2380 release_metapage(amp);
2381 if (bmp)
2382 release_metapage(bmp);
2383 if (cmp)
2384 release_metapage(cmp);
2385
2386 return (rc);
2387 }
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429 static int
2430 diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2431 {
2432 int rc;
2433 int iagno, i, xlen;
2434 struct inode *ipimap;
2435 struct super_block *sb;
2436 struct jfs_sb_info *sbi;
2437 struct metapage *mp;
2438 struct iag *iagp;
2439 s64 xaddr = 0;
2440 s64 blkno;
2441 tid_t tid;
2442 struct inode *iplist[1];
2443
2444
2445 ipimap = imap->im_ipimap;
2446 sb = ipimap->i_sb;
2447 sbi = JFS_SBI(sb);
2448
2449
2450 IAGFREE_LOCK(imap);
2451
2452
2453
2454
2455 if (imap->im_freeiag >= 0) {
2456
2457 iagno = imap->im_freeiag;
2458
2459
2460 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2461 } else {
2462
2463
2464
2465
2466
2467 IWRITE_LOCK(ipimap, RDWRLOCK_IMAP);
2468
2469 if (ipimap->i_size >> L2PSIZE != imap->im_nextiag + 1) {
2470 IWRITE_UNLOCK(ipimap);
2471 IAGFREE_UNLOCK(imap);
2472 jfs_error(imap->im_ipimap->i_sb,
2473 "ipimap->i_size is wrong\n");
2474 return -EIO;
2475 }
2476
2477
2478
2479 iagno = imap->im_nextiag;
2480
2481
2482
2483
2484 if (iagno > (MAXIAGS - 1)) {
2485
2486 IWRITE_UNLOCK(ipimap);
2487
2488 rc = -ENOSPC;
2489 goto out;
2490 }
2491
2492
2493
2494
2495
2496 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2497
2498
2499 xlen = sbi->nbperpage;
2500 if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {
2501
2502 IWRITE_UNLOCK(ipimap);
2503
2504 goto out;
2505 }
2506
2507
2508
2509
2510
2511 tid = txBegin(sb, COMMIT_FORCE);
2512 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
2513
2514
2515 if ((rc =
2516 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2517 txEnd(tid);
2518 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2519
2520
2521
2522 dbFree(ipimap, xaddr, (s64) xlen);
2523
2524
2525 IWRITE_UNLOCK(ipimap);
2526
2527 goto out;
2528 }
2529
2530
2531 ipimap->i_size += PSIZE;
2532 inode_add_bytes(ipimap, PSIZE);
2533
2534
2535 mp = get_metapage(ipimap, blkno, PSIZE, 0);
2536 if (!mp) {
2537
2538
2539
2540
2541 xtTruncate(tid, ipimap, ipimap->i_size - PSIZE,
2542 COMMIT_PWMAP);
2543
2544 txAbort(tid, 0);
2545 txEnd(tid);
2546 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2547
2548
2549 IWRITE_UNLOCK(ipimap);
2550
2551 rc = -EIO;
2552 goto out;
2553 }
2554 iagp = (struct iag *) mp->data;
2555
2556
2557 memset(iagp, 0, sizeof(struct iag));
2558 iagp->iagnum = cpu_to_le32(iagno);
2559 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
2560 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
2561 iagp->iagfree = cpu_to_le32(-1);
2562 iagp->nfreeinos = 0;
2563 iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);
2564
2565
2566
2567
2568 for (i = 0; i < SMAPSZ; i++)
2569 iagp->inosmap[i] = cpu_to_le32(ONES);
2570
2571
2572
2573
2574 flush_metapage(mp);
2575
2576
2577
2578
2579
2580
2581 iplist[0] = ipimap;
2582 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2583
2584 txEnd(tid);
2585 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2586
2587 duplicateIXtree(sb, blkno, xlen, &xaddr);
2588
2589
2590 imap->im_nextiag += 1;
2591
2592
2593
2594
2595 imap->im_freeiag = iagno;
2596
2597
2598
2599
2600 diSync(ipimap);
2601
2602
2603 IWRITE_UNLOCK(ipimap);
2604 }
2605
2606
2607 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
2608
2609
2610 if ((rc = diIAGRead(imap, iagno, &mp))) {
2611 IREAD_UNLOCK(ipimap);
2612 rc = -EIO;
2613 goto out;
2614 }
2615 iagp = (struct iag *) mp->data;
2616
2617
2618 imap->im_freeiag = le32_to_cpu(iagp->iagfree);
2619 iagp->iagfree = cpu_to_le32(-1);
2620
2621
2622 *iagnop = iagno;
2623 *mpp = mp;
2624
2625 out:
2626
2627 IAGFREE_UNLOCK(imap);
2628
2629 return (rc);
2630 }
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653 static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
2654 {
2655 struct inode *ipimap = imap->im_ipimap;
2656 s64 blkno;
2657
2658
2659 blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage);
2660
2661
2662 *mpp = read_metapage(ipimap, blkno, PSIZE, 0);
2663 if (*mpp == NULL) {
2664 return -EIO;
2665 }
2666
2667 return (0);
2668 }
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684 static int diFindFree(u32 word, int start)
2685 {
2686 int bitno;
2687 assert(start < 32);
2688
2689 for (word <<= start, bitno = start; bitno < 32;
2690 bitno++, word <<= 1) {
2691 if ((word & HIGHORDER) == 0)
2692 break;
2693 }
2694 return (bitno);
2695 }
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714 int
2715 diUpdatePMap(struct inode *ipimap,
2716 unsigned long inum, bool is_free, struct tblock * tblk)
2717 {
2718 int rc;
2719 struct iag *iagp;
2720 struct metapage *mp;
2721 int iagno, ino, extno, bitno;
2722 struct inomap *imap;
2723 u32 mask;
2724 struct jfs_log *log;
2725 int lsn, difft, diffp;
2726 unsigned long flags;
2727
2728 imap = JFS_IP(ipimap)->i_imap;
2729
2730 iagno = INOTOIAG(inum);
2731
2732 if (iagno >= imap->im_nextiag) {
2733 jfs_error(ipimap->i_sb, "the iag is outside the map\n");
2734 return -EIO;
2735 }
2736
2737 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
2738 rc = diIAGRead(imap, iagno, &mp);
2739 IREAD_UNLOCK(ipimap);
2740 if (rc)
2741 return (rc);
2742 metapage_wait_for_io(mp);
2743 iagp = (struct iag *) mp->data;
2744
2745
2746
2747 ino = inum & (INOSPERIAG - 1);
2748 extno = ino >> L2INOSPEREXT;
2749 bitno = ino & (INOSPEREXT - 1);
2750 mask = HIGHORDER >> bitno;
2751
2752
2753
2754 if (is_free) {
2755
2756
2757
2758
2759
2760 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2761 jfs_error(ipimap->i_sb,
2762 "inode %ld not marked as allocated in wmap!\n",
2763 inum);
2764 }
2765 if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
2766 jfs_error(ipimap->i_sb,
2767 "inode %ld not marked as allocated in pmap!\n",
2768 inum);
2769 }
2770
2771 iagp->pmap[extno] &= cpu_to_le32(~mask);
2772 }
2773
2774
2775
2776 else {
2777
2778
2779
2780 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2781 release_metapage(mp);
2782 jfs_error(ipimap->i_sb,
2783 "the inode is not allocated in the working map\n");
2784 return -EIO;
2785 }
2786 if ((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) {
2787 release_metapage(mp);
2788 jfs_error(ipimap->i_sb,
2789 "the inode is not free in the persistent map\n");
2790 return -EIO;
2791 }
2792
2793 iagp->pmap[extno] |= cpu_to_le32(mask);
2794 }
2795
2796
2797
2798 lsn = tblk->lsn;
2799 log = JFS_SBI(tblk->sb)->log;
2800 LOGSYNC_LOCK(log, flags);
2801 if (mp->lsn != 0) {
2802
2803 logdiff(difft, lsn, log);
2804 logdiff(diffp, mp->lsn, log);
2805 if (difft < diffp) {
2806 mp->lsn = lsn;
2807
2808 list_move(&mp->synclist, &tblk->synclist);
2809 }
2810
2811 assert(mp->clsn);
2812 logdiff(difft, tblk->clsn, log);
2813 logdiff(diffp, mp->clsn, log);
2814 if (difft > diffp)
2815 mp->clsn = tblk->clsn;
2816 } else {
2817 mp->log = log;
2818 mp->lsn = lsn;
2819
2820 log->count++;
2821 list_add(&mp->synclist, &tblk->synclist);
2822 mp->clsn = tblk->clsn;
2823 }
2824 LOGSYNC_UNLOCK(log, flags);
2825 write_metapage(mp);
2826 return (0);
2827 }
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837 int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2838 {
2839 int rc, rcx = 0;
2840 struct inomap *imap = JFS_IP(ipimap)->i_imap;
2841 struct iag *iagp = NULL, *hiagp = NULL;
2842 struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
2843 struct metapage *bp, *hbp;
2844 int i, n, head;
2845 int numinos, xnuminos = 0, xnumfree = 0;
2846 s64 agstart;
2847
2848 jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d",
2849 imap->im_nextiag, atomic_read(&imap->im_numinos),
2850 atomic_read(&imap->im_numfree));
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861 for (i = 0; i < MAXAG; i++) {
2862 imap->im_agctl[i].inofree = -1;
2863 imap->im_agctl[i].extfree = -1;
2864 imap->im_agctl[i].numinos = 0;
2865 imap->im_agctl[i].numfree = 0;
2866 }
2867
2868
2869
2870
2871
2872
2873 for (i = 0; i < imap->im_nextiag; i++) {
2874 if ((rc = diIAGRead(imap, i, &bp))) {
2875 rcx = rc;
2876 continue;
2877 }
2878 iagp = (struct iag *) bp->data;
2879 if (le32_to_cpu(iagp->iagnum) != i) {
2880 release_metapage(bp);
2881 jfs_error(ipimap->i_sb, "unexpected value of iagnum\n");
2882 return -EIO;
2883 }
2884
2885
2886 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2887 release_metapage(bp);
2888 continue;
2889 }
2890
2891 agstart = le64_to_cpu(iagp->agstart);
2892 n = agstart >> mp->db_agl2size;
2893 iagp->agstart = cpu_to_le64((s64)n << mp->db_agl2size);
2894
2895
2896 numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts))
2897 << L2INOSPEREXT;
2898 if (numinos > 0) {
2899
2900 imap->im_agctl[n].numinos += numinos;
2901 xnuminos += numinos;
2902 }
2903
2904
2905 if ((int) le32_to_cpu(iagp->nfreeinos) > 0) {
2906 if ((head = imap->im_agctl[n].inofree) == -1) {
2907 iagp->inofreefwd = cpu_to_le32(-1);
2908 iagp->inofreeback = cpu_to_le32(-1);
2909 } else {
2910 if ((rc = diIAGRead(imap, head, &hbp))) {
2911 rcx = rc;
2912 goto nextiag;
2913 }
2914 hiagp = (struct iag *) hbp->data;
2915 hiagp->inofreeback = iagp->iagnum;
2916 iagp->inofreefwd = cpu_to_le32(head);
2917 iagp->inofreeback = cpu_to_le32(-1);
2918 write_metapage(hbp);
2919 }
2920
2921 imap->im_agctl[n].inofree =
2922 le32_to_cpu(iagp->iagnum);
2923
2924
2925 imap->im_agctl[n].numfree +=
2926 le32_to_cpu(iagp->nfreeinos);
2927 xnumfree += le32_to_cpu(iagp->nfreeinos);
2928 }
2929
2930
2931 if (le32_to_cpu(iagp->nfreeexts) > 0) {
2932 if ((head = imap->im_agctl[n].extfree) == -1) {
2933 iagp->extfreefwd = cpu_to_le32(-1);
2934 iagp->extfreeback = cpu_to_le32(-1);
2935 } else {
2936 if ((rc = diIAGRead(imap, head, &hbp))) {
2937 rcx = rc;
2938 goto nextiag;
2939 }
2940 hiagp = (struct iag *) hbp->data;
2941 hiagp->extfreeback = iagp->iagnum;
2942 iagp->extfreefwd = cpu_to_le32(head);
2943 iagp->extfreeback = cpu_to_le32(-1);
2944 write_metapage(hbp);
2945 }
2946
2947 imap->im_agctl[n].extfree =
2948 le32_to_cpu(iagp->iagnum);
2949 }
2950
2951 nextiag:
2952 write_metapage(bp);
2953 }
2954
2955 if (xnuminos != atomic_read(&imap->im_numinos) ||
2956 xnumfree != atomic_read(&imap->im_numfree)) {
2957 jfs_error(ipimap->i_sb, "numinos or numfree incorrect\n");
2958 return -EIO;
2959 }
2960
2961 return rcx;
2962 }
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972 static void duplicateIXtree(struct super_block *sb, s64 blkno,
2973 int xlen, s64 *xaddr)
2974 {
2975 struct jfs_superblock *j_sb;
2976 struct buffer_head *bh;
2977 struct inode *ip;
2978 tid_t tid;
2979
2980
2981 if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)
2982 return;
2983 ip = diReadSpecial(sb, FILESYSTEM_I, 1);
2984 if (ip == NULL) {
2985 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
2986 if (readSuper(sb, &bh))
2987 return;
2988 j_sb = (struct jfs_superblock *)bh->b_data;
2989 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
2990
2991 mark_buffer_dirty(bh);
2992 sync_dirty_buffer(bh);
2993 brelse(bh);
2994 return;
2995 }
2996
2997
2998 tid = txBegin(sb, COMMIT_FORCE);
2999
3000 if (xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0)) {
3001 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
3002 txAbort(tid, 1);
3003 goto cleanup;
3004
3005 }
3006
3007 ip->i_size += PSIZE;
3008 inode_add_bytes(ip, PSIZE);
3009 txCommit(tid, 1, &ip, COMMIT_FORCE);
3010 cleanup:
3011 txEnd(tid);
3012 diFreeSpecial(ip);
3013 }
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024 static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3025 {
3026 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3027 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3028
3029 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3030 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3031 jfs_set_inode_flags(ip);
3032
3033 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3034 if (sbi->umask != -1) {
3035 ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask);
3036
3037 if (S_ISDIR(ip->i_mode)) {
3038 if (ip->i_mode & 0400)
3039 ip->i_mode |= 0100;
3040 if (ip->i_mode & 0040)
3041 ip->i_mode |= 0010;
3042 if (ip->i_mode & 0004)
3043 ip->i_mode |= 0001;
3044 }
3045 }
3046 set_nlink(ip, le32_to_cpu(dip->di_nlink));
3047
3048 jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3049 if (!uid_valid(sbi->uid))
3050 ip->i_uid = jfs_ip->saved_uid;
3051 else {
3052 ip->i_uid = sbi->uid;
3053 }
3054
3055 jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3056 if (!gid_valid(sbi->gid))
3057 ip->i_gid = jfs_ip->saved_gid;
3058 else {
3059 ip->i_gid = sbi->gid;
3060 }
3061
3062 ip->i_size = le64_to_cpu(dip->di_size);
3063 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
3064 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
3065 ip->i_mtime.tv_sec = le32_to_cpu(dip->di_mtime.tv_sec);
3066 ip->i_mtime.tv_nsec = le32_to_cpu(dip->di_mtime.tv_nsec);
3067 ip->i_ctime.tv_sec = le32_to_cpu(dip->di_ctime.tv_sec);
3068 ip->i_ctime.tv_nsec = le32_to_cpu(dip->di_ctime.tv_nsec);
3069 ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks));
3070 ip->i_generation = le32_to_cpu(dip->di_gen);
3071
3072 jfs_ip->ixpxd = dip->di_ixpxd;
3073 jfs_ip->acl = dip->di_acl;
3074 jfs_ip->ea = dip->di_ea;
3075 jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
3076 jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
3077 jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
3078
3079 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) {
3080 jfs_ip->dev = le32_to_cpu(dip->di_rdev);
3081 ip->i_rdev = new_decode_dev(jfs_ip->dev);
3082 }
3083
3084 if (S_ISDIR(ip->i_mode)) {
3085 memcpy(&jfs_ip->u.dir, &dip->u._dir, 384);
3086 } else if (S_ISREG(ip->i_mode) || S_ISLNK(ip->i_mode)) {
3087 memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288);
3088 } else
3089 memcpy(&jfs_ip->i_inline_ea, &dip->di_inlineea, 128);
3090
3091
3092 jfs_ip->cflag = 0;
3093 jfs_ip->btindex = 0;
3094 jfs_ip->btorder = 0;
3095 jfs_ip->bxflag = 0;
3096 jfs_ip->blid = 0;
3097 jfs_ip->atlhead = 0;
3098 jfs_ip->atltail = 0;
3099 jfs_ip->xtlid = 0;
3100 return (0);
3101 }
3102
3103
3104
3105
3106
3107
3108 static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3109 {
3110 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3111 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3112
3113 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3114 dip->di_inostamp = cpu_to_le32(sbi->inostamp);
3115 dip->di_number = cpu_to_le32(ip->i_ino);
3116 dip->di_gen = cpu_to_le32(ip->i_generation);
3117 dip->di_size = cpu_to_le64(ip->i_size);
3118 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3119 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3120 if (!uid_valid(sbi->uid))
3121 dip->di_uid = cpu_to_le32(i_uid_read(ip));
3122 else
3123 dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3124 jfs_ip->saved_uid));
3125 if (!gid_valid(sbi->gid))
3126 dip->di_gid = cpu_to_le32(i_gid_read(ip));
3127 else
3128 dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3129 jfs_ip->saved_gid));
3130
3131
3132
3133
3134 if (sbi->umask == -1)
3135 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) |
3136 ip->i_mode);
3137 else
3138 dip->di_mode = cpu_to_le32(jfs_ip->mode2);
3139
3140 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
3141 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
3142 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
3143 dip->di_ctime.tv_nsec = cpu_to_le32(ip->i_ctime.tv_nsec);
3144 dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime.tv_sec);
3145 dip->di_mtime.tv_nsec = cpu_to_le32(ip->i_mtime.tv_nsec);
3146 dip->di_ixpxd = jfs_ip->ixpxd;
3147 dip->di_acl = jfs_ip->acl;
3148 dip->di_ea = jfs_ip->ea;
3149 dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
3150 dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
3151 dip->di_otime.tv_nsec = 0;
3152 dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
3153 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3154 dip->di_rdev = cpu_to_le32(jfs_ip->dev);
3155 }