aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs/super.c')
-rw-r--r--fs/ufs/super.c140
1 files changed, 103 insertions, 37 deletions
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 3aadbd3167a6..74ef5e9bedff 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -381,24 +381,57 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
381} 381}
382 382
383/* 383/*
384 * Read on-disk structures associated with cylinder groups 384 * Diffrent types of UFS hold fs_cstotal in different
385 * places, and use diffrent data structure for it.
386 * To make things simplier we just copy fs_cstotal to ufs_sb_private_info
385 */ 387 */
386static int ufs_read_cylinder_structures (struct super_block *sb) 388static void ufs_setup_cstotal(struct super_block *sb)
387{ 389{
388 struct ufs_sb_info *sbi = UFS_SB(sb); 390 struct ufs_sb_info *sbi = UFS_SB(sb);
389 struct ufs_sb_private_info *uspi = sbi->s_uspi; 391 struct ufs_sb_private_info *uspi = sbi->s_uspi;
392 struct ufs_super_block_first *usb1;
393 struct ufs_super_block_second *usb2;
390 struct ufs_super_block_third *usb3; 394 struct ufs_super_block_third *usb3;
395 unsigned mtype = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
396
397 UFSD("ENTER, mtype=%u\n", mtype);
398 usb1 = ubh_get_usb_first(uspi);
399 usb2 = ubh_get_usb_second(uspi);
400 usb3 = ubh_get_usb_third(uspi);
401
402 if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
403 (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
404 mtype == UFS_MOUNT_UFSTYPE_UFS2) {
405 /*we have statistic in different place, then usual*/
406 uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir);
407 uspi->cs_total.cs_nbfree = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree);
408 uspi->cs_total.cs_nifree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);
409 uspi->cs_total.cs_nffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);
410 } else {
411 uspi->cs_total.cs_ndir = fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir);
412 uspi->cs_total.cs_nbfree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree);
413 uspi->cs_total.cs_nifree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
414 uspi->cs_total.cs_nffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
415 }
416 UFSD("EXIT\n");
417}
418
419/*
420 * Read on-disk structures associated with cylinder groups
421 */
422static int ufs_read_cylinder_structures(struct super_block *sb)
423{
424 struct ufs_sb_info *sbi = UFS_SB(sb);
425 struct ufs_sb_private_info *uspi = sbi->s_uspi;
426 unsigned flags = sbi->s_flags;
391 struct ufs_buffer_head * ubh; 427 struct ufs_buffer_head * ubh;
392 unsigned char * base, * space; 428 unsigned char * base, * space;
393 unsigned size, blks, i; 429 unsigned size, blks, i;
394 unsigned flags = 0; 430 struct ufs_super_block_third *usb3;
395 431
396 UFSD("ENTER\n"); 432 UFSD("ENTER\n");
397
398 usb3 = ubh_get_usb_third(uspi);
399 433
400 flags = UFS_SB(sb)->s_flags; 434 usb3 = ubh_get_usb_third(uspi);
401
402 /* 435 /*
403 * Read cs structures from (usually) first data block 436 * Read cs structures from (usually) first data block
404 * on the device. 437 * on the device.
@@ -475,21 +508,64 @@ failed:
475} 508}
476 509
477/* 510/*
478 * Put on-disk structures associated with cylinder groups and 511 * Sync our internal copy of fs_cstotal with disk
479 * write them back to disk
480 */ 512 */
481static void ufs_put_cylinder_structures (struct super_block *sb) 513static void ufs_put_cstotal(struct super_block *sb)
482{ 514{
483 struct ufs_sb_info * sbi = UFS_SB(sb); 515 unsigned mtype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
484 struct ufs_sb_private_info * uspi; 516 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
517 struct ufs_super_block_first *usb1;
518 struct ufs_super_block_second *usb2;
519 struct ufs_super_block_third *usb3;
520
521 UFSD("ENTER\n");
522 usb1 = ubh_get_usb_first(uspi);
523 usb2 = ubh_get_usb_second(uspi);
524 usb3 = ubh_get_usb_third(uspi);
525
526 if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
527 (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
528 mtype == UFS_MOUNT_UFSTYPE_UFS2) {
529 /*we have statistic in different place, then usual*/
530 usb2->fs_un.fs_u2.cs_ndir =
531 cpu_to_fs64(sb, uspi->cs_total.cs_ndir);
532 usb2->fs_un.fs_u2.cs_nbfree =
533 cpu_to_fs64(sb, uspi->cs_total.cs_nbfree);
534 usb3->fs_un1.fs_u2.cs_nifree =
535 cpu_to_fs64(sb, uspi->cs_total.cs_nifree);
536 usb3->fs_un1.fs_u2.cs_nffree =
537 cpu_to_fs64(sb, uspi->cs_total.cs_nffree);
538 } else {
539 usb1->fs_cstotal.cs_ndir =
540 cpu_to_fs32(sb, uspi->cs_total.cs_ndir);
541 usb1->fs_cstotal.cs_nbfree =
542 cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);
543 usb1->fs_cstotal.cs_nifree =
544 cpu_to_fs32(sb, uspi->cs_total.cs_nifree);
545 usb1->fs_cstotal.cs_nffree =
546 cpu_to_fs32(sb, uspi->cs_total.cs_nffree);
547 }
548 ubh_mark_buffer_dirty(USPI_UBH(uspi));
549 UFSD("EXIT\n");
550}
551
552/**
553 * ufs_put_super_internal() - put on-disk intrenal structures
554 * @sb: pointer to super_block structure
555 * Put on-disk structures associated with cylinder groups
556 * and write them back to disk, also update cs_total on disk
557 */
558static void ufs_put_super_internal(struct super_block *sb)
559{
560 struct ufs_sb_info *sbi = UFS_SB(sb);
561 struct ufs_sb_private_info *uspi = sbi->s_uspi;
485 struct ufs_buffer_head * ubh; 562 struct ufs_buffer_head * ubh;
486 unsigned char * base, * space; 563 unsigned char * base, * space;
487 unsigned blks, size, i; 564 unsigned blks, size, i;
565
488 566
489 UFSD("ENTER\n"); 567 UFSD("ENTER\n");
490 568 ufs_put_cstotal(sb);
491 uspi = sbi->s_uspi;
492
493 size = uspi->s_cssize; 569 size = uspi->s_cssize;
494 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; 570 blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
495 base = space = (char*) sbi->s_csp; 571 base = space = (char*) sbi->s_csp;
@@ -524,7 +600,6 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
524 struct ufs_super_block_first * usb1; 600 struct ufs_super_block_first * usb1;
525 struct ufs_super_block_second * usb2; 601 struct ufs_super_block_second * usb2;
526 struct ufs_super_block_third * usb3; 602 struct ufs_super_block_third * usb3;
527 struct ufs_super_block *usb;
528 struct ufs_buffer_head * ubh; 603 struct ufs_buffer_head * ubh;
529 struct inode *inode; 604 struct inode *inode;
530 unsigned block_size, super_block_size; 605 unsigned block_size, super_block_size;
@@ -728,8 +803,6 @@ again:
728 usb1 = ubh_get_usb_first(uspi); 803 usb1 = ubh_get_usb_first(uspi);
729 usb2 = ubh_get_usb_second(uspi); 804 usb2 = ubh_get_usb_second(uspi);
730 usb3 = ubh_get_usb_third(uspi); 805 usb3 = ubh_get_usb_third(uspi);
731 usb = (struct ufs_super_block *)
732 ((struct ufs_buffer_head *)uspi)->bh[0]->b_data ;
733 806
734 /* 807 /*
735 * Check ufs magic number 808 * Check ufs magic number
@@ -850,8 +923,7 @@ magic_found:
850 sb->s_flags |= MS_RDONLY; 923 sb->s_flags |= MS_RDONLY;
851 break; 924 break;
852 } 925 }
853 } 926 } else {
854 else {
855 printk("ufs_read_super: fs needs fsck\n"); 927 printk("ufs_read_super: fs needs fsck\n");
856 sb->s_flags |= MS_RDONLY; 928 sb->s_flags |= MS_RDONLY;
857 } 929 }
@@ -952,7 +1024,7 @@ magic_found:
952 if (!sb->s_root) 1024 if (!sb->s_root)
953 goto dalloc_failed; 1025 goto dalloc_failed;
954 1026
955 1027 ufs_setup_cstotal(sb);
956 /* 1028 /*
957 * Read cylinder group structures 1029 * Read cylinder group structures
958 */ 1030 */
@@ -1000,7 +1072,7 @@ static void ufs_write_super(struct super_block *sb)
1000 || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 1072 || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
1001 ufs_set_fs_state(sb, usb1, usb3, 1073 ufs_set_fs_state(sb, usb1, usb3,
1002 UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); 1074 UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
1003 ubh_mark_buffer_dirty (USPI_UBH(uspi)); 1075 ufs_put_cstotal(sb);
1004 } 1076 }
1005 sb->s_dirt = 0; 1077 sb->s_dirt = 0;
1006 UFSD("EXIT\n"); 1078 UFSD("EXIT\n");
@@ -1014,7 +1086,7 @@ static void ufs_put_super(struct super_block *sb)
1014 UFSD("ENTER\n"); 1086 UFSD("ENTER\n");
1015 1087
1016 if (!(sb->s_flags & MS_RDONLY)) 1088 if (!(sb->s_flags & MS_RDONLY))
1017 ufs_put_cylinder_structures (sb); 1089 ufs_put_super_internal(sb);
1018 1090
1019 ubh_brelse_uspi (sbi->s_uspi); 1091 ubh_brelse_uspi (sbi->s_uspi);
1020 kfree (sbi->s_uspi); 1092 kfree (sbi->s_uspi);
@@ -1049,8 +1121,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1049 return -EINVAL; 1121 return -EINVAL;
1050 if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { 1122 if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
1051 new_mount_opt |= ufstype; 1123 new_mount_opt |= ufstype;
1052 } 1124 } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
1053 else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
1054 printk("ufstype can't be changed during remount\n"); 1125 printk("ufstype can't be changed during remount\n");
1055 return -EINVAL; 1126 return -EINVAL;
1056 } 1127 }
@@ -1064,7 +1135,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1064 * fs was mouted as rw, remounting ro 1135 * fs was mouted as rw, remounting ro
1065 */ 1136 */
1066 if (*mount_flags & MS_RDONLY) { 1137 if (*mount_flags & MS_RDONLY) {
1067 ufs_put_cylinder_structures(sb); 1138 ufs_put_super_internal(sb);
1068 usb1->fs_time = cpu_to_fs32(sb, get_seconds()); 1139 usb1->fs_time = cpu_to_fs32(sb, get_seconds());
1069 if ((flags & UFS_ST_MASK) == UFS_ST_SUN 1140 if ((flags & UFS_ST_MASK) == UFS_ST_SUN
1070 || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 1141 || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
@@ -1073,11 +1144,10 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1073 ubh_mark_buffer_dirty (USPI_UBH(uspi)); 1144 ubh_mark_buffer_dirty (USPI_UBH(uspi));
1074 sb->s_dirt = 0; 1145 sb->s_dirt = 0;
1075 sb->s_flags |= MS_RDONLY; 1146 sb->s_flags |= MS_RDONLY;
1076 } 1147 } else {
1077 /* 1148 /*
1078 * fs was mounted as ro, remounting rw 1149 * fs was mounted as ro, remounting rw
1079 */ 1150 */
1080 else {
1081#ifndef CONFIG_UFS_FS_WRITE 1151#ifndef CONFIG_UFS_FS_WRITE
1082 printk("ufs was compiled with read-only support, " 1152 printk("ufs was compiled with read-only support, "
1083 "can't be mounted as read-write\n"); 1153 "can't be mounted as read-write\n");
@@ -1089,7 +1159,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1089 printk("this ufstype is read-only supported\n"); 1159 printk("this ufstype is read-only supported\n");
1090 return -EINVAL; 1160 return -EINVAL;
1091 } 1161 }
1092 if (!ufs_read_cylinder_structures (sb)) { 1162 if (!ufs_read_cylinder_structures(sb)) {
1093 printk("failed during remounting\n"); 1163 printk("failed during remounting\n");
1094 return -EPERM; 1164 return -EPERM;
1095 } 1165 }
@@ -1118,17 +1188,13 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf)
1118 if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { 1188 if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
1119 buf->f_type = UFS2_MAGIC; 1189 buf->f_type = UFS2_MAGIC;
1120 buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize); 1190 buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
1121 buf->f_bfree = ufs_blkstofrags(
1122 fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree)) +
1123 fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);
1124 buf->f_ffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);
1125 } else { 1191 } else {
1126 buf->f_type = UFS_MAGIC; 1192 buf->f_type = UFS_MAGIC;
1127 buf->f_blocks = uspi->s_dsize; 1193 buf->f_blocks = uspi->s_dsize;
1128 buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
1129 fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
1130 buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
1131 } 1194 }
1195 buf->f_bfree = ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
1196 uspi->cs_total.cs_nffree;
1197 buf->f_ffree = uspi->cs_total.cs_nifree;
1132 buf->f_bsize = sb->s_blocksize; 1198 buf->f_bsize = sb->s_blocksize;
1133 buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree)) 1199 buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
1134 ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0; 1200 ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;