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