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