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