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