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