1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <linux/fs.h>
45#include <linux/locks.h>
46#include "jfs_incore.h"
47#include "jfs_filsys.h"
48#include "jfs_dinode.h"
49#include "jfs_dmap.h"
50#include "jfs_imap.h"
51#include "jfs_metapage.h"
52#include "jfs_superblock.h"
53#include "jfs_debug.h"
54
55
56
57
58
59#define IAGFREE_LOCK_INIT(imap) init_MUTEX(&imap->im_freelock)
60#define IAGFREE_LOCK(imap) down(&imap->im_freelock)
61#define IAGFREE_UNLOCK(imap) up(&imap->im_freelock)
62
63
64#define AG_LOCK_INIT(imap,index) init_MUTEX(&(imap->im_aglock[index]))
65#define AG_LOCK(imap,agno) down(&imap->im_aglock[agno])
66#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno])
67
68
69
70
71extern struct address_space_operations jfs_aops;
72
73
74
75
76static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
77static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
78static int diAllocBit(struct inomap *, struct iag *, int);
79static int diAllocExt(struct inomap *, int, struct inode *);
80static int diAllocIno(struct inomap *, int, struct inode *);
81static int diFindFree(u32, int);
82static int diNewExt(struct inomap *, struct iag *, int);
83static int diNewIAG(struct inomap *, int *, int, struct metapage **);
84static void duplicateIXtree(struct super_block *, s64, int, s64 *);
85
86static int diIAGRead(struct inomap * imap, int, struct metapage **);
87static int copy_from_dinode(struct dinode *, struct inode *);
88static void copy_to_dinode(struct dinode *, struct inode *);
89
90
91
92
93
94
95#ifdef _JFS_DEBUG_IMAP
96#define DBG_DIINIT(imap) DBGdiInit(imap)
97#define DBG_DIALLOC(imap, ino) DBGdiAlloc(imap, ino)
98#define DBG_DIFREE(imap, ino) DBGdiFree(imap, ino)
99
100static void *DBGdiInit(struct inomap * imap);
101static void DBGdiAlloc(struct inomap * imap, ino_t ino);
102static void DBGdiFree(struct inomap * imap, ino_t ino);
103#else
104#define DBG_DIINIT(imap)
105#define DBG_DIALLOC(imap, ino)
106#define DBG_DIFREE(imap, ino)
107#endif
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126int diMount(struct inode *ipimap)
127{
128 struct inomap *imap;
129 struct metapage *mp;
130 int index;
131 struct dinomap *dinom_le;
132
133
134
135
136
137 imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
138 if (imap == NULL) {
139 jfs_err("diMount: kmalloc returned NULL!");
140 return -ENOMEM;
141 }
142
143
144
145 mp = read_metapage(ipimap,
146 IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
147 PSIZE, 0);
148 if (mp == NULL) {
149 kfree(imap);
150 return -EIO;
151 }
152
153
154 dinom_le = (struct dinomap *) mp->data;
155 imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag);
156 imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag);
157 atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos));
158 atomic_set(&imap->im_numfree, le32_to_cpu(dinom_le->in_numfree));
159 imap->im_nbperiext = le32_to_cpu(dinom_le->in_nbperiext);
160 imap->im_l2nbperiext = le32_to_cpu(dinom_le->in_l2nbperiext);
161 for (index = 0; index < MAXAG; index++) {
162 imap->im_agctl[index].inofree =
163 le32_to_cpu(dinom_le->in_agctl[index].inofree);
164 imap->im_agctl[index].extfree =
165 le32_to_cpu(dinom_le->in_agctl[index].extfree);
166 imap->im_agctl[index].numinos =
167 le32_to_cpu(dinom_le->in_agctl[index].numinos);
168 imap->im_agctl[index].numfree =
169 le32_to_cpu(dinom_le->in_agctl[index].numfree);
170 }
171
172
173 release_metapage(mp);
174
175
176
177
178
179 IAGFREE_LOCK_INIT(imap);
180
181
182 for (index = 0; index < MAXAG; index++) {
183 AG_LOCK_INIT(imap, index);
184 }
185
186
187
188
189 imap->im_ipimap = ipimap;
190 JFS_IP(ipimap)->i_imap = imap;
191
192
193
194 return (0);
195}
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212int diUnmount(struct inode *ipimap, int mounterror)
213{
214 struct inomap *imap = JFS_IP(ipimap)->i_imap;
215
216
217
218
219
220 if (!(mounterror || isReadOnly(ipimap)))
221 diSync(ipimap);
222
223
224
225
226 truncate_inode_pages(ipimap->i_mapping, 0);
227
228
229
230
231 kfree(imap);
232
233 return (0);
234}
235
236
237
238
239
240int diSync(struct inode *ipimap)
241{
242 struct dinomap *dinom_le;
243 struct inomap *imp = JFS_IP(ipimap)->i_imap;
244 struct metapage *mp;
245 int index;
246
247
248
249
250
251 mp = get_metapage(ipimap,
252 IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
253 PSIZE, 0);
254 if (mp == NULL) {
255 jfs_err("diSync: get_metapage failed!");
256 return -EIO;
257 }
258
259
260 dinom_le = (struct dinomap *) mp->data;
261 dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag);
262 dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag);
263 dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos));
264 dinom_le->in_numfree = cpu_to_le32(atomic_read(&imp->im_numfree));
265 dinom_le->in_nbperiext = cpu_to_le32(imp->im_nbperiext);
266 dinom_le->in_l2nbperiext = cpu_to_le32(imp->im_l2nbperiext);
267 for (index = 0; index < MAXAG; index++) {
268 dinom_le->in_agctl[index].inofree =
269 cpu_to_le32(imp->im_agctl[index].inofree);
270 dinom_le->in_agctl[index].extfree =
271 cpu_to_le32(imp->im_agctl[index].extfree);
272 dinom_le->in_agctl[index].numinos =
273 cpu_to_le32(imp->im_agctl[index].numinos);
274 dinom_le->in_agctl[index].numfree =
275 cpu_to_le32(imp->im_agctl[index].numfree);
276 }
277
278
279 write_metapage(mp);
280
281
282
283
284 fsync_inode_data_buffers(ipimap);
285
286 diWriteSpecial(ipimap, 0);
287
288 return (0);
289}
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325int diRead(struct inode *ip)
326{
327 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
328 int iagno, ino, extno, rc;
329 struct inode *ipimap;
330 struct dinode *dp;
331 struct iag *iagp;
332 struct metapage *mp;
333 s64 blkno, agstart;
334 struct inomap *imap;
335 int block_offset;
336 int inodes_left;
337 uint pageno;
338 int rel_inode;
339
340 jfs_info("diRead: ino = %ld", ip->i_ino);
341
342 ipimap = sbi->ipimap;
343 JFS_IP(ip)->ipimap = ipimap;
344
345
346 iagno = INOTOIAG(ip->i_ino);
347
348
349 imap = JFS_IP(ipimap)->i_imap;
350 IREAD_LOCK(ipimap);
351 rc = diIAGRead(imap, iagno, &mp);
352 IREAD_UNLOCK(ipimap);
353 if (rc) {
354 jfs_err("diRead: diIAGRead returned %d", rc);
355 return (rc);
356 }
357
358 iagp = (struct iag *) mp->data;
359
360
361 ino = ip->i_ino & (INOSPERIAG - 1);
362 extno = ino >> L2INOSPEREXT;
363
364 if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) ||
365 (addressPXD(&iagp->inoext[extno]) == 0)) {
366 release_metapage(mp);
367 return -ESTALE;
368 }
369
370
371
372
373 blkno = INOPBLK(&iagp->inoext[extno], ino, sbi->l2nbperpage);
374
375
376 agstart = le64_to_cpu(iagp->agstart);
377
378 release_metapage(mp);
379
380 rel_inode = (ino & (INOSPERPAGE - 1));
381 pageno = blkno >> sbi->l2nbperpage;
382
383 if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
384
385
386
387 inodes_left =
388 (sbi->nbperpage - block_offset) << sbi->l2niperblk;
389
390 if (rel_inode < inodes_left)
391 rel_inode += block_offset << sbi->l2niperblk;
392 else {
393 pageno += 1;
394 rel_inode -= inodes_left;
395 }
396 }
397
398
399 mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
400 if (mp == 0) {
401 jfs_err("diRead: read_metapage failed");
402 return -EIO;
403 }
404
405
406 dp = (struct dinode *) mp->data;
407 dp += rel_inode;
408
409 if (ip->i_ino != le32_to_cpu(dp->di_number)) {
410 jfs_error(ip->i_sb, "diRead: i_ino != di_number");
411 rc = -EIO;
412 } else if (le32_to_cpu(dp->di_nlink) == 0)
413 rc = -ESTALE;
414 else
415
416 rc = copy_from_dinode(dp, ip);
417
418 release_metapage(mp);
419
420
421 JFS_IP(ip)->agno = BLKTOAG(agstart, sbi);
422 JFS_IP(ip)->active_ag = -1;
423
424 return (rc);
425}
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
451{
452 struct jfs_sb_info *sbi = JFS_SBI(sb);
453 uint address;
454 struct dinode *dp;
455 struct inode *ip;
456 struct metapage *mp;
457 int rc;
458
459 ip = new_inode(sb);
460 if (ip == NULL) {
461 jfs_err("diReadSpecial: new_inode returned NULL!");
462 return ip;
463 }
464
465 rc = alloc_jfs_inode(ip);
466 if (rc) {
467 make_bad_inode(ip);
468 iput(ip);
469 return NULL;
470 }
471
472 if (secondary) {
473 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
474 JFS_IP(ip)->ipimap = sbi->ipaimap2;
475 } else {
476 address = AITBL_OFF >> L2PSIZE;
477 JFS_IP(ip)->ipimap = sbi->ipaimap;
478 }
479
480 ASSERT(inum < INOSPEREXT);
481
482 ip->i_ino = inum;
483
484 address += inum >> 3;
485
486
487 mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
488 if (mp == NULL) {
489 ip->i_nlink = 1;
490 iput(ip);
491 return (NULL);
492 }
493
494
495 dp = (struct dinode *) (mp->data);
496 dp += inum % 8;
497
498
499 if ((copy_from_dinode(dp, ip)) != 0) {
500
501 ip->i_nlink = 1;
502 iput(ip);
503
504 release_metapage(mp);
505 return (NULL);
506
507 }
508
509 ip->i_mapping->a_ops = &jfs_aops;
510 ip->i_mapping->gfp_mask = GFP_NOFS;
511
512 if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
513 sbi->gengen = le32_to_cpu(dp->di_gengen);
514 sbi->inostamp = le32_to_cpu(dp->di_inostamp);
515 }
516
517
518 release_metapage(mp);
519
520 return (ip);
521}
522
523
524
525
526
527
528
529
530
531
532
533
534
535void diWriteSpecial(struct inode *ip, int secondary)
536{
537 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
538 uint address;
539 struct dinode *dp;
540 ino_t inum = ip->i_ino;
541 struct metapage *mp;
542
543 ip->i_state &= ~I_DIRTY;
544
545 if (secondary)
546 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
547 else
548 address = AITBL_OFF >> L2PSIZE;
549
550 ASSERT(inum < INOSPEREXT);
551
552 address += inum >> 3;
553
554
555 mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
556 if (mp == NULL) {
557 jfs_err("diWriteSpecial: failed to read aggregate inode "
558 "extent!");
559 return;
560 }
561
562
563 dp = (struct dinode *) (mp->data);
564 dp += inum % 8;
565
566
567 copy_to_dinode(dp, ip);
568 memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);
569
570 if (inum == FILESYSTEM_I)
571 dp->di_gengen = cpu_to_le32(sbi->gengen);
572
573
574 write_metapage(mp);
575}
576
577
578
579
580
581
582void diFreeSpecial(struct inode *ip)
583{
584 if (ip == NULL) {
585 jfs_err("diFreeSpecial called with NULL ip!");
586 return;
587 }
588 fsync_inode_data_buffers(ip);
589 truncate_inode_pages(ip->i_mapping, 0);
590 iput(ip);
591}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619int diWrite(tid_t tid, struct inode *ip)
620{
621 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
622 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
623 int rc = 0;
624 s32 ino;
625 struct dinode *dp;
626 s64 blkno;
627 int block_offset;
628 int inodes_left;
629 struct metapage *mp;
630 uint pageno;
631 int rel_inode;
632 int dioffset;
633 struct inode *ipimap;
634 uint type;
635 lid_t lid;
636 struct tlock *ditlck, *tlck;
637 struct linelock *dilinelock, *ilinelock;
638 struct lv *lv;
639 int n;
640
641 ipimap = jfs_ip->ipimap;
642
643 ino = ip->i_ino & (INOSPERIAG - 1);
644
645 if (!addressPXD(&(jfs_ip->ixpxd)) ||
646 (lengthPXD(&(jfs_ip->ixpxd)) !=
647 JFS_IP(ipimap)->i_imap->im_nbperiext)) {
648 jfs_error(ip->i_sb, "diWrite: ixpxd invalid");
649 return -EIO;
650 }
651
652
653
654
655
656 blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);
657
658 rel_inode = (ino & (INOSPERPAGE - 1));
659 pageno = blkno >> sbi->l2nbperpage;
660
661 if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
662
663
664
665 inodes_left =
666 (sbi->nbperpage - block_offset) << sbi->l2niperblk;
667
668 if (rel_inode < inodes_left)
669 rel_inode += block_offset << sbi->l2niperblk;
670 else {
671 pageno += 1;
672 rel_inode -= inodes_left;
673 }
674 }
675
676 retry:
677 mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
678 if (mp == 0)
679 return -EIO;
680
681
682 dp = (struct dinode *) mp->data;
683 dp += rel_inode;
684
685 dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
686
687
688
689
690
691 if ((ditlck =
692 txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
693 goto retry;
694 dilinelock = (struct linelock *) & ditlck->lock;
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709 if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {
710
711
712
713
714 xtpage_t *p, *xp;
715 xad_t *xad;
716
717 jfs_ip->xtlid = 0;
718 tlck = lid_to_tlock(lid);
719 assert(tlck->type & tlckXTREE);
720 tlck->type |= tlckBTROOT;
721 tlck->mp = mp;
722 ilinelock = (struct linelock *) & tlck->lock;
723
724
725
726
727 p = &jfs_ip->i_xtroot;
728 xp = (xtpage_t *) &dp->di_dirtable;
729 lv = ilinelock->lv;
730 for (n = 0; n < ilinelock->index; n++, lv++) {
731 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
732 lv->length << L2XTSLOTSIZE);
733 }
734
735
736 xad = &xp->xad[XTENTRYSTART];
737 for (n = XTENTRYSTART;
738 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
739 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
740 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
741 }
742
743 if ((lid = jfs_ip->blid) == 0)
744 goto inlineData;
745 jfs_ip->blid = 0;
746
747 tlck = lid_to_tlock(lid);
748 type = tlck->type;
749 tlck->type |= tlckBTROOT;
750 tlck->mp = mp;
751 ilinelock = (struct linelock *) & tlck->lock;
752
753
754
755
756 if (type & tlckXTREE) {
757 xtpage_t *p, *xp;
758 xad_t *xad;
759
760
761
762
763 p = &jfs_ip->i_xtroot;
764 xp = &dp->di_xtroot;
765 lv = ilinelock->lv;
766 for (n = 0; n < ilinelock->index; n++, lv++) {
767 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
768 lv->length << L2XTSLOTSIZE);
769 }
770
771
772 xad = &xp->xad[XTENTRYSTART];
773 for (n = XTENTRYSTART;
774 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
775 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
776 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
777 }
778
779
780
781 else if (type & tlckDTREE) {
782 dtpage_t *p, *xp;
783
784
785
786
787 p = (dtpage_t *) &jfs_ip->i_dtroot;
788 xp = (dtpage_t *) & dp->di_dtroot;
789 lv = ilinelock->lv;
790 for (n = 0; n < ilinelock->index; n++, lv++) {
791 memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
792 lv->length << L2DTSLOTSIZE);
793 }
794 } else {
795 jfs_err("diWrite: UFO tlock");
796 }
797
798 inlineData:
799
800
801
802 if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
803 lv = & dilinelock->lv[dilinelock->index];
804 lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
805 lv->length = 2;
806 memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);
807 dilinelock->index++;
808 }
809
810
811
812
813 if (test_cflag(COMMIT_Inlineea, ip)) {
814 lv = & dilinelock->lv[dilinelock->index];
815 lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
816 lv->length = 1;
817 memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);
818 dilinelock->index++;
819
820 clear_cflag(COMMIT_Inlineea, ip);
821 }
822
823
824
825
826
827 lv = & dilinelock->lv[dilinelock->index];
828 lv->offset = dioffset >> L2INODESLOTSIZE;
829 copy_to_dinode(dp, ip);
830 if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
831 lv->length = 2;
832 memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);
833 } else
834 lv->length = 1;
835 dilinelock->index++;
836
837#ifdef _JFS_FASTDASD
838
839
840
841
842
843 if (S_ISDIR(ip->i_mode)
844 && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
845 bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(struct dasd));
846#endif
847
848
849
850
851 write_metapage(mp);
852
853 return (rc);
854}
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895int diFree(struct inode *ip)
896{
897 int rc;
898 ino_t inum = ip->i_ino;
899 struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;
900 struct metapage *mp, *amp, *bmp, *cmp, *dmp;
901 int iagno, ino, extno, bitno, sword, agno;
902 int back, fwd;
903 u32 bitmap, mask;
904 struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
905 struct inomap *imap = JFS_IP(ipimap)->i_imap;
906 pxd_t freepxd;
907 tid_t tid;
908 struct inode *iplist[3];
909 struct tlock *tlck;
910 struct pxd_lock *pxdlock;
911
912
913
914
915
916 aiagp = biagp = ciagp = diagp = NULL;
917
918
919
920 iagno = INOTOIAG(inum);
921
922
923
924
925 if (iagno >= imap->im_nextiag) {
926 dump_mem("imap", imap, 32);
927 jfs_error(ip->i_sb,
928 "diFree: inum = %d, iagno = %d, nextiag = %d",
929 (uint) inum, iagno, imap->im_nextiag);
930 return -EIO;
931 }
932
933
934
935 agno = JFS_IP(ip)->agno;
936
937
938
939 AG_LOCK(imap, agno);
940
941
942
943
944 IREAD_LOCK(ipimap);
945
946
947
948 if ((rc = diIAGRead(imap, iagno, &mp))) {
949 IREAD_UNLOCK(ipimap);
950 AG_UNLOCK(imap, agno);
951 return (rc);
952 }
953 iagp = (struct iag *) mp->data;
954
955
956
957
958 ino = inum & (INOSPERIAG - 1);
959 extno = ino >> L2INOSPEREXT;
960 bitno = ino & (INOSPEREXT - 1);
961 mask = HIGHORDER >> bitno;
962
963 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
964 jfs_error(ip->i_sb,
965 "diFree: wmap shows inode already free");
966 }
967
968 if (!addressPXD(&iagp->inoext[extno])) {
969 release_metapage(mp);
970 IREAD_UNLOCK(ipimap);
971 AG_UNLOCK(imap, agno);
972 jfs_error(ip->i_sb, "diFree: invalid inoext");
973 return -EIO;
974 }
975
976
977
978 bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
979
980 if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
981 release_metapage(mp);
982 IREAD_UNLOCK(ipimap);
983 AG_UNLOCK(imap, agno);
984 jfs_error(ip->i_sb, "diFree: numfree > numinos");
985 return -EIO;
986 }
987
988
989
990
991 if (bitmap ||
992 imap->im_agctl[agno].numfree < 96 ||
993 (imap->im_agctl[agno].numfree < 288 &&
994 (((imap->im_agctl[agno].numfree * 100) /
995 imap->im_agctl[agno].numinos) <= 25))) {
996
997
998
999
1000 if (iagp->nfreeinos == 0) {
1001
1002
1003
1004
1005
1006 if ((fwd = imap->im_agctl[agno].inofree) >= 0) {
1007
1008
1009
1010 if ((rc = diIAGRead(imap, fwd, &))) {
1011 IREAD_UNLOCK(ipimap);
1012 AG_UNLOCK(imap, agno);
1013 release_metapage(mp);
1014 return (rc);
1015 }
1016 aiagp = (struct iag *) amp->data;
1017
1018
1019
1020 aiagp->inofreeback = cpu_to_le32(iagno);
1021
1022 write_metapage(amp);
1023 }
1024
1025
1026
1027
1028 iagp->inofreefwd =
1029 cpu_to_le32(imap->im_agctl[agno].inofree);
1030 iagp->inofreeback = -1;
1031 imap->im_agctl[agno].inofree = iagno;
1032 }
1033 IREAD_UNLOCK(ipimap);
1034
1035
1036
1037
1038
1039
1040 if (iagp->wmap[extno] == ONES) {
1041 sword = extno >> L2EXTSPERSUM;
1042 bitno = extno & (EXTSPERSUM - 1);
1043 iagp->inosmap[sword] &=
1044 cpu_to_le32(~(HIGHORDER >> bitno));
1045 }
1046
1047
1048
1049 iagp->wmap[extno] = cpu_to_le32(bitmap);
1050 DBG_DIFREE(imap, inum);
1051
1052
1053
1054
1055 iagp->nfreeinos =
1056 cpu_to_le32(le32_to_cpu(iagp->nfreeinos) + 1);
1057 imap->im_agctl[agno].numfree += 1;
1058 atomic_inc(&imap->im_numfree);
1059
1060
1061
1062 AG_UNLOCK(imap, agno);
1063
1064
1065 write_metapage(mp);
1066
1067 return (0);
1068 }
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079 amp = bmp = cmp = dmp = NULL;
1080 fwd = back = -1;
1081
1082
1083
1084
1085 if (iagp->nfreeexts == 0) {
1086
1087
1088
1089
1090
1091
1092 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
1093 if ((rc = diIAGRead(imap, fwd, &)))
1094 goto error_out;
1095 aiagp = (struct iag *) amp->data;
1096 }
1097 } else {
1098
1099
1100
1101
1102
1103 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1104
1105
1106
1107
1108
1109 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
1110 if ((rc = diIAGRead(imap, fwd, &)))
1111 goto error_out;
1112 aiagp = (struct iag *) amp->data;
1113 }
1114
1115 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
1116 if ((rc = diIAGRead(imap, back, &bmp)))
1117 goto error_out;
1118 biagp = (struct iag *) bmp->data;
1119 }
1120 }
1121 }
1122
1123
1124
1125
1126 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1127 int inofreeback = le32_to_cpu(iagp->inofreeback);
1128 int inofreefwd = le32_to_cpu(iagp->inofreefwd);
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138 if (inofreefwd >= 0) {
1139
1140 if (inofreefwd == fwd)
1141 ciagp = (struct iag *) amp->data;
1142 else if (inofreefwd == back)
1143 ciagp = (struct iag *) bmp->data;
1144 else {
1145 if ((rc =
1146 diIAGRead(imap, inofreefwd, &cmp)))
1147 goto error_out;
1148 ciagp = (struct iag *) cmp->data;
1149 }
1150 assert(ciagp != NULL);
1151 }
1152
1153 if (inofreeback >= 0) {
1154 if (inofreeback == fwd)
1155 diagp = (struct iag *) amp->data;
1156 else if (inofreeback == back)
1157 diagp = (struct iag *) bmp->data;
1158 else {
1159 if ((rc =
1160 diIAGRead(imap, inofreeback, &dmp)))
1161 goto error_out;
1162 diagp = (struct iag *) dmp->data;
1163 }
1164 assert(diagp != NULL);
1165 }
1166 }
1167
1168 IREAD_UNLOCK(ipimap);
1169
1170
1171
1172
1173 freepxd = iagp->inoext[extno];
1174 invalidate_pxd_metapages(ip, freepxd);
1175
1176
1177
1178
1179
1180
1181
1182 if (iagp->nfreeexts == 0) {
1183 if (fwd >= 0)
1184 aiagp->extfreeback = cpu_to_le32(iagno);
1185
1186 iagp->extfreefwd =
1187 cpu_to_le32(imap->im_agctl[agno].extfree);
1188 iagp->extfreeback = -1;
1189 imap->im_agctl[agno].extfree = iagno;
1190 } else {
1191
1192
1193
1194 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1195 if (fwd >= 0)
1196 aiagp->extfreeback = iagp->extfreeback;
1197
1198 if (back >= 0)
1199 biagp->extfreefwd = iagp->extfreefwd;
1200 else
1201 imap->im_agctl[agno].extfree =
1202 le32_to_cpu(iagp->extfreefwd);
1203
1204 iagp->extfreefwd = iagp->extfreeback = -1;
1205
1206 IAGFREE_LOCK(imap);
1207 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
1208 imap->im_freeiag = iagno;
1209 IAGFREE_UNLOCK(imap);
1210 }
1211 }
1212
1213
1214
1215
1216 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1217 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0)
1218 ciagp->inofreeback = iagp->inofreeback;
1219
1220 if ((int) le32_to_cpu(iagp->inofreeback) >= 0)
1221 diagp->inofreefwd = iagp->inofreefwd;
1222 else
1223 imap->im_agctl[agno].inofree =
1224 le32_to_cpu(iagp->inofreefwd);
1225
1226 iagp->inofreefwd = iagp->inofreeback = -1;
1227 }
1228
1229
1230
1231
1232
1233
1234 if (iagp->pmap[extno] != 0) {
1235 jfs_error(ip->i_sb, "diFree: the pmap does not show inode free");
1236 }
1237 iagp->wmap[extno] = 0;
1238 DBG_DIFREE(imap, inum);
1239 PXDlength(&iagp->inoext[extno], 0);
1240 PXDaddress(&iagp->inoext[extno], 0);
1241
1242
1243
1244
1245
1246
1247 sword = extno >> L2EXTSPERSUM;
1248 bitno = extno & (EXTSPERSUM - 1);
1249 mask = HIGHORDER >> bitno;
1250 iagp->inosmap[sword] |= cpu_to_le32(mask);
1251 iagp->extsmap[sword] &= cpu_to_le32(~mask);
1252
1253
1254
1255
1256 iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) -
1257 (INOSPEREXT - 1));
1258 iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) + 1);
1259
1260
1261
1262
1263 imap->im_agctl[agno].numfree -= (INOSPEREXT - 1);
1264 imap->im_agctl[agno].numinos -= INOSPEREXT;
1265 atomic_sub(INOSPEREXT - 1, &imap->im_numfree);
1266 atomic_sub(INOSPEREXT, &imap->im_numinos);
1267
1268 if (amp)
1269 write_metapage(amp);
1270 if (bmp)
1271 write_metapage(bmp);
1272 if (cmp)
1273 write_metapage(cmp);
1274 if (dmp)
1275 write_metapage(dmp);
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
1287 down(&JFS_IP(ipimap)->commit_sem);
1288
1289
1290
1291
1292
1293
1294
1295
1296 tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
1297 pxdlock = (struct pxd_lock *) & tlck->lock;
1298 pxdlock->flag = mlckFREEPXD;
1299 pxdlock->pxd = freepxd;
1300 pxdlock->index = 1;
1301
1302 write_metapage(mp);
1303
1304 iplist[0] = ipimap;
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 iplist[1] = (struct inode *) (size_t)iagno;
1315 iplist[2] = (struct inode *) (size_t)extno;
1316
1317 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1318
1319 txEnd(tid);
1320 up(&JFS_IP(ipimap)->commit_sem);
1321
1322
1323 AG_UNLOCK(imap, agno);
1324
1325 return (0);
1326
1327 error_out:
1328 IREAD_UNLOCK(ipimap);
1329
1330 if (amp)
1331 release_metapage(amp);
1332 if (bmp)
1333 release_metapage(bmp);
1334 if (cmp)
1335 release_metapage(cmp);
1336 if (dmp)
1337 release_metapage(dmp);
1338
1339 AG_UNLOCK(imap, agno);
1340
1341 release_metapage(mp);
1342
1343 return (rc);
1344}
1345
1346
1347
1348
1349
1350static inline void
1351diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
1352{
1353 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
1354 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
1355
1356 ip->i_ino = (iagno << L2INOSPERIAG) + ino;
1357 DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino);
1358 jfs_ip->ixpxd = iagp->inoext[extno];
1359 jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
1360 jfs_ip->active_ag = -1;
1361}
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
1381{
1382 int rc, ino, iagno, addext, extno, bitno, sword;
1383 int nwords, rem, i, agno;
1384 u32 mask, inosmap, extsmap;
1385 struct inode *ipimap;
1386 struct metapage *mp;
1387 ino_t inum;
1388 struct iag *iagp;
1389 struct inomap *imap;
1390
1391
1392
1393
1394 ipimap = JFS_SBI(pip->i_sb)->ipimap;
1395 imap = JFS_IP(ipimap)->i_imap;
1396 JFS_IP(ip)->ipimap = ipimap;
1397 JFS_IP(ip)->fileset = FILESYSTEM_I;
1398
1399
1400
1401
1402 if (dir == TRUE) {
1403 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1404 AG_LOCK(imap, agno);
1405 goto tryag;
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418 agno = JFS_IP(pip)->agno;
1419
1420 if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
1421
1422
1423
1424
1425
1426 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1427 AG_LOCK(imap, agno);
1428 goto tryag;
1429 }
1430
1431 inum = pip->i_ino + 1;
1432 ino = inum & (INOSPERIAG - 1);
1433
1434
1435 if (ino == 0)
1436 inum = pip->i_ino;
1437
1438
1439 AG_LOCK(imap, agno);
1440
1441
1442 IREAD_LOCK(ipimap);
1443
1444
1445 iagno = INOTOIAG(inum);
1446 if ((rc = diIAGRead(imap, iagno, &mp))) {
1447 IREAD_UNLOCK(ipimap);
1448 AG_UNLOCK(imap, agno);
1449 return (rc);
1450 }
1451 iagp = (struct iag *) mp->data;
1452
1453
1454
1455
1456
1457 addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
1458
1459
1460
1461
1462
1463
1464
1465 if (iagp->nfreeinos || addext) {
1466
1467
1468 extno = ino >> L2INOSPEREXT;
1469
1470
1471
1472
1473 if (addressPXD(&iagp->inoext[extno])) {
1474 bitno = ino & (INOSPEREXT - 1);
1475 if ((bitno =
1476 diFindFree(le32_to_cpu(iagp->wmap[extno]),
1477 bitno))
1478 < INOSPEREXT) {
1479 ino = (extno << L2INOSPEREXT) + bitno;
1480
1481
1482
1483
1484 rc = diAllocBit(imap, iagp, ino);
1485 IREAD_UNLOCK(ipimap);
1486 if (rc) {
1487 assert(rc == -EIO);
1488 } else {
1489
1490
1491
1492 diInitInode(ip, iagno, ino, extno,
1493 iagp);
1494 mark_metapage_dirty(mp);
1495 }
1496 release_metapage(mp);
1497
1498
1499
1500 AG_UNLOCK(imap, agno);
1501 return (rc);
1502 }
1503
1504 if (!addext)
1505 extno =
1506 (extno ==
1507 EXTSPERIAG - 1) ? 0 : extno + 1;
1508 }
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 bitno = extno & (EXTSPERSUM - 1);
1527 nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1;
1528 sword = extno >> L2EXTSPERSUM;
1529
1530
1531
1532
1533 mask = ONES << (EXTSPERSUM - bitno);
1534 inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask;
1535 extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask;
1536
1537
1538
1539
1540 for (i = 0; i < nwords; i++) {
1541
1542
1543
1544 if (~inosmap) {
1545
1546
1547
1548
1549 rem = diFindFree(inosmap, 0);
1550 extno = (sword << L2EXTSPERSUM) + rem;
1551 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]),
1552 0);
1553 if (rem >= INOSPEREXT) {
1554 IREAD_UNLOCK(ipimap);
1555 release_metapage(mp);
1556 AG_UNLOCK(imap, agno);
1557 jfs_error(ip->i_sb,
1558 "diAlloc: can't find free bit "
1559 "in wmap");
1560 return EIO;
1561 }
1562
1563
1564
1565
1566
1567 ino = (extno << L2INOSPEREXT) + rem;
1568 rc = diAllocBit(imap, iagp, ino);
1569 IREAD_UNLOCK(ipimap);
1570 if (rc)
1571 assert(rc == -EIO);
1572 else {
1573
1574
1575
1576 diInitInode(ip, iagno, ino, extno,
1577 iagp);
1578 mark_metapage_dirty(mp);
1579 }
1580 release_metapage(mp);
1581
1582
1583
1584 AG_UNLOCK(imap, agno);
1585 return (rc);
1586
1587 }
1588
1589
1590
1591
1592
1593 if (addext && ~extsmap) {
1594
1595
1596
1597 rem = diFindFree(extsmap, 0);
1598 extno = (sword << L2EXTSPERSUM) + rem;
1599
1600
1601
1602 if ((rc = diNewExt(imap, iagp, extno))) {
1603
1604
1605
1606
1607 if (rc == -ENOSPC)
1608 break;
1609
1610 assert(rc == -EIO);
1611 } else {
1612
1613
1614
1615 diInitInode(ip, iagno,
1616 extno << L2INOSPEREXT,
1617 extno, iagp);
1618 mark_metapage_dirty(mp);
1619 }
1620 release_metapage(mp);
1621
1622
1623 IREAD_UNLOCK(ipimap);
1624 AG_UNLOCK(imap, agno);
1625 return (rc);
1626 }
1627
1628
1629
1630 sword = (sword == SMAPSZ - 1) ? 0 : sword + 1;
1631 inosmap = le32_to_cpu(iagp->inosmap[sword]);
1632 extsmap = le32_to_cpu(iagp->extsmap[sword]);
1633 }
1634 }
1635
1636 IREAD_UNLOCK(ipimap);
1637
1638
1639 release_metapage(mp);
1640
1641 tryag:
1642
1643
1644
1645 rc = diAllocAG(imap, agno, dir, ip);
1646
1647 AG_UNLOCK(imap, agno);
1648
1649 if (rc != -ENOSPC)
1650 return (rc);
1651
1652
1653
1654
1655 return (diAllocAny(imap, agno, dir, ip));
1656}
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688static int
1689diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
1690{
1691 int rc, addext, numfree, numinos;
1692
1693
1694
1695
1696 numfree = imap->im_agctl[agno].numfree;
1697 numinos = imap->im_agctl[agno].numinos;
1698
1699 if (numfree > numinos) {
1700 jfs_error(ip->i_sb, "diAllocAG: numfree > numinos");
1701 return -EIO;
1702 }
1703
1704
1705
1706
1707
1708
1709 if (dir == TRUE)
1710 addext = (numfree < 64 ||
1711 (numfree < 256
1712 && ((numfree * 100) / numinos) <= 20));
1713 else
1714 addext = (numfree == 0);
1715
1716
1717
1718
1719 if (addext) {
1720
1721
1722
1723
1724 if ((rc = diAllocExt(imap, agno, ip)) != -ENOSPC)
1725 return (rc);
1726 }
1727
1728
1729
1730
1731 return (diAllocIno(imap, agno, ip));
1732}
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
1758static int
1759diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
1760{
1761 int ag, rc;
1762 int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
1763
1764
1765
1766
1767
1768 for (ag = agno + 1; ag <= maxag; ag++) {
1769 AG_LOCK(imap, ag);
1770
1771 rc = diAllocAG(imap, ag, dir, ip);
1772
1773 AG_UNLOCK(imap, ag);
1774
1775 if (rc != -ENOSPC)
1776 return (rc);
1777 }
1778
1779
1780
1781 for (ag = 0; ag < agno; ag++) {
1782 AG_LOCK(imap, ag);
1783
1784 rc = diAllocAG(imap, ag, dir, ip);
1785
1786 AG_UNLOCK(imap, ag);
1787
1788 if (rc != -ENOSPC)
1789 return (rc);
1790 }
1791
1792
1793
1794 return -ENOSPC;
1795}
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1824{
1825 int iagno, ino, rc, rem, extno, sword;
1826 struct metapage *mp;
1827 struct iag *iagp;
1828
1829
1830
1831 if ((iagno = imap->im_agctl[agno].inofree) < 0)
1832 return -ENOSPC;
1833
1834
1835 IREAD_LOCK(imap->im_ipimap);
1836
1837
1838
1839 if ((rc = diIAGRead(imap, iagno, &mp))) {
1840 IREAD_UNLOCK(imap->im_ipimap);
1841 return (rc);
1842 }
1843 iagp = (struct iag *) mp->data;
1844
1845
1846
1847
1848 if (!iagp->nfreeinos) {
1849 IREAD_UNLOCK(imap->im_ipimap);
1850 release_metapage(mp);
1851 jfs_error(ip->i_sb,
1852 "diAllocIno: nfreeinos = 0, but iag on freelist");
1853 return -EIO;
1854 }
1855
1856
1857
1858
1859 for (sword = 0;; sword++) {
1860 if (sword >= SMAPSZ) {
1861 IREAD_UNLOCK(imap->im_ipimap);
1862 release_metapage(mp);
1863 jfs_error(ip->i_sb,
1864 "diAllocIno: free inode not found in summary map");
1865 return -EIO;
1866 }
1867
1868 if (~iagp->inosmap[sword])
1869 break;
1870 }
1871
1872
1873
1874
1875 rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0);
1876 if (rem >= EXTSPERSUM) {
1877 IREAD_UNLOCK(imap->im_ipimap);
1878 release_metapage(mp);
1879 jfs_error(ip->i_sb, "diAllocIno: no free extent found");
1880 return -EIO;
1881 }
1882 extno = (sword << L2EXTSPERSUM) + rem;
1883
1884
1885
1886 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0);
1887 if (rem >= INOSPEREXT) {
1888 IREAD_UNLOCK(imap->im_ipimap);
1889 release_metapage(mp);
1890 jfs_error(ip->i_sb, "diAllocIno: free inode not found");
1891 return -EIO;
1892 }
1893
1894
1895
1896 ino = (extno << L2INOSPEREXT) + rem;
1897
1898
1899
1900 rc = diAllocBit(imap, iagp, ino);
1901 IREAD_UNLOCK(imap->im_ipimap);
1902 if (rc) {
1903 release_metapage(mp);
1904 return (rc);
1905 }
1906
1907
1908
1909 diInitInode(ip, iagno, ino, extno, iagp);
1910 write_metapage(mp);
1911
1912 return (0);
1913}
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
1949{
1950 int rem, iagno, sword, extno, rc;
1951 struct metapage *mp;
1952 struct iag *iagp;
1953
1954
1955
1956
1957 if ((iagno = imap->im_agctl[agno].extfree) < 0) {
1958
1959
1960
1961 if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
1962 return (rc);
1963 }
1964 iagp = (struct iag *) mp->data;
1965
1966
1967
1968 iagp->agstart =
1969 cpu_to_le64(AGTOBLK(agno, imap->im_ipimap));
1970 } else {
1971
1972
1973 IREAD_LOCK(imap->im_ipimap);
1974 if ((rc = diIAGRead(imap, iagno, &mp))) {
1975 IREAD_UNLOCK(imap->im_ipimap);
1976 jfs_error(ip->i_sb, "diAllocExt: error reading iag");
1977 return rc;
1978 }
1979 iagp = (struct iag *) mp->data;
1980 }
1981
1982
1983
1984 for (sword = 0;; sword++) {
1985 if (sword >= SMAPSZ) {
1986 release_metapage(mp);
1987 IREAD_UNLOCK(imap->im_ipimap);
1988 jfs_error(ip->i_sb,
1989 "diAllocExt: free ext summary map not found");
1990 return -EIO;
1991 }
1992 if (~iagp->extsmap[sword])
1993 break;
1994 }
1995
1996
1997
1998 rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0);
1999 if (rem >= EXTSPERSUM) {
2000 release_metapage(mp);
2001 IREAD_UNLOCK(imap->im_ipimap);
2002 jfs_error(ip->i_sb, "diAllocExt: free extent not found");
2003 return -EIO;
2004 }
2005 extno = (sword << L2EXTSPERSUM) + rem;
2006
2007
2008
2009 rc = diNewExt(imap, iagp, extno);
2010 IREAD_UNLOCK(imap->im_ipimap);
2011 if (rc) {
2012
2013
2014
2015
2016 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2017 IAGFREE_LOCK(imap);
2018 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
2019 imap->im_freeiag = iagno;
2020 IAGFREE_UNLOCK(imap);
2021 }
2022 write_metapage(mp);
2023 return (rc);
2024 }
2025
2026
2027
2028 diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp);
2029
2030 write_metapage(mp);
2031
2032 return (0);
2033}
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2067{
2068 int extno, bitno, agno, sword, rc;
2069 struct metapage *amp, *bmp;
2070 struct iag *aiagp = 0, *biagp = 0;
2071 u32 mask;
2072
2073
2074
2075
2076
2077
2078 if (iagp->nfreeinos == cpu_to_le32(1)) {
2079 amp = bmp = NULL;
2080
2081 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
2082 if ((rc =
2083 diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
2084 &)))
2085 return (rc);
2086 aiagp = (struct iag *) amp->data;
2087 }
2088
2089 if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
2090 if ((rc =
2091 diIAGRead(imap,
2092 le32_to_cpu(iagp->inofreeback),
2093 &bmp))) {
2094 if (amp)
2095 release_metapage(amp);
2096 return (rc);
2097 }
2098 biagp = (struct iag *) bmp->data;
2099 }
2100 }
2101
2102
2103
2104
2105 agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb));
2106 extno = ino >> L2INOSPEREXT;
2107 bitno = ino & (INOSPEREXT - 1);
2108
2109
2110
2111 mask = HIGHORDER >> bitno;
2112
2113
2114
2115 if (((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) ||
2116 ((le32_to_cpu(iagp->wmap[extno]) & mask) != 0) ||
2117 (addressPXD(&iagp->inoext[extno]) == 0)) {
2118 if (amp)
2119 release_metapage(amp);
2120 if (bmp)
2121 release_metapage(bmp);
2122
2123 jfs_error(imap->im_ipimap->i_sb,
2124 "diAllocBit: iag inconsistent");
2125 return -EIO;
2126 }
2127
2128
2129
2130 iagp->wmap[extno] |= cpu_to_le32(mask);
2131
2132
2133
2134
2135
2136 if (iagp->wmap[extno] == ONES) {
2137 sword = extno >> L2EXTSPERSUM;
2138 bitno = extno & (EXTSPERSUM - 1);
2139 iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno);
2140 }
2141
2142
2143
2144
2145 if (iagp->nfreeinos == cpu_to_le32(1)) {
2146 if (amp) {
2147 aiagp->inofreeback = iagp->inofreeback;
2148 write_metapage(amp);
2149 }
2150
2151 if (bmp) {
2152 biagp->inofreefwd = iagp->inofreefwd;
2153 write_metapage(bmp);
2154 } else {
2155 imap->im_agctl[agno].inofree =
2156 le32_to_cpu(iagp->inofreefwd);
2157 }
2158 iagp->inofreefwd = iagp->inofreeback = -1;
2159 }
2160
2161
2162
2163
2164 iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) - 1);
2165 imap->im_agctl[agno].numfree -= 1;
2166 atomic_dec(&imap->im_numfree);
2167
2168 return (0);
2169}
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2216{
2217 int agno, iagno, fwd, back, freei = 0, sword, rc;
2218 struct iag *aiagp = 0, *biagp = 0, *ciagp = 0;
2219 struct metapage *amp, *bmp, *cmp, *dmp;
2220 struct inode *ipimap;
2221 s64 blkno, hint;
2222 int i, j;
2223 u32 mask;
2224 ino_t ino;
2225 struct dinode *dp;
2226 struct jfs_sb_info *sbi;
2227
2228
2229
2230 if (!iagp->nfreeexts) {
2231 jfs_error(imap->im_ipimap->i_sb, "diNewExt: no free extents");
2232 return -EIO;
2233 }
2234
2235
2236
2237 ipimap = imap->im_ipimap;
2238 sbi = JFS_SBI(ipimap->i_sb);
2239
2240 amp = bmp = cmp = NULL;
2241
2242
2243
2244 agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
2245 iagno = le32_to_cpu(iagp->iagnum);
2246
2247
2248
2249
2250
2251
2252 if (iagp->nfreeexts == cpu_to_le32(1)) {
2253 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
2254 if ((rc = diIAGRead(imap, fwd, &)))
2255 return (rc);
2256 aiagp = (struct iag *) amp->data;
2257 }
2258
2259 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
2260 if ((rc = diIAGRead(imap, back, &bmp)))
2261 goto error_out;
2262 biagp = (struct iag *) bmp->data;
2263 }
2264 } else {
2265
2266
2267
2268
2269
2270
2271 fwd = back = -1;
2272 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2273 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
2274 if ((rc = diIAGRead(imap, fwd, &)))
2275 goto error_out;
2276 aiagp = (struct iag *) amp->data;
2277 }
2278 }
2279 }
2280
2281
2282
2283
2284
2285
2286
2287
2288 if (iagp->nfreeinos == 0) {
2289 freei = imap->im_agctl[agno].inofree;
2290
2291 if (freei >= 0) {
2292 if (freei == fwd) {
2293 ciagp = aiagp;
2294 } else if (freei == back) {
2295 ciagp = biagp;
2296 } else {
2297 if ((rc = diIAGRead(imap, freei, &cmp)))
2298 goto error_out;
2299 ciagp = (struct iag *) cmp->data;
2300 }
2301 if (ciagp == NULL) {
2302 jfs_error(imap->im_ipimap->i_sb,
2303 "diNewExt: ciagp == NULL");
2304 rc = -EIO;
2305 goto error_out;
2306 }
2307 }
2308 }
2309
2310
2311
2312 if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0))
2313 hint = ((s64) agno << sbi->bmap->db_agl2size) - 1;
2314 else
2315 hint = addressPXD(&iagp->inoext[extno - 1]) +
2316 lengthPXD(&iagp->inoext[extno - 1]) - 1;
2317
2318 if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno)))
2319 goto error_out;
2320
2321
2322
2323
2324 ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT);
2325
2326
2327
2328
2329 for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) {
2330
2331
2332 dmp = get_metapage(ipimap, blkno + i, PSIZE, 1);
2333 if (dmp == NULL) {
2334 rc = -EIO;
2335 goto error_out;
2336 }
2337 dp = (struct dinode *) dmp->data;
2338
2339
2340
2341
2342 for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) {
2343 dp->di_inostamp = cpu_to_le32(sbi->inostamp);
2344 dp->di_number = cpu_to_le32(ino);
2345 dp->di_fileset = cpu_to_le32(FILESYSTEM_I);
2346 dp->di_mode = 0;
2347 dp->di_nlink = 0;
2348 PXDaddress(&(dp->di_ixpxd), blkno);
2349 PXDlength(&(dp->di_ixpxd), imap->im_nbperiext);
2350 }
2351 write_metapage(dmp);
2352 }
2353
2354
2355
2356
2357 if (iagp->nfreeexts == cpu_to_le32(1)) {
2358 if (fwd >= 0)
2359 aiagp->extfreeback = iagp->extfreeback;
2360
2361 if (back >= 0)
2362 biagp->extfreefwd = iagp->extfreefwd;
2363 else
2364 imap->im_agctl[agno].extfree =
2365 le32_to_cpu(iagp->extfreefwd);
2366
2367 iagp->extfreefwd = iagp->extfreeback = -1;
2368 } else {
2369
2370
2371
2372 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2373 if (fwd >= 0)
2374 aiagp->extfreeback = cpu_to_le32(iagno);
2375
2376 iagp->extfreefwd = cpu_to_le32(fwd);
2377 iagp->extfreeback = -1;
2378 imap->im_agctl[agno].extfree = iagno;
2379 }
2380 }
2381
2382
2383
2384
2385 if (iagp->nfreeinos == 0) {
2386 if (freei >= 0)
2387 ciagp->inofreeback = cpu_to_le32(iagno);
2388
2389 iagp->inofreefwd =
2390 cpu_to_le32(imap->im_agctl[agno].inofree);
2391 iagp->inofreeback = -1;
2392 imap->im_agctl[agno].inofree = iagno;
2393 }
2394
2395
2396 PXDlength(&iagp->inoext[extno], imap->im_nbperiext);
2397 PXDaddress(&iagp->inoext[extno], blkno);
2398
2399
2400
2401
2402
2403 iagp->wmap[extno] = cpu_to_le32(HIGHORDER);
2404 iagp->pmap[extno] = 0;
2405
2406
2407
2408
2409
2410 sword = extno >> L2EXTSPERSUM;
2411 mask = HIGHORDER >> (extno & (EXTSPERSUM - 1));
2412 iagp->extsmap[sword] |= cpu_to_le32(mask);
2413 iagp->inosmap[sword] &= cpu_to_le32(~mask);
2414
2415
2416
2417
2418 iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) +
2419 (INOSPEREXT - 1));
2420 iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) - 1);
2421
2422
2423
2424 imap->im_agctl[agno].numfree += (INOSPEREXT - 1);
2425 imap->im_agctl[agno].numinos += INOSPEREXT;
2426
2427
2428
2429 atomic_add(INOSPEREXT - 1, &imap->im_numfree);
2430 atomic_add(INOSPEREXT, &imap->im_numinos);
2431
2432
2433
2434 if (amp)
2435 write_metapage(amp);
2436 if (bmp)
2437 write_metapage(bmp);
2438 if (cmp)
2439 write_metapage(cmp);
2440
2441 return (0);
2442
2443 error_out:
2444
2445
2446
2447 if (amp)
2448 release_metapage(amp);
2449 if (bmp)
2450 release_metapage(bmp);
2451 if (cmp)
2452 release_metapage(cmp);
2453
2454 return (rc);
2455}
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497static int
2498diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2499{
2500 int rc;
2501 int iagno, i, xlen;
2502 struct inode *ipimap;
2503 struct super_block *sb;
2504 struct jfs_sb_info *sbi;
2505 struct metapage *mp;
2506 struct iag *iagp;
2507 s64 xaddr = 0;
2508 s64 blkno;
2509 tid_t tid;
2510#ifdef _STILL_TO_PORT
2511 xad_t xad;
2512#endif
2513 struct inode *iplist[1];
2514
2515
2516 ipimap = imap->im_ipimap;
2517 sb = ipimap->i_sb;
2518 sbi = JFS_SBI(sb);
2519
2520
2521 IAGFREE_LOCK(imap);
2522
2523
2524
2525
2526 if (imap->im_freeiag >= 0) {
2527
2528 iagno = imap->im_freeiag;
2529
2530
2531 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2532 } else {
2533
2534
2535
2536
2537
2538 IWRITE_LOCK(ipimap);
2539
2540 if (ipimap->i_size >> L2PSIZE != imap->im_nextiag + 1) {
2541 IWRITE_UNLOCK(ipimap);
2542 IAGFREE_UNLOCK(imap);
2543 jfs_error(imap->im_ipimap->i_sb,
2544 "diNewIAG: ipimap->i_size is wrong");
2545 return -EIO;
2546 }
2547
2548
2549
2550 iagno = imap->im_nextiag;
2551
2552
2553
2554
2555 if (iagno > (MAXIAGS - 1)) {
2556
2557 IWRITE_UNLOCK(ipimap);
2558
2559 rc = -ENOSPC;
2560 goto out;
2561 }
2562
2563
2564
2565
2566
2567 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2568
2569
2570 xlen = sbi->nbperpage;
2571 if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {
2572
2573 IWRITE_UNLOCK(ipimap);
2574
2575 goto out;
2576 }
2577
2578
2579 mp = get_metapage(ipimap, xaddr, PSIZE, 1);
2580 if (!mp) {
2581
2582
2583
2584 dbFree(ipimap, xaddr, (s64) xlen);
2585
2586
2587 IWRITE_UNLOCK(ipimap);
2588
2589 rc = -EIO;
2590 goto out;
2591 }
2592 iagp = (struct iag *) mp->data;
2593
2594
2595 memset(iagp, 0, sizeof(struct iag));
2596 iagp->iagnum = cpu_to_le32(iagno);
2597 iagp->inofreefwd = iagp->inofreeback = -1;
2598 iagp->extfreefwd = iagp->extfreeback = -1;
2599 iagp->iagfree = -1;
2600 iagp->nfreeinos = 0;
2601 iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);
2602
2603
2604
2605
2606 for (i = 0; i < SMAPSZ; i++)
2607 iagp->inosmap[i] = ONES;
2608
2609 flush_metapage(mp);
2610#ifdef _STILL_TO_PORT
2611
2612 if (bmWrite(bp)) {
2613
2614
2615
2616 dbFree(ipimap, xaddr, (s64) xlen);
2617
2618
2619 IWRITE_UNLOCK(ipimap);
2620
2621 rc = -EIO;
2622 goto out;
2623 }
2624
2625
2626
2627
2628
2629
2630
2631#endif
2632 tid = txBegin(sb, COMMIT_FORCE);
2633 down(&JFS_IP(ipimap)->commit_sem);
2634
2635
2636 if ((rc =
2637 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2638 txEnd(tid);
2639 up(&JFS_IP(ipimap)->commit_sem);
2640
2641
2642
2643 dbFree(ipimap, xaddr, (s64) xlen);
2644
2645
2646 IWRITE_UNLOCK(ipimap);
2647
2648 goto out;
2649 }
2650
2651
2652 ipimap->i_size += PSIZE;
2653 ipimap->i_blocks += LBLK2PBLK(sb, xlen);
2654
2655
2656
2657
2658
2659
2660 iplist[0] = ipimap;
2661 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2662
2663 txEnd(tid);
2664 up(&JFS_IP(ipimap)->commit_sem);
2665
2666 duplicateIXtree(sb, blkno, xlen, &xaddr);
2667
2668
2669 imap->im_nextiag += 1;
2670
2671
2672
2673
2674 imap->im_freeiag = iagno;
2675
2676
2677
2678
2679 diSync(ipimap);
2680
2681
2682 IWRITE_UNLOCK(ipimap);
2683 }
2684
2685
2686 IREAD_LOCK(ipimap);
2687
2688
2689 if ((rc = diIAGRead(imap, iagno, &mp))) {
2690 IREAD_UNLOCK(ipimap);
2691 rc = -EIO;
2692 goto out;
2693 }
2694 iagp = (struct iag *) mp->data;
2695
2696
2697 imap->im_freeiag = le32_to_cpu(iagp->iagfree);
2698 iagp->iagfree = -1;
2699
2700
2701 *iagnop = iagno;
2702 *mpp = mp;
2703
2704 out:
2705
2706 IAGFREE_UNLOCK(imap);
2707
2708 return (rc);
2709}
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
2733{
2734 struct inode *ipimap = imap->im_ipimap;
2735 s64 blkno;
2736
2737
2738 blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage);
2739
2740
2741 *mpp = read_metapage(ipimap, blkno, PSIZE, 0);
2742 if (*mpp == NULL) {
2743 return -EIO;
2744 }
2745
2746 return (0);
2747}
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763static int diFindFree(u32 word, int start)
2764{
2765 int bitno;
2766 assert(start < 32);
2767
2768 for (word <<= start, bitno = start; bitno < 32;
2769 bitno++, word <<= 1) {
2770 if ((word & HIGHORDER) == 0)
2771 break;
2772 }
2773 return (bitno);
2774}
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793int
2794diUpdatePMap(struct inode *ipimap,
2795 unsigned long inum, boolean_t is_free, struct tblock * tblk)
2796{
2797 int rc;
2798 struct iag *iagp;
2799 struct metapage *mp;
2800 int iagno, ino, extno, bitno;
2801 struct inomap *imap;
2802 u32 mask;
2803 struct jfs_log *log;
2804 int lsn, difft, diffp;
2805
2806 imap = JFS_IP(ipimap)->i_imap;
2807
2808 iagno = INOTOIAG(inum);
2809
2810 if (iagno >= imap->im_nextiag) {
2811 jfs_error(ipimap->i_sb,
2812 "diUpdatePMap: the iag is outside the map");
2813 return -EIO;
2814 }
2815
2816 IREAD_LOCK(ipimap);
2817 rc = diIAGRead(imap, iagno, &mp);
2818 IREAD_UNLOCK(ipimap);
2819 if (rc)
2820 return (rc);
2821 iagp = (struct iag *) mp->data;
2822
2823
2824
2825 ino = inum & (INOSPERIAG - 1);
2826 extno = ino >> L2INOSPEREXT;
2827 bitno = ino & (INOSPEREXT - 1);
2828 mask = HIGHORDER >> bitno;
2829
2830
2831
2832 if (is_free == TRUE) {
2833
2834
2835
2836
2837
2838 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2839 jfs_error(ipimap->i_sb,
2840 "diUpdatePMap: inode %ld not marked as "
2841 "allocated in wmap!", inum);
2842 }
2843 if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
2844 jfs_error(ipimap->i_sb,
2845 "diUpdatePMap: inode %ld not marked as "
2846 "allocated in pmap!", inum);
2847 }
2848
2849 iagp->pmap[extno] &= cpu_to_le32(~mask);
2850 }
2851
2852
2853
2854 else {
2855
2856
2857
2858 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2859 release_metapage(mp);
2860 jfs_error(ipimap->i_sb,
2861 "diUpdatePMap: the inode is not allocated in "
2862 "the working map");
2863 return -EIO;
2864 }
2865 if ((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) {
2866 release_metapage(mp);
2867 jfs_error(ipimap->i_sb,
2868 "diUpdatePMap: the inode is not free in the "
2869 "persistent map");
2870 return -EIO;
2871 }
2872
2873 iagp->pmap[extno] |= cpu_to_le32(mask);
2874 }
2875
2876
2877
2878 lsn = tblk->lsn;
2879 log = JFS_SBI(tblk->sb)->log;
2880 if (mp->lsn != 0) {
2881
2882 logdiff(difft, lsn, log);
2883 logdiff(diffp, mp->lsn, log);
2884 if (difft < diffp) {
2885 mp->lsn = lsn;
2886
2887 LOGSYNC_LOCK(log);
2888 list_del(&mp->synclist);
2889 list_add(&mp->synclist, &tblk->synclist);
2890 LOGSYNC_UNLOCK(log);
2891 }
2892
2893 LOGSYNC_LOCK(log);
2894 assert(mp->clsn);
2895 logdiff(difft, tblk->clsn, log);
2896 logdiff(diffp, mp->clsn, log);
2897 if (difft > diffp)
2898 mp->clsn = tblk->clsn;
2899 LOGSYNC_UNLOCK(log);
2900 } else {
2901 mp->log = log;
2902 mp->lsn = lsn;
2903
2904 LOGSYNC_LOCK(log);
2905 log->count++;
2906 list_add(&mp->synclist, &tblk->synclist);
2907 mp->clsn = tblk->clsn;
2908 LOGSYNC_UNLOCK(log);
2909 }
2910 write_metapage(mp);
2911 return (0);
2912}
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2923{
2924 int rc, rcx = 0;
2925 struct inomap *imap = JFS_IP(ipimap)->i_imap;
2926 struct iag *iagp = 0, *hiagp = 0;
2927 struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
2928 struct metapage *bp, *hbp;
2929 int i, n, head;
2930 int numinos, xnuminos = 0, xnumfree = 0;
2931 s64 agstart;
2932
2933 jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d",
2934 imap->im_nextiag, atomic_read(&imap->im_numinos),
2935 atomic_read(&imap->im_numfree));
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946 for (i = 0; i < MAXAG; i++) {
2947 imap->im_agctl[i].inofree = -1;
2948 imap->im_agctl[i].extfree = -1;
2949 imap->im_agctl[i].numinos = 0;
2950 imap->im_agctl[i].numfree = 0;
2951 }
2952
2953
2954
2955
2956
2957
2958 for (i = 0; i < imap->im_nextiag; i++) {
2959 if ((rc = diIAGRead(imap, i, &bp))) {
2960 rcx = rc;
2961 continue;
2962 }
2963 iagp = (struct iag *) bp->data;
2964 if (le32_to_cpu(iagp->iagnum) != i) {
2965 release_metapage(bp);
2966 jfs_error(ipimap->i_sb,
2967 "diExtendFs: unexpected value of iagnum");
2968 return -EIO;
2969 }
2970
2971
2972 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2973 release_metapage(bp);
2974 continue;
2975 }
2976
2977
2978 agstart = le64_to_cpu(iagp->agstart);
2979
2980 n = agstart >> mp->db_agl2size;
2981
2982
2983 numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts))
2984 << L2INOSPEREXT;
2985 if (numinos > 0) {
2986
2987 imap->im_agctl[n].numinos += numinos;
2988 xnuminos += numinos;
2989 }
2990
2991
2992 if ((int) le32_to_cpu(iagp->nfreeinos) > 0) {
2993 if ((head = imap->im_agctl[n].inofree) == -1)
2994 iagp->inofreefwd = iagp->inofreeback = -1;
2995 else {
2996 if ((rc = diIAGRead(imap, head, &hbp))) {
2997 rcx = rc;
2998 goto nextiag;
2999 }
3000 hiagp = (struct iag *) hbp->data;
3001 hiagp->inofreeback = iagp->iagnum;
3002 iagp->inofreefwd = cpu_to_le32(head);
3003 iagp->inofreeback = -1;
3004 write_metapage(hbp);
3005 }
3006
3007 imap->im_agctl[n].inofree =
3008 le32_to_cpu(iagp->iagnum);
3009
3010
3011 imap->im_agctl[n].numfree +=
3012 le32_to_cpu(iagp->nfreeinos);
3013 xnumfree += le32_to_cpu(iagp->nfreeinos);
3014 }
3015
3016
3017 if (le32_to_cpu(iagp->nfreeexts) > 0) {
3018 if ((head = imap->im_agctl[n].extfree) == -1)
3019 iagp->extfreefwd = iagp->extfreeback = -1;
3020 else {
3021 if ((rc = diIAGRead(imap, head, &hbp))) {
3022 rcx = rc;
3023 goto nextiag;
3024 }
3025 hiagp = (struct iag *) hbp->data;
3026 hiagp->extfreeback = iagp->iagnum;
3027 iagp->extfreefwd = cpu_to_le32(head);
3028 iagp->extfreeback = -1;
3029 write_metapage(hbp);
3030 }
3031
3032 imap->im_agctl[n].extfree =
3033 le32_to_cpu(iagp->iagnum);
3034 }
3035
3036 nextiag:
3037 write_metapage(bp);
3038 }
3039
3040 if (xnuminos != atomic_read(&imap->im_numinos) ||
3041 xnumfree != atomic_read(&imap->im_numfree)) {
3042 jfs_error(ipimap->i_sb,
3043 "diExtendFs: numinos or numfree incorrect");
3044 return -EIO;
3045 }
3046
3047 return rcx;
3048}
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058static void duplicateIXtree(struct super_block *sb, s64 blkno,
3059 int xlen, s64 *xaddr)
3060{
3061 struct jfs_superblock *j_sb;
3062 struct buffer_head *bh;
3063 struct inode *ip;
3064 tid_t tid;
3065
3066
3067 if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)
3068 return;
3069 ip = diReadSpecial(sb, FILESYSTEM_I, 1);
3070 if (ip == NULL) {
3071 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
3072 if (readSuper(sb, &bh))
3073 return;
3074 j_sb = (struct jfs_superblock *)bh->b_data;
3075 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
3076
3077 mark_buffer_dirty(bh);
3078 ll_rw_block(WRITE, 1, &bh);
3079 wait_on_buffer(bh);
3080 brelse(bh);
3081 return;
3082 }
3083
3084
3085 tid = txBegin(sb, COMMIT_FORCE);
3086
3087 if (xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0)) {
3088 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
3089 txAbort(tid, 1);
3090 goto cleanup;
3091
3092 }
3093
3094 ip->i_size += PSIZE;
3095 ip->i_blocks += LBLK2PBLK(sb, xlen);
3096 txCommit(tid, 1, &ip, COMMIT_FORCE);
3097 cleanup:
3098 txEnd(tid);
3099 diFreeSpecial(ip);
3100}
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3112{
3113 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3114
3115 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3116 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3117
3118 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3119 ip->i_nlink = le32_to_cpu(dip->di_nlink);
3120 ip->i_uid = le32_to_cpu(dip->di_uid);
3121 ip->i_gid = le32_to_cpu(dip->di_gid);
3122 ip->i_size = le64_to_cpu(dip->di_size);
3123 ip->i_atime = le32_to_cpu(dip->di_atime.tv_sec);
3124 ip->i_mtime = le32_to_cpu(dip->di_mtime.tv_sec);
3125 ip->i_ctime = le32_to_cpu(dip->di_ctime.tv_sec);
3126 ip->i_blksize = ip->i_sb->s_blocksize;
3127 ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks));
3128 ip->i_generation = le32_to_cpu(dip->di_gen);
3129
3130 jfs_ip->ixpxd = dip->di_ixpxd;
3131 jfs_ip->acl = dip->di_acl;
3132 jfs_ip->ea = dip->di_ea;
3133 jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
3134 jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
3135 jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
3136
3137 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3138 ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev));
3139
3140 if (S_ISDIR(ip->i_mode)) {
3141 memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
3142 } else if (S_ISREG(ip->i_mode) || S_ISLNK(ip->i_mode)) {
3143 memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288);
3144 } else
3145 memcpy(&jfs_ip->i_inline_ea, &dip->di_inlineea, 128);
3146
3147
3148 jfs_ip->cflag = 0;
3149 jfs_ip->btindex = 0;
3150 jfs_ip->btorder = 0;
3151 jfs_ip->bxflag = 0;
3152 jfs_ip->blid = 0;
3153 jfs_ip->atlhead = 0;
3154 jfs_ip->atltail = 0;
3155 jfs_ip->xtlid = 0;
3156 return (0);
3157}
3158
3159
3160
3161
3162
3163
3164static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3165{
3166 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3167
3168 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3169 dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp);
3170 dip->di_number = cpu_to_le32(ip->i_ino);
3171 dip->di_gen = cpu_to_le32(ip->i_generation);
3172 dip->di_size = cpu_to_le64(ip->i_size);
3173 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3174 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3175 dip->di_uid = cpu_to_le32(ip->i_uid);
3176 dip->di_gid = cpu_to_le32(ip->i_gid);
3177
3178
3179
3180
3181 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode);
3182 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime);
3183 dip->di_atime.tv_nsec = 0;
3184 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime);
3185 dip->di_ctime.tv_nsec = 0;
3186 dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime);
3187 dip->di_mtime.tv_nsec = 0;
3188 dip->di_ixpxd = jfs_ip->ixpxd;
3189 dip->di_acl = jfs_ip->acl;
3190 dip->di_ea = jfs_ip->ea;
3191 dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
3192 dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
3193 dip->di_otime.tv_nsec = 0;
3194 dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
3195
3196 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3197 dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev));
3198}
3199
3200#ifdef _JFS_DEBUG_IMAP
3201
3202
3203
3204static void *DBGdiInit(struct inomap * imap)
3205{
3206 u32 *dimap;
3207 int size;
3208 size = 64 * 1024;
3209 if ((dimap = (u32 *) xmalloc(size, L2PSIZE, kernel_heap)) == NULL)
3210 assert(0);
3211 bzero((void *) dimap, size);
3212 imap->im_DBGdimap = dimap;
3213}
3214
3215
3216
3217
3218static void DBGdiAlloc(struct inomap * imap, ino_t ino)
3219{
3220 u32 *dimap = imap->im_DBGdimap;
3221 int w, b;
3222 u32 m;
3223 w = ino >> 5;
3224 b = ino & 31;
3225 m = 0x80000000 >> b;
3226 assert(w < 64 * 256);
3227 if (dimap[w] & m) {
3228 printk("DEBUG diAlloc: duplicate alloc ino:0x%x\n", ino);
3229 }
3230 dimap[w] |= m;
3231}
3232
3233
3234
3235
3236static void DBGdiFree(struct inomap * imap, ino_t ino)
3237{
3238 u32 *dimap = imap->im_DBGdimap;
3239 int w, b;
3240 u32 m;
3241 w = ino >> 5;
3242 b = ino & 31;
3243 m = 0x80000000 >> b;
3244 assert(w < 64 * 256);
3245 if ((dimap[w] & m) == 0) {
3246 printk("DEBUG diFree: duplicate free ino:0x%x\n", ino);
3247 }
3248 dimap[w] &= ~m;
3249}
3250
3251static void dump_cp(struct inomap * ipimap, char *function, int line)
3252{
3253 printk("\n* ********* *\nControl Page %s %d\n", function, line);
3254 printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag,
3255 ipimap->im_nextiag);
3256 printk("NumInos %d\tNumFree %d\n",
3257 atomic_read(&ipimap->im_numinos),
3258 atomic_read(&ipimap->im_numfree));
3259 printk("AG InoFree %d\tAG ExtFree %d\n",
3260 ipimap->im_agctl[0].inofree, ipimap->im_agctl[0].extfree);
3261 printk("AG NumInos %d\tAG NumFree %d\n",
3262 ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree);
3263}
3264
3265static void dump_iag(struct iag * iag, char *function, int line)
3266{
3267 printk("\n* ********* *\nIAG %s %d\n", function, line);
3268 printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum),
3269 le32_to_cpu(iag->iagfree));
3270 printk("InoFreeFwd %d\tInoFreeBack %d\n",
3271 le32_to_cpu(iag->inofreefwd),
3272 le32_to_cpu(iag->inofreeback));
3273 printk("ExtFreeFwd %d\tExtFreeBack %d\n",
3274 le32_to_cpu(iag->extfreefwd),
3275 le32_to_cpu(iag->extfreeback));
3276 printk("NFreeInos %d\tNFreeExts %d\n", le32_to_cpu(iag->nfreeinos),
3277 le32_to_cpu(iag->nfreeexts));
3278}
3279#endif
3280