diff options
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 218 |
1 files changed, 114 insertions, 104 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 48145f505a6a..03b34b738993 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -67,6 +67,11 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem " | |||
67 | "(NILFS)"); | 67 | "(NILFS)"); |
68 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
69 | 69 | ||
70 | struct kmem_cache *nilfs_inode_cachep; | ||
71 | struct kmem_cache *nilfs_transaction_cachep; | ||
72 | struct kmem_cache *nilfs_segbuf_cachep; | ||
73 | struct kmem_cache *nilfs_btree_path_cache; | ||
74 | |||
70 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); | 75 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); |
71 | 76 | ||
72 | /** | 77 | /** |
@@ -129,7 +134,6 @@ void nilfs_warning(struct super_block *sb, const char *function, | |||
129 | va_end(args); | 134 | va_end(args); |
130 | } | 135 | } |
131 | 136 | ||
132 | static struct kmem_cache *nilfs_inode_cachep; | ||
133 | 137 | ||
134 | struct inode *nilfs_alloc_inode_common(struct the_nilfs *nilfs) | 138 | struct inode *nilfs_alloc_inode_common(struct the_nilfs *nilfs) |
135 | { | 139 | { |
@@ -155,34 +159,6 @@ void nilfs_destroy_inode(struct inode *inode) | |||
155 | kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); | 159 | kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); |
156 | } | 160 | } |
157 | 161 | ||
158 | static void init_once(void *obj) | ||
159 | { | ||
160 | struct nilfs_inode_info *ii = obj; | ||
161 | |||
162 | INIT_LIST_HEAD(&ii->i_dirty); | ||
163 | #ifdef CONFIG_NILFS_XATTR | ||
164 | init_rwsem(&ii->xattr_sem); | ||
165 | #endif | ||
166 | nilfs_btnode_cache_init_once(&ii->i_btnode_cache); | ||
167 | ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union; | ||
168 | inode_init_once(&ii->vfs_inode); | ||
169 | } | ||
170 | |||
171 | static int nilfs_init_inode_cache(void) | ||
172 | { | ||
173 | nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache", | ||
174 | sizeof(struct nilfs_inode_info), | ||
175 | 0, SLAB_RECLAIM_ACCOUNT, | ||
176 | init_once); | ||
177 | |||
178 | return (nilfs_inode_cachep == NULL) ? -ENOMEM : 0; | ||
179 | } | ||
180 | |||
181 | static inline void nilfs_destroy_inode_cache(void) | ||
182 | { | ||
183 | kmem_cache_destroy(nilfs_inode_cachep); | ||
184 | } | ||
185 | |||
186 | static void nilfs_clear_inode(struct inode *inode) | 162 | static void nilfs_clear_inode(struct inode *inode) |
187 | { | 163 | { |
188 | struct nilfs_inode_info *ii = NILFS_I(inode); | 164 | struct nilfs_inode_info *ii = NILFS_I(inode); |
@@ -266,8 +242,8 @@ int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) | |||
266 | int err; | 242 | int err; |
267 | 243 | ||
268 | /* nilfs->sem must be locked by the caller. */ | 244 | /* nilfs->sem must be locked by the caller. */ |
269 | if (sbp[0]->s_magic != NILFS_SUPER_MAGIC) { | 245 | if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { |
270 | if (sbp[1] && sbp[1]->s_magic == NILFS_SUPER_MAGIC) | 246 | if (sbp[1] && sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) |
271 | nilfs_swap_super_block(nilfs); | 247 | nilfs_swap_super_block(nilfs); |
272 | else { | 248 | else { |
273 | printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", | 249 | printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", |
@@ -470,10 +446,10 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
470 | if (nilfs_test_opt(sbi, SNAPSHOT)) | 446 | if (nilfs_test_opt(sbi, SNAPSHOT)) |
471 | seq_printf(seq, ",cp=%llu", | 447 | seq_printf(seq, ",cp=%llu", |
472 | (unsigned long long int)sbi->s_snapshot_cno); | 448 | (unsigned long long int)sbi->s_snapshot_cno); |
473 | if (nilfs_test_opt(sbi, ERRORS_RO)) | ||
474 | seq_printf(seq, ",errors=remount-ro"); | ||
475 | if (nilfs_test_opt(sbi, ERRORS_PANIC)) | 449 | if (nilfs_test_opt(sbi, ERRORS_PANIC)) |
476 | seq_printf(seq, ",errors=panic"); | 450 | seq_printf(seq, ",errors=panic"); |
451 | if (nilfs_test_opt(sbi, ERRORS_CONT)) | ||
452 | seq_printf(seq, ",errors=continue"); | ||
477 | if (nilfs_test_opt(sbi, STRICT_ORDER)) | 453 | if (nilfs_test_opt(sbi, STRICT_ORDER)) |
478 | seq_printf(seq, ",order=strict"); | 454 | seq_printf(seq, ",order=strict"); |
479 | if (nilfs_test_opt(sbi, NORECOVERY)) | 455 | if (nilfs_test_opt(sbi, NORECOVERY)) |
@@ -631,7 +607,7 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi, | |||
631 | struct nilfs_super_block *sbp) | 607 | struct nilfs_super_block *sbp) |
632 | { | 608 | { |
633 | sbi->s_mount_opt = | 609 | sbi->s_mount_opt = |
634 | NILFS_MOUNT_ERRORS_CONT | NILFS_MOUNT_BARRIER; | 610 | NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER; |
635 | } | 611 | } |
636 | 612 | ||
637 | static int nilfs_setup_super(struct nilfs_sb_info *sbi) | 613 | static int nilfs_setup_super(struct nilfs_sb_info *sbi) |
@@ -778,9 +754,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
778 | goto failed_sbi; | 754 | goto failed_sbi; |
779 | } | 755 | } |
780 | cno = sbi->s_snapshot_cno; | 756 | cno = sbi->s_snapshot_cno; |
781 | } else | 757 | } |
782 | /* Read-only mount */ | ||
783 | sbi->s_snapshot_cno = cno; | ||
784 | } | 758 | } |
785 | 759 | ||
786 | err = nilfs_attach_checkpoint(sbi, cno); | 760 | err = nilfs_attach_checkpoint(sbi, cno); |
@@ -849,7 +823,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
849 | struct the_nilfs *nilfs = sbi->s_nilfs; | 823 | struct the_nilfs *nilfs = sbi->s_nilfs; |
850 | unsigned long old_sb_flags; | 824 | unsigned long old_sb_flags; |
851 | struct nilfs_mount_options old_opts; | 825 | struct nilfs_mount_options old_opts; |
852 | int err; | 826 | int was_snapshot, err; |
853 | 827 | ||
854 | lock_kernel(); | 828 | lock_kernel(); |
855 | 829 | ||
@@ -857,6 +831,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
857 | old_sb_flags = sb->s_flags; | 831 | old_sb_flags = sb->s_flags; |
858 | old_opts.mount_opt = sbi->s_mount_opt; | 832 | old_opts.mount_opt = sbi->s_mount_opt; |
859 | old_opts.snapshot_cno = sbi->s_snapshot_cno; | 833 | old_opts.snapshot_cno = sbi->s_snapshot_cno; |
834 | was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); | ||
860 | 835 | ||
861 | if (!parse_options(data, sb)) { | 836 | if (!parse_options(data, sb)) { |
862 | err = -EINVAL; | 837 | err = -EINVAL; |
@@ -864,20 +839,32 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
864 | } | 839 | } |
865 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); | 840 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); |
866 | 841 | ||
867 | if ((*flags & MS_RDONLY) && | 842 | err = -EINVAL; |
868 | sbi->s_snapshot_cno != old_opts.snapshot_cno) { | 843 | if (was_snapshot) { |
869 | printk(KERN_WARNING "NILFS (device %s): couldn't " | 844 | if (!(*flags & MS_RDONLY)) { |
870 | "remount to a different snapshot.\n", | 845 | printk(KERN_ERR "NILFS (device %s): cannot remount " |
871 | sb->s_id); | 846 | "snapshot read/write.\n", |
872 | err = -EINVAL; | 847 | sb->s_id); |
873 | goto restore_opts; | 848 | goto restore_opts; |
849 | } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) { | ||
850 | printk(KERN_ERR "NILFS (device %s): cannot " | ||
851 | "remount to a different snapshot.\n", | ||
852 | sb->s_id); | ||
853 | goto restore_opts; | ||
854 | } | ||
855 | } else { | ||
856 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | ||
857 | printk(KERN_ERR "NILFS (device %s): cannot change " | ||
858 | "a regular mount to a snapshot.\n", | ||
859 | sb->s_id); | ||
860 | goto restore_opts; | ||
861 | } | ||
874 | } | 862 | } |
875 | 863 | ||
876 | if (!nilfs_valid_fs(nilfs)) { | 864 | if (!nilfs_valid_fs(nilfs)) { |
877 | printk(KERN_WARNING "NILFS (device %s): couldn't " | 865 | printk(KERN_WARNING "NILFS (device %s): couldn't " |
878 | "remount because the filesystem is in an " | 866 | "remount because the filesystem is in an " |
879 | "incomplete recovery state.\n", sb->s_id); | 867 | "incomplete recovery state.\n", sb->s_id); |
880 | err = -EINVAL; | ||
881 | goto restore_opts; | 868 | goto restore_opts; |
882 | } | 869 | } |
883 | 870 | ||
@@ -888,9 +875,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
888 | nilfs_detach_segment_constructor(sbi); | 875 | nilfs_detach_segment_constructor(sbi); |
889 | sb->s_flags |= MS_RDONLY; | 876 | sb->s_flags |= MS_RDONLY; |
890 | 877 | ||
891 | sbi->s_snapshot_cno = nilfs_last_cno(nilfs); | ||
892 | /* nilfs_set_opt(sbi, SNAPSHOT); */ | ||
893 | |||
894 | /* | 878 | /* |
895 | * Remounting a valid RW partition RDONLY, so set | 879 | * Remounting a valid RW partition RDONLY, so set |
896 | * the RDONLY flag and then mark the partition as valid again. | 880 | * the RDONLY flag and then mark the partition as valid again. |
@@ -909,24 +893,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
909 | * store the current valid flag. (It may have been changed | 893 | * store the current valid flag. (It may have been changed |
910 | * by fsck since we originally mounted the partition.) | 894 | * by fsck since we originally mounted the partition.) |
911 | */ | 895 | */ |
912 | if (nilfs->ns_current && nilfs->ns_current != sbi) { | ||
913 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
914 | "remount because an RW-mount exists.\n", | ||
915 | sb->s_id); | ||
916 | err = -EBUSY; | ||
917 | goto restore_opts; | ||
918 | } | ||
919 | if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { | ||
920 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
921 | "remount because the current RO-mount is not " | ||
922 | "the latest one.\n", | ||
923 | sb->s_id); | ||
924 | err = -EINVAL; | ||
925 | goto restore_opts; | ||
926 | } | ||
927 | sb->s_flags &= ~MS_RDONLY; | 896 | sb->s_flags &= ~MS_RDONLY; |
928 | nilfs_clear_opt(sbi, SNAPSHOT); | ||
929 | sbi->s_snapshot_cno = 0; | ||
930 | 897 | ||
931 | err = nilfs_attach_segment_constructor(sbi); | 898 | err = nilfs_attach_segment_constructor(sbi); |
932 | if (err) | 899 | if (err) |
@@ -935,8 +902,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
935 | down_write(&nilfs->ns_sem); | 902 | down_write(&nilfs->ns_sem); |
936 | nilfs_setup_super(sbi); | 903 | nilfs_setup_super(sbi); |
937 | up_write(&nilfs->ns_sem); | 904 | up_write(&nilfs->ns_sem); |
938 | |||
939 | nilfs->ns_current = sbi; | ||
940 | } | 905 | } |
941 | out: | 906 | out: |
942 | up_write(&nilfs->ns_super_sem); | 907 | up_write(&nilfs->ns_super_sem); |
@@ -1022,10 +987,14 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1022 | { | 987 | { |
1023 | struct nilfs_super_data sd; | 988 | struct nilfs_super_data sd; |
1024 | struct super_block *s; | 989 | struct super_block *s; |
990 | fmode_t mode = FMODE_READ; | ||
1025 | struct the_nilfs *nilfs; | 991 | struct the_nilfs *nilfs; |
1026 | int err, need_to_close = 1; | 992 | int err, need_to_close = 1; |
1027 | 993 | ||
1028 | sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type); | 994 | if (!(flags & MS_RDONLY)) |
995 | mode |= FMODE_WRITE; | ||
996 | |||
997 | sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type); | ||
1029 | if (IS_ERR(sd.bdev)) | 998 | if (IS_ERR(sd.bdev)) |
1030 | return PTR_ERR(sd.bdev); | 999 | return PTR_ERR(sd.bdev); |
1031 | 1000 | ||
@@ -1092,10 +1061,12 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1092 | 1061 | ||
1093 | /* New superblock instance created */ | 1062 | /* New superblock instance created */ |
1094 | s->s_flags = flags; | 1063 | s->s_flags = flags; |
1064 | s->s_mode = mode; | ||
1095 | strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); | 1065 | strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); |
1096 | sb_set_blocksize(s, block_size(sd.bdev)); | 1066 | sb_set_blocksize(s, block_size(sd.bdev)); |
1097 | 1067 | ||
1098 | err = nilfs_fill_super(s, data, flags & MS_VERBOSE, nilfs); | 1068 | err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0, |
1069 | nilfs); | ||
1099 | if (err) | 1070 | if (err) |
1100 | goto cancel_new; | 1071 | goto cancel_new; |
1101 | 1072 | ||
@@ -1106,7 +1077,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1106 | mutex_unlock(&nilfs->ns_mount_mutex); | 1077 | mutex_unlock(&nilfs->ns_mount_mutex); |
1107 | put_nilfs(nilfs); | 1078 | put_nilfs(nilfs); |
1108 | if (need_to_close) | 1079 | if (need_to_close) |
1109 | close_bdev_exclusive(sd.bdev, flags); | 1080 | close_bdev_exclusive(sd.bdev, mode); |
1110 | simple_set_mnt(mnt, s); | 1081 | simple_set_mnt(mnt, s); |
1111 | return 0; | 1082 | return 0; |
1112 | 1083 | ||
@@ -1114,7 +1085,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1114 | mutex_unlock(&nilfs->ns_mount_mutex); | 1085 | mutex_unlock(&nilfs->ns_mount_mutex); |
1115 | put_nilfs(nilfs); | 1086 | put_nilfs(nilfs); |
1116 | failed: | 1087 | failed: |
1117 | close_bdev_exclusive(sd.bdev, flags); | 1088 | close_bdev_exclusive(sd.bdev, mode); |
1118 | 1089 | ||
1119 | return err; | 1090 | return err; |
1120 | 1091 | ||
@@ -1124,7 +1095,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1124 | put_nilfs(nilfs); | 1095 | put_nilfs(nilfs); |
1125 | deactivate_locked_super(s); | 1096 | deactivate_locked_super(s); |
1126 | /* | 1097 | /* |
1127 | * deactivate_super() invokes close_bdev_exclusive(). | 1098 | * deactivate_locked_super() invokes close_bdev_exclusive(). |
1128 | * We must finish all post-cleaning before this call; | 1099 | * We must finish all post-cleaning before this call; |
1129 | * put_nilfs() needs the block device. | 1100 | * put_nilfs() needs the block device. |
1130 | */ | 1101 | */ |
@@ -1139,54 +1110,93 @@ struct file_system_type nilfs_fs_type = { | |||
1139 | .fs_flags = FS_REQUIRES_DEV, | 1110 | .fs_flags = FS_REQUIRES_DEV, |
1140 | }; | 1111 | }; |
1141 | 1112 | ||
1142 | static int __init init_nilfs_fs(void) | 1113 | static void nilfs_inode_init_once(void *obj) |
1143 | { | 1114 | { |
1144 | int err; | 1115 | struct nilfs_inode_info *ii = obj; |
1145 | |||
1146 | err = nilfs_init_inode_cache(); | ||
1147 | if (err) | ||
1148 | goto failed; | ||
1149 | 1116 | ||
1150 | err = nilfs_init_transaction_cache(); | 1117 | INIT_LIST_HEAD(&ii->i_dirty); |
1151 | if (err) | 1118 | #ifdef CONFIG_NILFS_XATTR |
1152 | goto failed_inode_cache; | 1119 | init_rwsem(&ii->xattr_sem); |
1120 | #endif | ||
1121 | nilfs_btnode_cache_init_once(&ii->i_btnode_cache); | ||
1122 | ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union; | ||
1123 | inode_init_once(&ii->vfs_inode); | ||
1124 | } | ||
1153 | 1125 | ||
1154 | err = nilfs_init_segbuf_cache(); | 1126 | static void nilfs_segbuf_init_once(void *obj) |
1155 | if (err) | 1127 | { |
1156 | goto failed_transaction_cache; | 1128 | memset(obj, 0, sizeof(struct nilfs_segment_buffer)); |
1129 | } | ||
1157 | 1130 | ||
1158 | err = nilfs_btree_path_cache_init(); | 1131 | static void nilfs_destroy_cachep(void) |
1159 | if (err) | 1132 | { |
1160 | goto failed_segbuf_cache; | 1133 | if (nilfs_inode_cachep) |
1134 | kmem_cache_destroy(nilfs_inode_cachep); | ||
1135 | if (nilfs_transaction_cachep) | ||
1136 | kmem_cache_destroy(nilfs_transaction_cachep); | ||
1137 | if (nilfs_segbuf_cachep) | ||
1138 | kmem_cache_destroy(nilfs_segbuf_cachep); | ||
1139 | if (nilfs_btree_path_cache) | ||
1140 | kmem_cache_destroy(nilfs_btree_path_cache); | ||
1141 | } | ||
1161 | 1142 | ||
1162 | err = register_filesystem(&nilfs_fs_type); | 1143 | static int __init nilfs_init_cachep(void) |
1163 | if (err) | 1144 | { |
1164 | goto failed_btree_path_cache; | 1145 | nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache", |
1146 | sizeof(struct nilfs_inode_info), 0, | ||
1147 | SLAB_RECLAIM_ACCOUNT, nilfs_inode_init_once); | ||
1148 | if (!nilfs_inode_cachep) | ||
1149 | goto fail; | ||
1150 | |||
1151 | nilfs_transaction_cachep = kmem_cache_create("nilfs2_transaction_cache", | ||
1152 | sizeof(struct nilfs_transaction_info), 0, | ||
1153 | SLAB_RECLAIM_ACCOUNT, NULL); | ||
1154 | if (!nilfs_transaction_cachep) | ||
1155 | goto fail; | ||
1156 | |||
1157 | nilfs_segbuf_cachep = kmem_cache_create("nilfs2_segbuf_cache", | ||
1158 | sizeof(struct nilfs_segment_buffer), 0, | ||
1159 | SLAB_RECLAIM_ACCOUNT, nilfs_segbuf_init_once); | ||
1160 | if (!nilfs_segbuf_cachep) | ||
1161 | goto fail; | ||
1162 | |||
1163 | nilfs_btree_path_cache = kmem_cache_create("nilfs2_btree_path_cache", | ||
1164 | sizeof(struct nilfs_btree_path) * NILFS_BTREE_LEVEL_MAX, | ||
1165 | 0, 0, NULL); | ||
1166 | if (!nilfs_btree_path_cache) | ||
1167 | goto fail; | ||
1165 | 1168 | ||
1166 | return 0; | 1169 | return 0; |
1167 | 1170 | ||
1168 | failed_btree_path_cache: | 1171 | fail: |
1169 | nilfs_btree_path_cache_destroy(); | 1172 | nilfs_destroy_cachep(); |
1173 | return -ENOMEM; | ||
1174 | } | ||
1175 | |||
1176 | static int __init init_nilfs_fs(void) | ||
1177 | { | ||
1178 | int err; | ||
1170 | 1179 | ||
1171 | failed_segbuf_cache: | 1180 | err = nilfs_init_cachep(); |
1172 | nilfs_destroy_segbuf_cache(); | 1181 | if (err) |
1182 | goto fail; | ||
1173 | 1183 | ||
1174 | failed_transaction_cache: | 1184 | err = register_filesystem(&nilfs_fs_type); |
1175 | nilfs_destroy_transaction_cache(); | 1185 | if (err) |
1186 | goto free_cachep; | ||
1176 | 1187 | ||
1177 | failed_inode_cache: | 1188 | printk(KERN_INFO "NILFS version 2 loaded\n"); |
1178 | nilfs_destroy_inode_cache(); | 1189 | return 0; |
1179 | 1190 | ||
1180 | failed: | 1191 | free_cachep: |
1192 | nilfs_destroy_cachep(); | ||
1193 | fail: | ||
1181 | return err; | 1194 | return err; |
1182 | } | 1195 | } |
1183 | 1196 | ||
1184 | static void __exit exit_nilfs_fs(void) | 1197 | static void __exit exit_nilfs_fs(void) |
1185 | { | 1198 | { |
1186 | nilfs_destroy_segbuf_cache(); | 1199 | nilfs_destroy_cachep(); |
1187 | nilfs_destroy_transaction_cache(); | ||
1188 | nilfs_destroy_inode_cache(); | ||
1189 | nilfs_btree_path_cache_destroy(); | ||
1190 | unregister_filesystem(&nilfs_fs_type); | 1200 | unregister_filesystem(&nilfs_fs_type); |
1191 | } | 1201 | } |
1192 | 1202 | ||