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