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 "
538 "extent!");
539 return;
540 }
541
542
543 dp = (struct dinode *) (mp->data);
544 dp += inum % 8;
545
546
547 copy_to_dinode(dp, ip);
548 memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);
549
550 if (inum == FILESYSTEM_I)
551 dp->di_gengen = cpu_to_le32(sbi->gengen);
552
553
554 write_metapage(mp);
555}
556
557
558
559
560
561
562void diFreeSpecial(struct inode *ip)
563{
564 if (ip == NULL) {
565 jfs_err("diFreeSpecial called with NULL ip!");
566 return;
567 }
568 filemap_write_and_wait(ip->i_mapping);
569 truncate_inode_pages(ip->i_mapping, 0);
570 iput(ip);
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
598
599int diWrite(tid_t tid, struct inode *ip)
600{
601 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
602 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
603 int rc = 0;
604 s32 ino;
605 struct dinode *dp;
606 s64 blkno;
607 int block_offset;
608 int inodes_left;
609 struct metapage *mp;
610 unsigned long pageno;
611 int rel_inode;
612 int dioffset;
613 struct inode *ipimap;
614 uint type;
615 lid_t lid;
616 struct tlock *ditlck, *tlck;
617 struct linelock *dilinelock, *ilinelock;
618 struct lv *lv;
619 int n;
620
621 ipimap = jfs_ip->ipimap;
622
623 ino = ip->i_ino & (INOSPERIAG - 1);
624
625 if (!addressPXD(&(jfs_ip->ixpxd)) ||
626 (lengthPXD(&(jfs_ip->ixpxd)) !=
627 JFS_IP(ipimap)->i_imap->im_nbperiext)) {
628 jfs_error(ip->i_sb, "ixpxd invalid\n");
629 return -EIO;
630 }
631
632
633
634
635
636 blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);
637
638 rel_inode = (ino & (INOSPERPAGE - 1));
639 pageno = blkno >> sbi->l2nbperpage;
640
641 if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
642
643
644
645 inodes_left =
646 (sbi->nbperpage - block_offset) << sbi->l2niperblk;
647
648 if (rel_inode < inodes_left)
649 rel_inode += block_offset << sbi->l2niperblk;
650 else {
651 pageno += 1;
652 rel_inode -= inodes_left;
653 }
654 }
655
656 retry:
657 mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
658 if (!mp)
659 return -EIO;
660
661
662 dp = (struct dinode *) mp->data;
663 dp += rel_inode;
664
665 dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
666
667
668
669
670
671 if ((ditlck =
672 txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
673 goto retry;
674 dilinelock = (struct linelock *) & ditlck->lock;
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689 if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {
690
691
692
693
694 xtpage_t *p, *xp;
695 xad_t *xad;
696
697 jfs_ip->xtlid = 0;
698 tlck = lid_to_tlock(lid);
699 assert(tlck->type & tlckXTREE);
700 tlck->type |= tlckBTROOT;
701 tlck->mp = mp;
702 ilinelock = (struct linelock *) & tlck->lock;
703
704
705
706
707 p = &jfs_ip->i_xtroot;
708 xp = (xtpage_t *) &dp->di_dirtable;
709 lv = ilinelock->lv;
710 for (n = 0; n < ilinelock->index; n++, lv++) {
711 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
712 lv->length << L2XTSLOTSIZE);
713 }
714
715
716 xad = &xp->xad[XTENTRYSTART];
717 for (n = XTENTRYSTART;
718 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
719 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
720 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
721 }
722
723 if ((lid = jfs_ip->blid) == 0)
724 goto inlineData;
725 jfs_ip->blid = 0;
726
727 tlck = lid_to_tlock(lid);
728 type = tlck->type;
729 tlck->type |= tlckBTROOT;
730 tlck->mp = mp;
731 ilinelock = (struct linelock *) & tlck->lock;
732
733
734
735
736 if (type & tlckXTREE) {
737 xtpage_t *p, *xp;
738 xad_t *xad;
739
740
741
742
743 p = &jfs_ip->i_xtroot;
744 xp = &dp->di_xtroot;
745 lv = ilinelock->lv;
746 for (n = 0; n < ilinelock->index; n++, lv++) {
747 memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
748 lv->length << L2XTSLOTSIZE);
749 }
750
751
752 xad = &xp->xad[XTENTRYSTART];
753 for (n = XTENTRYSTART;
754 n < le16_to_cpu(xp->header.nextindex); n++, xad++)
755 if (xad->flag & (XAD_NEW | XAD_EXTENDED))
756 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
757 }
758
759
760
761 else if (type & tlckDTREE) {
762 dtpage_t *p, *xp;
763
764
765
766
767 p = (dtpage_t *) &jfs_ip->i_dtroot;
768 xp = (dtpage_t *) & dp->di_dtroot;
769 lv = ilinelock->lv;
770 for (n = 0; n < ilinelock->index; n++, lv++) {
771 memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
772 lv->length << L2DTSLOTSIZE);
773 }
774 } else {
775 jfs_err("diWrite: UFO tlock");
776 }
777
778 inlineData:
779
780
781
782 if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
783 lv = & dilinelock->lv[dilinelock->index];
784 lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
785 lv->length = 2;
786 memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);
787 dilinelock->index++;
788 }
789
790
791
792
793 if (test_cflag(COMMIT_Inlineea, ip)) {
794 lv = & dilinelock->lv[dilinelock->index];
795 lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
796 lv->length = 1;
797 memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);
798 dilinelock->index++;
799
800 clear_cflag(COMMIT_Inlineea, ip);
801 }
802
803
804
805
806 lv = & dilinelock->lv[dilinelock->index];
807 lv->offset = dioffset >> L2INODESLOTSIZE;
808 copy_to_dinode(dp, ip);
809 if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
810 lv->length = 2;
811 memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);
812 } else
813 lv->length = 1;
814 dilinelock->index++;
815
816
817
818
819 write_metapage(mp);
820
821 return (rc);
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
862
863int diFree(struct inode *ip)
864{
865 int rc;
866 ino_t inum = ip->i_ino;
867 struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;
868 struct metapage *mp, *amp, *bmp, *cmp, *dmp;
869 int iagno, ino, extno, bitno, sword, agno;
870 int back, fwd;
871 u32 bitmap, mask;
872 struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
873 struct inomap *imap = JFS_IP(ipimap)->i_imap;
874 pxd_t freepxd;
875 tid_t tid;
876 struct inode *iplist[3];
877 struct tlock *tlck;
878 struct pxd_lock *pxdlock;
879
880
881
882
883
884 aiagp = biagp = ciagp = diagp = NULL;
885
886
887
888 iagno = INOTOIAG(inum);
889
890
891
892
893 if (iagno >= imap->im_nextiag) {
894 print_hex_dump(KERN_ERR, "imap: ", DUMP_PREFIX_ADDRESS, 16, 4,
895 imap, 32, 0);
896 jfs_error(ip->i_sb, "inum = %d, iagno = %d, nextiag = %d\n",
897 (uint) inum, iagno, imap->im_nextiag);
898 return -EIO;
899 }
900
901
902
903 agno = BLKTOAG(JFS_IP(ip)->agstart, JFS_SBI(ip->i_sb));
904
905
906
907 AG_LOCK(imap, agno);
908
909
910
911
912 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
913
914
915
916 if ((rc = diIAGRead(imap, iagno, &mp))) {
917 IREAD_UNLOCK(ipimap);
918 AG_UNLOCK(imap, agno);
919 return (rc);
920 }
921 iagp = (struct iag *) mp->data;
922
923
924
925
926 ino = inum & (INOSPERIAG - 1);
927 extno = ino >> L2INOSPEREXT;
928 bitno = ino & (INOSPEREXT - 1);
929 mask = HIGHORDER >> bitno;
930
931 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
932 jfs_error(ip->i_sb, "wmap shows inode already free\n");
933 }
934
935 if (!addressPXD(&iagp->inoext[extno])) {
936 release_metapage(mp);
937 IREAD_UNLOCK(ipimap);
938 AG_UNLOCK(imap, agno);
939 jfs_error(ip->i_sb, "invalid inoext\n");
940 return -EIO;
941 }
942
943
944
945 bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
946
947 if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
948 release_metapage(mp);
949 IREAD_UNLOCK(ipimap);
950 AG_UNLOCK(imap, agno);
951 jfs_error(ip->i_sb, "numfree > numinos\n");
952 return -EIO;
953 }
954
955
956
957
958 if (bitmap ||
959 imap->im_agctl[agno].numfree < 96 ||
960 (imap->im_agctl[agno].numfree < 288 &&
961 (((imap->im_agctl[agno].numfree * 100) /
962 imap->im_agctl[agno].numinos) <= 25))) {
963
964
965
966
967 if (iagp->nfreeinos == 0) {
968
969
970
971
972
973 if ((fwd = imap->im_agctl[agno].inofree) >= 0) {
974
975
976
977 if ((rc = diIAGRead(imap, fwd, &))) {
978 IREAD_UNLOCK(ipimap);
979 AG_UNLOCK(imap, agno);
980 release_metapage(mp);
981 return (rc);
982 }
983 aiagp = (struct iag *) amp->data;
984
985
986
987 aiagp->inofreeback = cpu_to_le32(iagno);
988
989 write_metapage(amp);
990 }
991
992
993
994
995 iagp->inofreefwd =
996 cpu_to_le32(imap->im_agctl[agno].inofree);
997 iagp->inofreeback = cpu_to_le32(-1);
998 imap->im_agctl[agno].inofree = iagno;
999 }
1000 IREAD_UNLOCK(ipimap);
1001
1002
1003
1004
1005
1006
1007 if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
1008 sword = extno >> L2EXTSPERSUM;
1009 bitno = extno & (EXTSPERSUM - 1);
1010 iagp->inosmap[sword] &=
1011 cpu_to_le32(~(HIGHORDER >> bitno));
1012 }
1013
1014
1015
1016 iagp->wmap[extno] = cpu_to_le32(bitmap);
1017
1018
1019
1020
1021 le32_add_cpu(&iagp->nfreeinos, 1);
1022 imap->im_agctl[agno].numfree += 1;
1023 atomic_inc(&imap->im_numfree);
1024
1025
1026
1027 AG_UNLOCK(imap, agno);
1028
1029
1030 write_metapage(mp);
1031
1032 return (0);
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044 amp = bmp = cmp = dmp = NULL;
1045 fwd = back = -1;
1046
1047
1048
1049
1050 if (iagp->nfreeexts == 0) {
1051
1052
1053
1054
1055
1056
1057 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
1058 if ((rc = diIAGRead(imap, fwd, &)))
1059 goto error_out;
1060 aiagp = (struct iag *) amp->data;
1061 }
1062 } else {
1063
1064
1065
1066
1067
1068 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1069
1070
1071
1072
1073
1074 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
1075 if ((rc = diIAGRead(imap, fwd, &)))
1076 goto error_out;
1077 aiagp = (struct iag *) amp->data;
1078 }
1079
1080 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
1081 if ((rc = diIAGRead(imap, back, &bmp)))
1082 goto error_out;
1083 biagp = (struct iag *) bmp->data;
1084 }
1085 }
1086 }
1087
1088
1089
1090
1091 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1092 int inofreeback = le32_to_cpu(iagp->inofreeback);
1093 int inofreefwd = le32_to_cpu(iagp->inofreefwd);
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103 if (inofreefwd >= 0) {
1104
1105 if (inofreefwd == fwd)
1106 ciagp = (struct iag *) amp->data;
1107 else if (inofreefwd == back)
1108 ciagp = (struct iag *) bmp->data;
1109 else {
1110 if ((rc =
1111 diIAGRead(imap, inofreefwd, &cmp)))
1112 goto error_out;
1113 ciagp = (struct iag *) cmp->data;
1114 }
1115 assert(ciagp != NULL);
1116 }
1117
1118 if (inofreeback >= 0) {
1119 if (inofreeback == fwd)
1120 diagp = (struct iag *) amp->data;
1121 else if (inofreeback == back)
1122 diagp = (struct iag *) bmp->data;
1123 else {
1124 if ((rc =
1125 diIAGRead(imap, inofreeback, &dmp)))
1126 goto error_out;
1127 diagp = (struct iag *) dmp->data;
1128 }
1129 assert(diagp != NULL);
1130 }
1131 }
1132
1133 IREAD_UNLOCK(ipimap);
1134
1135
1136
1137
1138 freepxd = iagp->inoext[extno];
1139 invalidate_pxd_metapages(ip, freepxd);
1140
1141
1142
1143
1144
1145
1146
1147 if (iagp->nfreeexts == 0) {
1148 if (fwd >= 0)
1149 aiagp->extfreeback = cpu_to_le32(iagno);
1150
1151 iagp->extfreefwd =
1152 cpu_to_le32(imap->im_agctl[agno].extfree);
1153 iagp->extfreeback = cpu_to_le32(-1);
1154 imap->im_agctl[agno].extfree = iagno;
1155 } else {
1156
1157
1158
1159 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
1160 if (fwd >= 0)
1161 aiagp->extfreeback = iagp->extfreeback;
1162
1163 if (back >= 0)
1164 biagp->extfreefwd = iagp->extfreefwd;
1165 else
1166 imap->im_agctl[agno].extfree =
1167 le32_to_cpu(iagp->extfreefwd);
1168
1169 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
1170
1171 IAGFREE_LOCK(imap);
1172 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
1173 imap->im_freeiag = iagno;
1174 IAGFREE_UNLOCK(imap);
1175 }
1176 }
1177
1178
1179
1180
1181 if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
1182 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0)
1183 ciagp->inofreeback = iagp->inofreeback;
1184
1185 if ((int) le32_to_cpu(iagp->inofreeback) >= 0)
1186 diagp->inofreefwd = iagp->inofreefwd;
1187 else
1188 imap->im_agctl[agno].inofree =
1189 le32_to_cpu(iagp->inofreefwd);
1190
1191 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
1192 }
1193
1194
1195
1196
1197
1198
1199 if (iagp->pmap[extno] != 0) {
1200 jfs_error(ip->i_sb, "the pmap does not show inode free\n");
1201 }
1202 iagp->wmap[extno] = 0;
1203 PXDlength(&iagp->inoext[extno], 0);
1204 PXDaddress(&iagp->inoext[extno], 0);
1205
1206
1207
1208
1209
1210
1211 sword = extno >> L2EXTSPERSUM;
1212 bitno = extno & (EXTSPERSUM - 1);
1213 mask = HIGHORDER >> bitno;
1214 iagp->inosmap[sword] |= cpu_to_le32(mask);
1215 iagp->extsmap[sword] &= cpu_to_le32(~mask);
1216
1217
1218
1219
1220 le32_add_cpu(&iagp->nfreeinos, -(INOSPEREXT - 1));
1221 le32_add_cpu(&iagp->nfreeexts, 1);
1222
1223
1224
1225
1226 imap->im_agctl[agno].numfree -= (INOSPEREXT - 1);
1227 imap->im_agctl[agno].numinos -= INOSPEREXT;
1228 atomic_sub(INOSPEREXT - 1, &imap->im_numfree);
1229 atomic_sub(INOSPEREXT, &imap->im_numinos);
1230
1231 if (amp)
1232 write_metapage(amp);
1233 if (bmp)
1234 write_metapage(bmp);
1235 if (cmp)
1236 write_metapage(cmp);
1237 if (dmp)
1238 write_metapage(dmp);
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
1250 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
1251
1252
1253
1254
1255
1256
1257
1258
1259 tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
1260 pxdlock = (struct pxd_lock *) & tlck->lock;
1261 pxdlock->flag = mlckFREEPXD;
1262 pxdlock->pxd = freepxd;
1263 pxdlock->index = 1;
1264
1265 write_metapage(mp);
1266
1267 iplist[0] = ipimap;
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 iplist[1] = (struct inode *) (size_t)iagno;
1278 iplist[2] = (struct inode *) (size_t)extno;
1279
1280 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1281
1282 txEnd(tid);
1283 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
1284
1285
1286 AG_UNLOCK(imap, agno);
1287
1288 return (0);
1289
1290 error_out:
1291 IREAD_UNLOCK(ipimap);
1292
1293 if (amp)
1294 release_metapage(amp);
1295 if (bmp)
1296 release_metapage(bmp);
1297 if (cmp)
1298 release_metapage(cmp);
1299 if (dmp)
1300 release_metapage(dmp);
1301
1302 AG_UNLOCK(imap, agno);
1303
1304 release_metapage(mp);
1305
1306 return (rc);
1307}
1308
1309
1310
1311
1312
1313static inline void
1314diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
1315{
1316 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
1317
1318 ip->i_ino = (iagno << L2INOSPERIAG) + ino;
1319 jfs_ip->ixpxd = iagp->inoext[extno];
1320 jfs_ip->agstart = le64_to_cpu(iagp->agstart);
1321 jfs_ip->active_ag = -1;
1322}
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1342{
1343 int rc, ino, iagno, addext, extno, bitno, sword;
1344 int nwords, rem, i, agno;
1345 u32 mask, inosmap, extsmap;
1346 struct inode *ipimap;
1347 struct metapage *mp;
1348 ino_t inum;
1349 struct iag *iagp;
1350 struct inomap *imap;
1351
1352
1353
1354
1355 ipimap = JFS_SBI(pip->i_sb)->ipimap;
1356 imap = JFS_IP(ipimap)->i_imap;
1357 JFS_IP(ip)->ipimap = ipimap;
1358 JFS_IP(ip)->fileset = FILESYSTEM_I;
1359
1360
1361
1362
1363 if (dir) {
1364 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1365 AG_LOCK(imap, agno);
1366 goto tryag;
1367 }
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb));
1380
1381 if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
1382
1383
1384
1385
1386
1387 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1388 AG_LOCK(imap, agno);
1389 goto tryag;
1390 }
1391
1392 inum = pip->i_ino + 1;
1393 ino = inum & (INOSPERIAG - 1);
1394
1395
1396 if (ino == 0)
1397 inum = pip->i_ino;
1398
1399
1400 AG_LOCK(imap, agno);
1401
1402
1403 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
1404
1405
1406 iagno = INOTOIAG(inum);
1407 if ((rc = diIAGRead(imap, iagno, &mp))) {
1408 IREAD_UNLOCK(ipimap);
1409 AG_UNLOCK(imap, agno);
1410 return (rc);
1411 }
1412 iagp = (struct iag *) mp->data;
1413
1414
1415
1416
1417
1418 addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
1419
1420
1421
1422
1423
1424
1425
1426 if (iagp->nfreeinos || addext) {
1427
1428
1429 extno = ino >> L2INOSPEREXT;
1430
1431
1432
1433
1434 if (addressPXD(&iagp->inoext[extno])) {
1435 bitno = ino & (INOSPEREXT - 1);
1436 if ((bitno =
1437 diFindFree(le32_to_cpu(iagp->wmap[extno]),
1438 bitno))
1439 < INOSPEREXT) {
1440 ino = (extno << L2INOSPEREXT) + bitno;
1441
1442
1443
1444
1445 rc = diAllocBit(imap, iagp, ino);
1446 IREAD_UNLOCK(ipimap);
1447 if (rc) {
1448 assert(rc == -EIO);
1449 } else {
1450
1451
1452
1453 diInitInode(ip, iagno, ino, extno,
1454 iagp);
1455 mark_metapage_dirty(mp);
1456 }
1457 release_metapage(mp);
1458
1459
1460
1461 AG_UNLOCK(imap, agno);
1462 return (rc);
1463 }
1464
1465 if (!addext)
1466 extno =
1467 (extno ==
1468 EXTSPERIAG - 1) ? 0 : extno + 1;
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 bitno = extno & (EXTSPERSUM - 1);
1488 nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1;
1489 sword = extno >> L2EXTSPERSUM;
1490
1491
1492
1493
1494 mask = (bitno == 0) ? 0 : (ONES << (EXTSPERSUM - bitno));
1495 inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask;
1496 extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask;
1497
1498
1499
1500
1501 for (i = 0; i < nwords; i++) {
1502
1503
1504
1505 if (~inosmap) {
1506
1507
1508
1509
1510 rem = diFindFree(inosmap, 0);
1511 extno = (sword << L2EXTSPERSUM) + rem;
1512 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]),
1513 0);
1514 if (rem >= INOSPEREXT) {
1515 IREAD_UNLOCK(ipimap);
1516 release_metapage(mp);
1517 AG_UNLOCK(imap, agno);
1518 jfs_error(ip->i_sb,
1519 "can't find free bit in wmap\n");
1520 return -EIO;
1521 }
1522
1523
1524
1525
1526
1527 ino = (extno << L2INOSPEREXT) + rem;
1528 rc = diAllocBit(imap, iagp, ino);
1529 IREAD_UNLOCK(ipimap);
1530 if (rc)
1531 assert(rc == -EIO);
1532 else {
1533
1534
1535
1536 diInitInode(ip, iagno, ino, extno,
1537 iagp);
1538 mark_metapage_dirty(mp);
1539 }
1540 release_metapage(mp);
1541
1542
1543
1544 AG_UNLOCK(imap, agno);
1545 return (rc);
1546
1547 }
1548
1549
1550
1551
1552
1553 if (addext && ~extsmap) {
1554
1555
1556
1557 rem = diFindFree(extsmap, 0);
1558 extno = (sword << L2EXTSPERSUM) + rem;
1559
1560
1561
1562 if ((rc = diNewExt(imap, iagp, extno))) {
1563
1564
1565
1566
1567 if (rc == -ENOSPC)
1568 break;
1569
1570 assert(rc == -EIO);
1571 } else {
1572
1573
1574
1575 diInitInode(ip, iagno,
1576 extno << L2INOSPEREXT,
1577 extno, iagp);
1578 mark_metapage_dirty(mp);
1579 }
1580 release_metapage(mp);
1581
1582
1583 IREAD_UNLOCK(ipimap);
1584 AG_UNLOCK(imap, agno);
1585 return (rc);
1586 }
1587
1588
1589
1590 sword = (sword == SMAPSZ - 1) ? 0 : sword + 1;
1591 inosmap = le32_to_cpu(iagp->inosmap[sword]);
1592 extsmap = le32_to_cpu(iagp->extsmap[sword]);
1593 }
1594 }
1595
1596 IREAD_UNLOCK(ipimap);
1597
1598
1599 release_metapage(mp);
1600
1601 tryag:
1602
1603
1604
1605 rc = diAllocAG(imap, agno, dir, ip);
1606
1607 AG_UNLOCK(imap, agno);
1608
1609 if (rc != -ENOSPC)
1610 return (rc);
1611
1612
1613
1614
1615 return (diAllocAny(imap, agno, dir, ip));
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
1647
1648static int
1649diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
1650{
1651 int rc, addext, numfree, numinos;
1652
1653
1654
1655
1656 numfree = imap->im_agctl[agno].numfree;
1657 numinos = imap->im_agctl[agno].numinos;
1658
1659 if (numfree > numinos) {
1660 jfs_error(ip->i_sb, "numfree > numinos\n");
1661 return -EIO;
1662 }
1663
1664
1665
1666
1667
1668
1669 if (dir)
1670 addext = (numfree < 64 ||
1671 (numfree < 256
1672 && ((numfree * 100) / numinos) <= 20));
1673 else
1674 addext = (numfree == 0);
1675
1676
1677
1678
1679 if (addext) {
1680
1681
1682
1683
1684 if ((rc = diAllocExt(imap, agno, ip)) != -ENOSPC)
1685 return (rc);
1686 }
1687
1688
1689
1690
1691 return (diAllocIno(imap, agno, ip));
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
1717
1718static int
1719diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
1720{
1721 int ag, rc;
1722 int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
1723
1724
1725
1726
1727
1728 for (ag = agno + 1; ag <= maxag; ag++) {
1729 AG_LOCK(imap, ag);
1730
1731 rc = diAllocAG(imap, ag, dir, ip);
1732
1733 AG_UNLOCK(imap, ag);
1734
1735 if (rc != -ENOSPC)
1736 return (rc);
1737 }
1738
1739
1740
1741 for (ag = 0; ag < agno; ag++) {
1742 AG_LOCK(imap, ag);
1743
1744 rc = diAllocAG(imap, ag, dir, ip);
1745
1746 AG_UNLOCK(imap, ag);
1747
1748 if (rc != -ENOSPC)
1749 return (rc);
1750 }
1751
1752
1753
1754 return -ENOSPC;
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
1782
1783static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1784{
1785 int iagno, ino, rc, rem, extno, sword;
1786 struct metapage *mp;
1787 struct iag *iagp;
1788
1789
1790
1791 if ((iagno = imap->im_agctl[agno].inofree) < 0)
1792 return -ENOSPC;
1793
1794
1795 IREAD_LOCK(imap->im_ipimap, RDWRLOCK_IMAP);
1796
1797
1798
1799 if ((rc = diIAGRead(imap, iagno, &mp))) {
1800 IREAD_UNLOCK(imap->im_ipimap);
1801 return (rc);
1802 }
1803 iagp = (struct iag *) mp->data;
1804
1805
1806
1807
1808 if (!iagp->nfreeinos) {
1809 IREAD_UNLOCK(imap->im_ipimap);
1810 release_metapage(mp);
1811 jfs_error(ip->i_sb, "nfreeinos = 0, but iag on freelist\n");
1812 return -EIO;
1813 }
1814
1815
1816
1817
1818 for (sword = 0;; sword++) {
1819 if (sword >= SMAPSZ) {
1820 IREAD_UNLOCK(imap->im_ipimap);
1821 release_metapage(mp);
1822 jfs_error(ip->i_sb,
1823 "free inode not found in summary map\n");
1824 return -EIO;
1825 }
1826
1827 if (~iagp->inosmap[sword])
1828 break;
1829 }
1830
1831
1832
1833
1834 rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0);
1835 if (rem >= EXTSPERSUM) {
1836 IREAD_UNLOCK(imap->im_ipimap);
1837 release_metapage(mp);
1838 jfs_error(ip->i_sb, "no free extent found\n");
1839 return -EIO;
1840 }
1841 extno = (sword << L2EXTSPERSUM) + rem;
1842
1843
1844
1845 rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0);
1846 if (rem >= INOSPEREXT) {
1847 IREAD_UNLOCK(imap->im_ipimap);
1848 release_metapage(mp);
1849 jfs_error(ip->i_sb, "free inode not found\n");
1850 return -EIO;
1851 }
1852
1853
1854
1855 ino = (extno << L2INOSPEREXT) + rem;
1856
1857
1858
1859 rc = diAllocBit(imap, iagp, ino);
1860 IREAD_UNLOCK(imap->im_ipimap);
1861 if (rc) {
1862 release_metapage(mp);
1863 return (rc);
1864 }
1865
1866
1867
1868 diInitInode(ip, iagno, ino, extno, iagp);
1869 write_metapage(mp);
1870
1871 return (0);
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
1906
1907static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
1908{
1909 int rem, iagno, sword, extno, rc;
1910 struct metapage *mp;
1911 struct iag *iagp;
1912
1913
1914
1915
1916 if ((iagno = imap->im_agctl[agno].extfree) < 0) {
1917
1918
1919
1920 if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
1921 return (rc);
1922 }
1923 iagp = (struct iag *) mp->data;
1924
1925
1926
1927 iagp->agstart =
1928 cpu_to_le64(AGTOBLK(agno, imap->im_ipimap));
1929 } else {
1930
1931
1932 IREAD_LOCK(imap->im_ipimap, RDWRLOCK_IMAP);
1933 if ((rc = diIAGRead(imap, iagno, &mp))) {
1934 IREAD_UNLOCK(imap->im_ipimap);
1935 jfs_error(ip->i_sb, "error reading iag\n");
1936 return rc;
1937 }
1938 iagp = (struct iag *) mp->data;
1939 }
1940
1941
1942
1943 for (sword = 0;; sword++) {
1944 if (sword >= SMAPSZ) {
1945 release_metapage(mp);
1946 IREAD_UNLOCK(imap->im_ipimap);
1947 jfs_error(ip->i_sb, "free ext summary map not found\n");
1948 return -EIO;
1949 }
1950 if (~iagp->extsmap[sword])
1951 break;
1952 }
1953
1954
1955
1956 rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0);
1957 if (rem >= EXTSPERSUM) {
1958 release_metapage(mp);
1959 IREAD_UNLOCK(imap->im_ipimap);
1960 jfs_error(ip->i_sb, "free extent not found\n");
1961 return -EIO;
1962 }
1963 extno = (sword << L2EXTSPERSUM) + rem;
1964
1965
1966
1967 rc = diNewExt(imap, iagp, extno);
1968 IREAD_UNLOCK(imap->im_ipimap);
1969 if (rc) {
1970
1971
1972
1973
1974 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
1975 IAGFREE_LOCK(imap);
1976 iagp->iagfree = cpu_to_le32(imap->im_freeiag);
1977 imap->im_freeiag = iagno;
1978 IAGFREE_UNLOCK(imap);
1979 }
1980 write_metapage(mp);
1981 return (rc);
1982 }
1983
1984
1985
1986 diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp);
1987
1988 write_metapage(mp);
1989
1990 return (0);
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
2023
2024static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2025{
2026 int extno, bitno, agno, sword, rc;
2027 struct metapage *amp = NULL, *bmp = NULL;
2028 struct iag *aiagp = NULL, *biagp = NULL;
2029 u32 mask;
2030
2031
2032
2033
2034
2035
2036 if (iagp->nfreeinos == cpu_to_le32(1)) {
2037 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
2038 if ((rc =
2039 diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
2040 &)))
2041 return (rc);
2042 aiagp = (struct iag *) amp->data;
2043 }
2044
2045 if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
2046 if ((rc =
2047 diIAGRead(imap,
2048 le32_to_cpu(iagp->inofreeback),
2049 &bmp))) {
2050 if (amp)
2051 release_metapage(amp);
2052 return (rc);
2053 }
2054 biagp = (struct iag *) bmp->data;
2055 }
2056 }
2057
2058
2059
2060
2061 agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb));
2062 extno = ino >> L2INOSPEREXT;
2063 bitno = ino & (INOSPEREXT - 1);
2064
2065
2066
2067 mask = HIGHORDER >> bitno;
2068
2069
2070
2071 if (((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) ||
2072 ((le32_to_cpu(iagp->wmap[extno]) & mask) != 0) ||
2073 (addressPXD(&iagp->inoext[extno]) == 0)) {
2074 if (amp)
2075 release_metapage(amp);
2076 if (bmp)
2077 release_metapage(bmp);
2078
2079 jfs_error(imap->im_ipimap->i_sb, "iag inconsistent\n");
2080 return -EIO;
2081 }
2082
2083
2084
2085 iagp->wmap[extno] |= cpu_to_le32(mask);
2086
2087
2088
2089
2090
2091 if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
2092 sword = extno >> L2EXTSPERSUM;
2093 bitno = extno & (EXTSPERSUM - 1);
2094 iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno);
2095 }
2096
2097
2098
2099
2100 if (iagp->nfreeinos == cpu_to_le32(1)) {
2101 if (amp) {
2102 aiagp->inofreeback = iagp->inofreeback;
2103 write_metapage(amp);
2104 }
2105
2106 if (bmp) {
2107 biagp->inofreefwd = iagp->inofreefwd;
2108 write_metapage(bmp);
2109 } else {
2110 imap->im_agctl[agno].inofree =
2111 le32_to_cpu(iagp->inofreefwd);
2112 }
2113 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
2114 }
2115
2116
2117
2118
2119 le32_add_cpu(&iagp->nfreeinos, -1);
2120 imap->im_agctl[agno].numfree -= 1;
2121 atomic_dec(&imap->im_numfree);
2122
2123 return (0);
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
2169
2170static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2171{
2172 int agno, iagno, fwd, back, freei = 0, sword, rc;
2173 struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL;
2174 struct metapage *amp, *bmp, *cmp, *dmp;
2175 struct inode *ipimap;
2176 s64 blkno, hint;
2177 int i, j;
2178 u32 mask;
2179 ino_t ino;
2180 struct dinode *dp;
2181 struct jfs_sb_info *sbi;
2182
2183
2184
2185 if (!iagp->nfreeexts) {
2186 jfs_error(imap->im_ipimap->i_sb, "no free extents\n");
2187 return -EIO;
2188 }
2189
2190
2191
2192 ipimap = imap->im_ipimap;
2193 sbi = JFS_SBI(ipimap->i_sb);
2194
2195 amp = bmp = cmp = NULL;
2196
2197
2198
2199 agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
2200 iagno = le32_to_cpu(iagp->iagnum);
2201
2202
2203
2204
2205
2206
2207 if (iagp->nfreeexts == cpu_to_le32(1)) {
2208 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
2209 if ((rc = diIAGRead(imap, fwd, &)))
2210 return (rc);
2211 aiagp = (struct iag *) amp->data;
2212 }
2213
2214 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
2215 if ((rc = diIAGRead(imap, back, &bmp)))
2216 goto error_out;
2217 biagp = (struct iag *) bmp->data;
2218 }
2219 } else {
2220
2221
2222
2223
2224
2225
2226 fwd = back = -1;
2227 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2228 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
2229 if ((rc = diIAGRead(imap, fwd, &)))
2230 goto error_out;
2231 aiagp = (struct iag *) amp->data;
2232 }
2233 }
2234 }
2235
2236
2237
2238
2239
2240
2241
2242
2243 if (iagp->nfreeinos == 0) {
2244 freei = imap->im_agctl[agno].inofree;
2245
2246 if (freei >= 0) {
2247 if (freei == fwd) {
2248 ciagp = aiagp;
2249 } else if (freei == back) {
2250 ciagp = biagp;
2251 } else {
2252 if ((rc = diIAGRead(imap, freei, &cmp)))
2253 goto error_out;
2254 ciagp = (struct iag *) cmp->data;
2255 }
2256 if (ciagp == NULL) {
2257 jfs_error(imap->im_ipimap->i_sb,
2258 "ciagp == NULL\n");
2259 rc = -EIO;
2260 goto error_out;
2261 }
2262 }
2263 }
2264
2265
2266
2267 if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0))
2268 hint = ((s64) agno << sbi->bmap->db_agl2size) - 1;
2269 else
2270 hint = addressPXD(&iagp->inoext[extno - 1]) +
2271 lengthPXD(&iagp->inoext[extno - 1]) - 1;
2272
2273 if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno)))
2274 goto error_out;
2275
2276
2277
2278
2279 ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT);
2280
2281
2282
2283
2284 for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) {
2285
2286
2287 dmp = get_metapage(ipimap, blkno + i, PSIZE, 1);
2288 if (dmp == NULL) {
2289 rc = -EIO;
2290 goto error_out;
2291 }
2292 dp = (struct dinode *) dmp->data;
2293
2294
2295
2296
2297 for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) {
2298 dp->di_inostamp = cpu_to_le32(sbi->inostamp);
2299 dp->di_number = cpu_to_le32(ino);
2300 dp->di_fileset = cpu_to_le32(FILESYSTEM_I);
2301 dp->di_mode = 0;
2302 dp->di_nlink = 0;
2303 PXDaddress(&(dp->di_ixpxd), blkno);
2304 PXDlength(&(dp->di_ixpxd), imap->im_nbperiext);
2305 }
2306 write_metapage(dmp);
2307 }
2308
2309
2310
2311
2312 if (iagp->nfreeexts == cpu_to_le32(1)) {
2313 if (fwd >= 0)
2314 aiagp->extfreeback = iagp->extfreeback;
2315
2316 if (back >= 0)
2317 biagp->extfreefwd = iagp->extfreefwd;
2318 else
2319 imap->im_agctl[agno].extfree =
2320 le32_to_cpu(iagp->extfreefwd);
2321
2322 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
2323 } else {
2324
2325
2326
2327 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2328 if (fwd >= 0)
2329 aiagp->extfreeback = cpu_to_le32(iagno);
2330
2331 iagp->extfreefwd = cpu_to_le32(fwd);
2332 iagp->extfreeback = cpu_to_le32(-1);
2333 imap->im_agctl[agno].extfree = iagno;
2334 }
2335 }
2336
2337
2338
2339
2340 if (iagp->nfreeinos == 0) {
2341 if (freei >= 0)
2342 ciagp->inofreeback = cpu_to_le32(iagno);
2343
2344 iagp->inofreefwd =
2345 cpu_to_le32(imap->im_agctl[agno].inofree);
2346 iagp->inofreeback = cpu_to_le32(-1);
2347 imap->im_agctl[agno].inofree = iagno;
2348 }
2349
2350
2351 PXDlength(&iagp->inoext[extno], imap->im_nbperiext);
2352 PXDaddress(&iagp->inoext[extno], blkno);
2353
2354
2355
2356
2357
2358 iagp->wmap[extno] = cpu_to_le32(HIGHORDER);
2359 iagp->pmap[extno] = 0;
2360
2361
2362
2363
2364
2365 sword = extno >> L2EXTSPERSUM;
2366 mask = HIGHORDER >> (extno & (EXTSPERSUM - 1));
2367 iagp->extsmap[sword] |= cpu_to_le32(mask);
2368 iagp->inosmap[sword] &= cpu_to_le32(~mask);
2369
2370
2371
2372
2373 le32_add_cpu(&iagp->nfreeinos, (INOSPEREXT - 1));
2374 le32_add_cpu(&iagp->nfreeexts, -1);
2375
2376
2377
2378 imap->im_agctl[agno].numfree += (INOSPEREXT - 1);
2379 imap->im_agctl[agno].numinos += INOSPEREXT;
2380
2381
2382
2383 atomic_add(INOSPEREXT - 1, &imap->im_numfree);
2384 atomic_add(INOSPEREXT, &imap->im_numinos);
2385
2386
2387
2388 if (amp)
2389 write_metapage(amp);
2390 if (bmp)
2391 write_metapage(bmp);
2392 if (cmp)
2393 write_metapage(cmp);
2394
2395 return (0);
2396
2397 error_out:
2398
2399
2400
2401 if (amp)
2402 release_metapage(amp);
2403 if (bmp)
2404 release_metapage(bmp);
2405 if (cmp)
2406 release_metapage(cmp);
2407
2408 return (rc);
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
2450
2451static int
2452diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2453{
2454 int rc;
2455 int iagno, i, xlen;
2456 struct inode *ipimap;
2457 struct super_block *sb;
2458 struct jfs_sb_info *sbi;
2459 struct metapage *mp;
2460 struct iag *iagp;
2461 s64 xaddr = 0;
2462 s64 blkno;
2463 tid_t tid;
2464 struct inode *iplist[1];
2465
2466
2467 ipimap = imap->im_ipimap;
2468 sb = ipimap->i_sb;
2469 sbi = JFS_SBI(sb);
2470
2471
2472 IAGFREE_LOCK(imap);
2473
2474
2475
2476
2477 if (imap->im_freeiag >= 0) {
2478
2479 iagno = imap->im_freeiag;
2480
2481
2482 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2483 } else {
2484
2485
2486
2487
2488
2489 IWRITE_LOCK(ipimap, RDWRLOCK_IMAP);
2490
2491 if (ipimap->i_size >> L2PSIZE != imap->im_nextiag + 1) {
2492 IWRITE_UNLOCK(ipimap);
2493 IAGFREE_UNLOCK(imap);
2494 jfs_error(imap->im_ipimap->i_sb,
2495 "ipimap->i_size is wrong\n");
2496 return -EIO;
2497 }
2498
2499
2500
2501 iagno = imap->im_nextiag;
2502
2503
2504
2505
2506 if (iagno > (MAXIAGS - 1)) {
2507
2508 IWRITE_UNLOCK(ipimap);
2509
2510 rc = -ENOSPC;
2511 goto out;
2512 }
2513
2514
2515
2516
2517
2518 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
2519
2520
2521 xlen = sbi->nbperpage;
2522 if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {
2523
2524 IWRITE_UNLOCK(ipimap);
2525
2526 goto out;
2527 }
2528
2529
2530
2531
2532
2533 tid = txBegin(sb, COMMIT_FORCE);
2534 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
2535
2536
2537 if ((rc =
2538 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2539 txEnd(tid);
2540 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2541
2542
2543
2544 dbFree(ipimap, xaddr, (s64) xlen);
2545
2546
2547 IWRITE_UNLOCK(ipimap);
2548
2549 goto out;
2550 }
2551
2552
2553 ipimap->i_size += PSIZE;
2554 inode_add_bytes(ipimap, PSIZE);
2555
2556
2557 mp = get_metapage(ipimap, blkno, PSIZE, 0);
2558 if (!mp) {
2559
2560
2561
2562
2563 xtTruncate(tid, ipimap, ipimap->i_size - PSIZE,
2564 COMMIT_PWMAP);
2565
2566 txAbort(tid, 0);
2567 txEnd(tid);
2568 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2569
2570
2571 IWRITE_UNLOCK(ipimap);
2572
2573 rc = -EIO;
2574 goto out;
2575 }
2576 iagp = (struct iag *) mp->data;
2577
2578
2579 memset(iagp, 0, sizeof(struct iag));
2580 iagp->iagnum = cpu_to_le32(iagno);
2581 iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
2582 iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);
2583 iagp->iagfree = cpu_to_le32(-1);
2584 iagp->nfreeinos = 0;
2585 iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);
2586
2587
2588
2589
2590 for (i = 0; i < SMAPSZ; i++)
2591 iagp->inosmap[i] = cpu_to_le32(ONES);
2592
2593
2594
2595
2596 flush_metapage(mp);
2597
2598
2599
2600
2601
2602
2603 iplist[0] = ipimap;
2604 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2605
2606 txEnd(tid);
2607 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2608
2609 duplicateIXtree(sb, blkno, xlen, &xaddr);
2610
2611
2612 imap->im_nextiag += 1;
2613
2614
2615
2616
2617 imap->im_freeiag = iagno;
2618
2619
2620
2621
2622 diSync(ipimap);
2623
2624
2625 IWRITE_UNLOCK(ipimap);
2626 }
2627
2628
2629 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
2630
2631
2632 if ((rc = diIAGRead(imap, iagno, &mp))) {
2633 IREAD_UNLOCK(ipimap);
2634 rc = -EIO;
2635 goto out;
2636 }
2637 iagp = (struct iag *) mp->data;
2638
2639
2640 imap->im_freeiag = le32_to_cpu(iagp->iagfree);
2641 iagp->iagfree = cpu_to_le32(-1);
2642
2643
2644 *iagnop = iagno;
2645 *mpp = mp;
2646
2647 out:
2648
2649 IAGFREE_UNLOCK(imap);
2650
2651 return (rc);
2652}
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
2676{
2677 struct inode *ipimap = imap->im_ipimap;
2678 s64 blkno;
2679
2680
2681 blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage);
2682
2683
2684 *mpp = read_metapage(ipimap, blkno, PSIZE, 0);
2685 if (*mpp == NULL) {
2686 return -EIO;
2687 }
2688
2689 return (0);
2690}
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706static int diFindFree(u32 word, int start)
2707{
2708 int bitno;
2709 assert(start < 32);
2710
2711 for (word <<= start, bitno = start; bitno < 32;
2712 bitno++, word <<= 1) {
2713 if ((word & HIGHORDER) == 0)
2714 break;
2715 }
2716 return (bitno);
2717}
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736int
2737diUpdatePMap(struct inode *ipimap,
2738 unsigned long inum, bool is_free, struct tblock * tblk)
2739{
2740 int rc;
2741 struct iag *iagp;
2742 struct metapage *mp;
2743 int iagno, ino, extno, bitno;
2744 struct inomap *imap;
2745 u32 mask;
2746 struct jfs_log *log;
2747 int lsn, difft, diffp;
2748 unsigned long flags;
2749
2750 imap = JFS_IP(ipimap)->i_imap;
2751
2752 iagno = INOTOIAG(inum);
2753
2754 if (iagno >= imap->im_nextiag) {
2755 jfs_error(ipimap->i_sb, "the iag is outside the map\n");
2756 return -EIO;
2757 }
2758
2759 IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
2760 rc = diIAGRead(imap, iagno, &mp);
2761 IREAD_UNLOCK(ipimap);
2762 if (rc)
2763 return (rc);
2764 metapage_wait_for_io(mp);
2765 iagp = (struct iag *) mp->data;
2766
2767
2768
2769 ino = inum & (INOSPERIAG - 1);
2770 extno = ino >> L2INOSPEREXT;
2771 bitno = ino & (INOSPEREXT - 1);
2772 mask = HIGHORDER >> bitno;
2773
2774
2775
2776 if (is_free) {
2777
2778
2779
2780
2781
2782 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2783 jfs_error(ipimap->i_sb,
2784 "inode %ld not marked as allocated in wmap!\n",
2785 inum);
2786 }
2787 if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
2788 jfs_error(ipimap->i_sb,
2789 "inode %ld not marked as allocated in pmap!\n",
2790 inum);
2791 }
2792
2793 iagp->pmap[extno] &= cpu_to_le32(~mask);
2794 }
2795
2796
2797
2798 else {
2799
2800
2801
2802 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2803 release_metapage(mp);
2804 jfs_error(ipimap->i_sb,
2805 "the inode is not allocated in the working map\n");
2806 return -EIO;
2807 }
2808 if ((le32_to_cpu(iagp->pmap[extno]) & mask) != 0) {
2809 release_metapage(mp);
2810 jfs_error(ipimap->i_sb,
2811 "the inode is not free in the persistent map\n");
2812 return -EIO;
2813 }
2814
2815 iagp->pmap[extno] |= cpu_to_le32(mask);
2816 }
2817
2818
2819
2820 lsn = tblk->lsn;
2821 log = JFS_SBI(tblk->sb)->log;
2822 LOGSYNC_LOCK(log, flags);
2823 if (mp->lsn != 0) {
2824
2825 logdiff(difft, lsn, log);
2826 logdiff(diffp, mp->lsn, log);
2827 if (difft < diffp) {
2828 mp->lsn = lsn;
2829
2830 list_move(&mp->synclist, &tblk->synclist);
2831 }
2832
2833 assert(mp->clsn);
2834 logdiff(difft, tblk->clsn, log);
2835 logdiff(diffp, mp->clsn, log);
2836 if (difft > diffp)
2837 mp->clsn = tblk->clsn;
2838 } else {
2839 mp->log = log;
2840 mp->lsn = lsn;
2841
2842 log->count++;
2843 list_add(&mp->synclist, &tblk->synclist);
2844 mp->clsn = tblk->clsn;
2845 }
2846 LOGSYNC_UNLOCK(log, flags);
2847 write_metapage(mp);
2848 return (0);
2849}
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2860{
2861 int rc, rcx = 0;
2862 struct inomap *imap = JFS_IP(ipimap)->i_imap;
2863 struct iag *iagp = NULL, *hiagp = NULL;
2864 struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
2865 struct metapage *bp, *hbp;
2866 int i, n, head;
2867 int numinos, xnuminos = 0, xnumfree = 0;
2868 s64 agstart;
2869
2870 jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d",
2871 imap->im_nextiag, atomic_read(&imap->im_numinos),
2872 atomic_read(&imap->im_numfree));
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883 for (i = 0; i < MAXAG; i++) {
2884 imap->im_agctl[i].inofree = -1;
2885 imap->im_agctl[i].extfree = -1;
2886 imap->im_agctl[i].numinos = 0;
2887 imap->im_agctl[i].numfree = 0;
2888 }
2889
2890
2891
2892
2893
2894
2895 for (i = 0; i < imap->im_nextiag; i++) {
2896 if ((rc = diIAGRead(imap, i, &bp))) {
2897 rcx = rc;
2898 continue;
2899 }
2900 iagp = (struct iag *) bp->data;
2901 if (le32_to_cpu(iagp->iagnum) != i) {
2902 release_metapage(bp);
2903 jfs_error(ipimap->i_sb, "unexpected value of iagnum\n");
2904 return -EIO;
2905 }
2906
2907
2908 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2909 release_metapage(bp);
2910 continue;
2911 }
2912
2913 agstart = le64_to_cpu(iagp->agstart);
2914 n = agstart >> mp->db_agl2size;
2915 iagp->agstart = cpu_to_le64((s64)n << mp->db_agl2size);
2916
2917
2918 numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts))
2919 << L2INOSPEREXT;
2920 if (numinos > 0) {
2921
2922 imap->im_agctl[n].numinos += numinos;
2923 xnuminos += numinos;
2924 }
2925
2926
2927 if ((int) le32_to_cpu(iagp->nfreeinos) > 0) {
2928 if ((head = imap->im_agctl[n].inofree) == -1) {
2929 iagp->inofreefwd = cpu_to_le32(-1);
2930 iagp->inofreeback = cpu_to_le32(-1);
2931 } else {
2932 if ((rc = diIAGRead(imap, head, &hbp))) {
2933 rcx = rc;
2934 goto nextiag;
2935 }
2936 hiagp = (struct iag *) hbp->data;
2937 hiagp->inofreeback = iagp->iagnum;
2938 iagp->inofreefwd = cpu_to_le32(head);
2939 iagp->inofreeback = cpu_to_le32(-1);
2940 write_metapage(hbp);
2941 }
2942
2943 imap->im_agctl[n].inofree =
2944 le32_to_cpu(iagp->iagnum);
2945
2946
2947 imap->im_agctl[n].numfree +=
2948 le32_to_cpu(iagp->nfreeinos);
2949 xnumfree += le32_to_cpu(iagp->nfreeinos);
2950 }
2951
2952
2953 if (le32_to_cpu(iagp->nfreeexts) > 0) {
2954 if ((head = imap->im_agctl[n].extfree) == -1) {
2955 iagp->extfreefwd = cpu_to_le32(-1);
2956 iagp->extfreeback = cpu_to_le32(-1);
2957 } else {
2958 if ((rc = diIAGRead(imap, head, &hbp))) {
2959 rcx = rc;
2960 goto nextiag;
2961 }
2962 hiagp = (struct iag *) hbp->data;
2963 hiagp->extfreeback = iagp->iagnum;
2964 iagp->extfreefwd = cpu_to_le32(head);
2965 iagp->extfreeback = cpu_to_le32(-1);
2966 write_metapage(hbp);
2967 }
2968
2969 imap->im_agctl[n].extfree =
2970 le32_to_cpu(iagp->iagnum);
2971 }
2972
2973 nextiag:
2974 write_metapage(bp);
2975 }
2976
2977 if (xnuminos != atomic_read(&imap->im_numinos) ||
2978 xnumfree != atomic_read(&imap->im_numfree)) {
2979 jfs_error(ipimap->i_sb, "numinos or numfree incorrect\n");
2980 return -EIO;
2981 }
2982
2983 return rcx;
2984}
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994static void duplicateIXtree(struct super_block *sb, s64 blkno,
2995 int xlen, s64 *xaddr)
2996{
2997 struct jfs_superblock *j_sb;
2998 struct buffer_head *bh;
2999 struct inode *ip;
3000 tid_t tid;
3001
3002
3003 if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)
3004 return;
3005 ip = diReadSpecial(sb, FILESYSTEM_I, 1);
3006 if (ip == NULL) {
3007 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
3008 if (readSuper(sb, &bh))
3009 return;
3010 j_sb = (struct jfs_superblock *)bh->b_data;
3011 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
3012
3013 mark_buffer_dirty(bh);
3014 sync_dirty_buffer(bh);
3015 brelse(bh);
3016 return;
3017 }
3018
3019
3020 tid = txBegin(sb, COMMIT_FORCE);
3021
3022 if (xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0)) {
3023 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
3024 txAbort(tid, 1);
3025 goto cleanup;
3026
3027 }
3028
3029 ip->i_size += PSIZE;
3030 inode_add_bytes(ip, PSIZE);
3031 txCommit(tid, 1, &ip, COMMIT_FORCE);
3032 cleanup:
3033 txEnd(tid);
3034 diFreeSpecial(ip);
3035}
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3047{
3048 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3049 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3050
3051 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3052 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3053 jfs_set_inode_flags(ip);
3054
3055 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3056 if (sbi->umask != -1) {
3057 ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask);
3058
3059 if (S_ISDIR(ip->i_mode)) {
3060 if (ip->i_mode & 0400)
3061 ip->i_mode |= 0100;
3062 if (ip->i_mode & 0040)
3063 ip->i_mode |= 0010;
3064 if (ip->i_mode & 0004)
3065 ip->i_mode |= 0001;
3066 }
3067 }
3068 set_nlink(ip, le32_to_cpu(dip->di_nlink));
3069
3070 jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3071 if (!uid_valid(sbi->uid))
3072 ip->i_uid = jfs_ip->saved_uid;
3073 else {
3074 ip->i_uid = sbi->uid;
3075 }
3076
3077 jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3078 if (!gid_valid(sbi->gid))
3079 ip->i_gid = jfs_ip->saved_gid;
3080 else {
3081 ip->i_gid = sbi->gid;
3082 }
3083
3084 ip->i_size = le64_to_cpu(dip->di_size);
3085 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
3086 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
3087 ip->i_mtime.tv_sec = le32_to_cpu(dip->di_mtime.tv_sec);
3088 ip->i_mtime.tv_nsec = le32_to_cpu(dip->di_mtime.tv_nsec);
3089 ip->i_ctime.tv_sec = le32_to_cpu(dip->di_ctime.tv_sec);
3090 ip->i_ctime.tv_nsec = le32_to_cpu(dip->di_ctime.tv_nsec);
3091 ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks));
3092 ip->i_generation = le32_to_cpu(dip->di_gen);
3093
3094 jfs_ip->ixpxd = dip->di_ixpxd;
3095 jfs_ip->acl = dip->di_acl;
3096 jfs_ip->ea = dip->di_ea;
3097 jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
3098 jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
3099 jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
3100
3101 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) {
3102 jfs_ip->dev = le32_to_cpu(dip->di_rdev);
3103 ip->i_rdev = new_decode_dev(jfs_ip->dev);
3104 }
3105
3106 if (S_ISDIR(ip->i_mode)) {
3107 memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
3108 } else if (S_ISREG(ip->i_mode) || S_ISLNK(ip->i_mode)) {
3109 memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288);
3110 } else
3111 memcpy(&jfs_ip->i_inline_ea, &dip->di_inlineea, 128);
3112
3113
3114 jfs_ip->cflag = 0;
3115 jfs_ip->btindex = 0;
3116 jfs_ip->btorder = 0;
3117 jfs_ip->bxflag = 0;
3118 jfs_ip->blid = 0;
3119 jfs_ip->atlhead = 0;
3120 jfs_ip->atltail = 0;
3121 jfs_ip->xtlid = 0;
3122 return (0);
3123}
3124
3125
3126
3127
3128
3129
3130static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3131{
3132 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3133 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3134
3135 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3136 dip->di_inostamp = cpu_to_le32(sbi->inostamp);
3137 dip->di_number = cpu_to_le32(ip->i_ino);
3138 dip->di_gen = cpu_to_le32(ip->i_generation);
3139 dip->di_size = cpu_to_le64(ip->i_size);
3140 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3141 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3142 if (!uid_valid(sbi->uid))
3143 dip->di_uid = cpu_to_le32(i_uid_read(ip));
3144 else
3145 dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3146 jfs_ip->saved_uid));
3147 if (!gid_valid(sbi->gid))
3148 dip->di_gid = cpu_to_le32(i_gid_read(ip));
3149 else
3150 dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3151 jfs_ip->saved_gid));
3152 jfs_get_inode_flags(jfs_ip);
3153
3154
3155
3156
3157 if (sbi->umask == -1)
3158 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) |
3159 ip->i_mode);
3160 else
3161 dip->di_mode = cpu_to_le32(jfs_ip->mode2);
3162
3163 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
3164 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
3165 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
3166 dip->di_ctime.tv_nsec = cpu_to_le32(ip->i_ctime.tv_nsec);
3167 dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime.tv_sec);
3168 dip->di_mtime.tv_nsec = cpu_to_le32(ip->i_mtime.tv_nsec);
3169 dip->di_ixpxd = jfs_ip->ixpxd;
3170 dip->di_acl = jfs_ip->acl;
3171 dip->di_ea = jfs_ip->ea;
3172 dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
3173 dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
3174 dip->di_otime.tv_nsec = 0;
3175 dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
3176 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
3177 dip->di_rdev = cpu_to_le32(jfs_ip->dev);
3178}
3179