diff options
-rw-r--r-- | fs/ufs/ialloc.c | 116 | ||||
-rw-r--r-- | fs/ufs/inode.c | 111 | ||||
-rw-r--r-- | fs/ufs/super.c | 36 | ||||
-rw-r--r-- | include/linux/ufs_fs.h | 4 | ||||
-rw-r--r-- | include/linux/ufs_fs_i.h | 1 |
5 files changed, 208 insertions, 60 deletions
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 2ad1259c6eca..b868878009b6 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -18,6 +18,9 @@ | |||
18 | * Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 | 18 | * Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 |
19 | * Big-endian to little-endian byte-swapping/bitmaps by | 19 | * Big-endian to little-endian byte-swapping/bitmaps by |
20 | * David S. Miller (davem@caip.rutgers.edu), 1995 | 20 | * David S. Miller (davem@caip.rutgers.edu), 1995 |
21 | * | ||
22 | * UFS2 write support added by | ||
23 | * Evgeniy Dushistov <dushistov@mail.ru>, 2007 | ||
21 | */ | 24 | */ |
22 | 25 | ||
23 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
@@ -126,6 +129,47 @@ void ufs_free_inode (struct inode * inode) | |||
126 | } | 129 | } |
127 | 130 | ||
128 | /* | 131 | /* |
132 | * Nullify new chunk of inodes, | ||
133 | * BSD people also set ui_gen field of inode | ||
134 | * during nullification, but we not care about | ||
135 | * that because of linux ufs do not support NFS | ||
136 | */ | ||
137 | static void ufs2_init_inodes_chunk(struct super_block *sb, | ||
138 | struct ufs_cg_private_info *ucpi, | ||
139 | struct ufs_cylinder_group *ucg) | ||
140 | { | ||
141 | struct buffer_head *bh; | ||
142 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | ||
143 | sector_t beg = uspi->s_sbbase + | ||
144 | ufs_inotofsba(ucpi->c_cgx * uspi->s_ipg + | ||
145 | fs32_to_cpu(sb, ucg->cg_u.cg_u2.cg_initediblk)); | ||
146 | sector_t end = beg + uspi->s_fpb; | ||
147 | |||
148 | UFSD("ENTER cgno %d\n", ucpi->c_cgx); | ||
149 | |||
150 | for (; beg < end; ++beg) { | ||
151 | bh = sb_getblk(sb, beg); | ||
152 | lock_buffer(bh); | ||
153 | memset(bh->b_data, 0, sb->s_blocksize); | ||
154 | set_buffer_uptodate(bh); | ||
155 | mark_buffer_dirty(bh); | ||
156 | unlock_buffer(bh); | ||
157 | if (sb->s_flags & MS_SYNCHRONOUS) | ||
158 | sync_dirty_buffer(bh); | ||
159 | brelse(bh); | ||
160 | } | ||
161 | |||
162 | fs32_add(sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb); | ||
163 | ubh_mark_buffer_dirty(UCPI_UBH(ucpi)); | ||
164 | if (sb->s_flags & MS_SYNCHRONOUS) { | ||
165 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | ||
166 | ubh_wait_on_buffer(UCPI_UBH(ucpi)); | ||
167 | } | ||
168 | |||
169 | UFSD("EXIT\n"); | ||
170 | } | ||
171 | |||
172 | /* | ||
129 | * There are two policies for allocating an inode. If the new inode is | 173 | * There are two policies for allocating an inode. If the new inode is |
130 | * a directory, then a forward search is made for a block group with both | 174 | * a directory, then a forward search is made for a block group with both |
131 | * free space and a low directory-to-inode ratio; if that fails, then of | 175 | * free space and a low directory-to-inode ratio; if that fails, then of |
@@ -146,6 +190,7 @@ struct inode * ufs_new_inode(struct inode * dir, int mode) | |||
146 | struct inode * inode; | 190 | struct inode * inode; |
147 | unsigned cg, bit, i, j, start; | 191 | unsigned cg, bit, i, j, start; |
148 | struct ufs_inode_info *ufsi; | 192 | struct ufs_inode_info *ufsi; |
193 | int err = -ENOSPC; | ||
149 | 194 | ||
150 | UFSD("ENTER\n"); | 195 | UFSD("ENTER\n"); |
151 | 196 | ||
@@ -198,13 +243,15 @@ struct inode * ufs_new_inode(struct inode * dir, int mode) | |||
198 | goto cg_found; | 243 | goto cg_found; |
199 | } | 244 | } |
200 | } | 245 | } |
201 | 246 | ||
202 | goto failed; | 247 | goto failed; |
203 | 248 | ||
204 | cg_found: | 249 | cg_found: |
205 | ucpi = ufs_load_cylinder (sb, cg); | 250 | ucpi = ufs_load_cylinder (sb, cg); |
206 | if (!ucpi) | 251 | if (!ucpi) { |
252 | err = -EIO; | ||
207 | goto failed; | 253 | goto failed; |
254 | } | ||
208 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); | 255 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
209 | if (!ufs_cg_chkmagic(sb, ucg)) | 256 | if (!ufs_cg_chkmagic(sb, ucg)) |
210 | ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number"); | 257 | ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number"); |
@@ -216,6 +263,7 @@ cg_found: | |||
216 | if (!(bit < start)) { | 263 | if (!(bit < start)) { |
217 | ufs_error (sb, "ufs_new_inode", | 264 | ufs_error (sb, "ufs_new_inode", |
218 | "cylinder group %u corrupted - error in inode bitmap\n", cg); | 265 | "cylinder group %u corrupted - error in inode bitmap\n", cg); |
266 | err = -EIO; | ||
219 | goto failed; | 267 | goto failed; |
220 | } | 268 | } |
221 | } | 269 | } |
@@ -224,9 +272,18 @@ cg_found: | |||
224 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit); | 272 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit); |
225 | else { | 273 | else { |
226 | ufs_panic (sb, "ufs_new_inode", "internal error"); | 274 | ufs_panic (sb, "ufs_new_inode", "internal error"); |
275 | err = -EIO; | ||
227 | goto failed; | 276 | goto failed; |
228 | } | 277 | } |
229 | 278 | ||
279 | if (uspi->fs_magic == UFS2_MAGIC) { | ||
280 | u32 initediblk = fs32_to_cpu(sb, ucg->cg_u.cg_u2.cg_initediblk); | ||
281 | |||
282 | if (bit + uspi->s_inopb > initediblk && | ||
283 | initediblk < fs32_to_cpu(sb, ucg->cg_u.cg_u2.cg_niblk)) | ||
284 | ufs2_init_inodes_chunk(sb, ucpi, ucg); | ||
285 | } | ||
286 | |||
230 | fs32_sub(sb, &ucg->cg_cs.cs_nifree, 1); | 287 | fs32_sub(sb, &ucg->cg_cs.cs_nifree, 1); |
231 | uspi->cs_total.cs_nifree--; | 288 | uspi->cs_total.cs_nifree--; |
232 | fs32_sub(sb, &sbi->fs_cs(cg).cs_nifree, 1); | 289 | fs32_sub(sb, &sbi->fs_cs(cg).cs_nifree, 1); |
@@ -236,7 +293,6 @@ cg_found: | |||
236 | uspi->cs_total.cs_ndir++; | 293 | uspi->cs_total.cs_ndir++; |
237 | fs32_add(sb, &sbi->fs_cs(cg).cs_ndir, 1); | 294 | fs32_add(sb, &sbi->fs_cs(cg).cs_ndir, 1); |
238 | } | 295 | } |
239 | |||
240 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 296 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
241 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 297 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
242 | if (sb->s_flags & MS_SYNCHRONOUS) { | 298 | if (sb->s_flags & MS_SYNCHRONOUS) { |
@@ -245,6 +301,7 @@ cg_found: | |||
245 | } | 301 | } |
246 | sb->s_dirt = 1; | 302 | sb->s_dirt = 1; |
247 | 303 | ||
304 | inode->i_ino = cg * uspi->s_ipg + bit; | ||
248 | inode->i_mode = mode; | 305 | inode->i_mode = mode; |
249 | inode->i_uid = current->fsuid; | 306 | inode->i_uid = current->fsuid; |
250 | if (dir->i_mode & S_ISGID) { | 307 | if (dir->i_mode & S_ISGID) { |
@@ -254,39 +311,72 @@ cg_found: | |||
254 | } else | 311 | } else |
255 | inode->i_gid = current->fsgid; | 312 | inode->i_gid = current->fsgid; |
256 | 313 | ||
257 | inode->i_ino = cg * uspi->s_ipg + bit; | ||
258 | inode->i_blocks = 0; | 314 | inode->i_blocks = 0; |
315 | inode->i_generation = 0; | ||
259 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 316 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
260 | ufsi->i_flags = UFS_I(dir)->i_flags; | 317 | ufsi->i_flags = UFS_I(dir)->i_flags; |
261 | ufsi->i_lastfrag = 0; | 318 | ufsi->i_lastfrag = 0; |
262 | ufsi->i_gen = 0; | ||
263 | ufsi->i_shadow = 0; | 319 | ufsi->i_shadow = 0; |
264 | ufsi->i_osync = 0; | 320 | ufsi->i_osync = 0; |
265 | ufsi->i_oeftflag = 0; | 321 | ufsi->i_oeftflag = 0; |
266 | ufsi->i_dir_start_lookup = 0; | 322 | ufsi->i_dir_start_lookup = 0; |
267 | memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); | 323 | memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); |
268 | |||
269 | insert_inode_hash(inode); | 324 | insert_inode_hash(inode); |
270 | mark_inode_dirty(inode); | 325 | mark_inode_dirty(inode); |
271 | 326 | ||
327 | if (uspi->fs_magic == UFS2_MAGIC) { | ||
328 | struct buffer_head *bh; | ||
329 | struct ufs2_inode *ufs2_inode; | ||
330 | |||
331 | /* | ||
332 | * setup birth date, we do it here because of there is no sense | ||
333 | * to hold it in struct ufs_inode_info, and lose 64 bit | ||
334 | */ | ||
335 | bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino)); | ||
336 | if (!bh) { | ||
337 | ufs_warning(sb, "ufs_read_inode", | ||
338 | "unable to read inode %lu\n", | ||
339 | inode->i_ino); | ||
340 | err = -EIO; | ||
341 | goto fail_remove_inode; | ||
342 | } | ||
343 | lock_buffer(bh); | ||
344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; | ||
345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); | ||
346 | ufs2_inode->ui_birthtime.tv_sec = | ||
347 | cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec); | ||
348 | ufs2_inode->ui_birthtime.tv_usec = 0; | ||
349 | mark_buffer_dirty(bh); | ||
350 | unlock_buffer(bh); | ||
351 | if (sb->s_flags & MS_SYNCHRONOUS) | ||
352 | sync_dirty_buffer(bh); | ||
353 | brelse(bh); | ||
354 | } | ||
355 | |||
272 | unlock_super (sb); | 356 | unlock_super (sb); |
273 | 357 | ||
274 | if (DQUOT_ALLOC_INODE(inode)) { | 358 | if (DQUOT_ALLOC_INODE(inode)) { |
275 | DQUOT_DROP(inode); | 359 | DQUOT_DROP(inode); |
276 | inode->i_flags |= S_NOQUOTA; | 360 | err = -EDQUOT; |
277 | inode->i_nlink = 0; | 361 | goto fail_without_unlock; |
278 | iput(inode); | ||
279 | return ERR_PTR(-EDQUOT); | ||
280 | } | 362 | } |
281 | 363 | ||
282 | UFSD("allocating inode %lu\n", inode->i_ino); | 364 | UFSD("allocating inode %lu\n", inode->i_ino); |
283 | UFSD("EXIT\n"); | 365 | UFSD("EXIT\n"); |
284 | return inode; | 366 | return inode; |
285 | 367 | ||
368 | fail_remove_inode: | ||
369 | unlock_super(sb); | ||
370 | fail_without_unlock: | ||
371 | inode->i_flags |= S_NOQUOTA; | ||
372 | inode->i_nlink = 0; | ||
373 | iput(inode); | ||
374 | UFSD("EXIT (FAILED): err %d\n", err); | ||
375 | return ERR_PTR(err); | ||
286 | failed: | 376 | failed: |
287 | unlock_super (sb); | 377 | unlock_super (sb); |
288 | make_bad_inode(inode); | 378 | make_bad_inode(inode); |
289 | iput (inode); | 379 | iput (inode); |
290 | UFSD("EXIT (FAILED)\n"); | 380 | UFSD("EXIT (FAILED): err %d\n", err); |
291 | return ERR_PTR(-ENOSPC); | 381 | return ERR_PTR(err); |
292 | } | 382 | } |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 4295ca91cf85..dd52eecdcb0f 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -616,8 +616,8 @@ static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) | |||
616 | inode->i_atime.tv_nsec = 0; | 616 | inode->i_atime.tv_nsec = 0; |
617 | inode->i_ctime.tv_nsec = 0; | 617 | inode->i_ctime.tv_nsec = 0; |
618 | inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks); | 618 | inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks); |
619 | inode->i_generation = fs32_to_cpu(sb, ufs_inode->ui_gen); | ||
619 | ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags); | 620 | ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags); |
620 | ufsi->i_gen = fs32_to_cpu(sb, ufs_inode->ui_gen); | ||
621 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); | 621 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); |
622 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); | 622 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); |
623 | 623 | ||
@@ -661,8 +661,8 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) | |||
661 | inode->i_atime.tv_nsec = 0; | 661 | inode->i_atime.tv_nsec = 0; |
662 | inode->i_ctime.tv_nsec = 0; | 662 | inode->i_ctime.tv_nsec = 0; |
663 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); | 663 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
664 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); | ||
664 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); | 665 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
665 | ufsi->i_gen = fs32_to_cpu(sb, ufs2_inode->ui_gen); | ||
666 | /* | 666 | /* |
667 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); | 667 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); |
668 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); | 668 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); |
@@ -731,34 +731,11 @@ bad_inode: | |||
731 | make_bad_inode(inode); | 731 | make_bad_inode(inode); |
732 | } | 732 | } |
733 | 733 | ||
734 | static int ufs_update_inode(struct inode * inode, int do_sync) | 734 | static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) |
735 | { | 735 | { |
736 | struct ufs_inode_info *ufsi = UFS_I(inode); | 736 | struct super_block *sb = inode->i_sb; |
737 | struct super_block * sb; | 737 | struct ufs_inode_info *ufsi = UFS_I(inode); |
738 | struct ufs_sb_private_info * uspi; | 738 | unsigned i; |
739 | struct buffer_head * bh; | ||
740 | struct ufs_inode * ufs_inode; | ||
741 | unsigned i; | ||
742 | unsigned flags; | ||
743 | |||
744 | UFSD("ENTER, ino %lu\n", inode->i_ino); | ||
745 | |||
746 | sb = inode->i_sb; | ||
747 | uspi = UFS_SB(sb)->s_uspi; | ||
748 | flags = UFS_SB(sb)->s_flags; | ||
749 | |||
750 | if (inode->i_ino < UFS_ROOTINO || | ||
751 | inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) { | ||
752 | ufs_warning (sb, "ufs_read_inode", "bad inode number (%lu)\n", inode->i_ino); | ||
753 | return -1; | ||
754 | } | ||
755 | |||
756 | bh = sb_bread(sb, ufs_inotofsba(inode->i_ino)); | ||
757 | if (!bh) { | ||
758 | ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino); | ||
759 | return -1; | ||
760 | } | ||
761 | ufs_inode = (struct ufs_inode *) (bh->b_data + ufs_inotofsbo(inode->i_ino) * sizeof(struct ufs_inode)); | ||
762 | 739 | ||
763 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); | 740 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); |
764 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); | 741 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); |
@@ -775,9 +752,9 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
775 | ufs_inode->ui_mtime.tv_usec = 0; | 752 | ufs_inode->ui_mtime.tv_usec = 0; |
776 | ufs_inode->ui_blocks = cpu_to_fs32(sb, inode->i_blocks); | 753 | ufs_inode->ui_blocks = cpu_to_fs32(sb, inode->i_blocks); |
777 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); | 754 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); |
778 | ufs_inode->ui_gen = cpu_to_fs32(sb, ufsi->i_gen); | 755 | ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation); |
779 | 756 | ||
780 | if ((flags & UFS_UID_MASK) == UFS_UID_EFT) { | 757 | if ((UFS_SB(sb)->s_flags & UFS_UID_MASK) == UFS_UID_EFT) { |
781 | ufs_inode->ui_u3.ui_sun.ui_shadow = cpu_to_fs32(sb, ufsi->i_shadow); | 758 | ufs_inode->ui_u3.ui_sun.ui_shadow = cpu_to_fs32(sb, ufsi->i_shadow); |
782 | ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, ufsi->i_oeftflag); | 759 | ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, ufsi->i_oeftflag); |
783 | } | 760 | } |
@@ -796,6 +773,78 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
796 | 773 | ||
797 | if (!inode->i_nlink) | 774 | if (!inode->i_nlink) |
798 | memset (ufs_inode, 0, sizeof(struct ufs_inode)); | 775 | memset (ufs_inode, 0, sizeof(struct ufs_inode)); |
776 | } | ||
777 | |||
778 | static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) | ||
779 | { | ||
780 | struct super_block *sb = inode->i_sb; | ||
781 | struct ufs_inode_info *ufsi = UFS_I(inode); | ||
782 | unsigned i; | ||
783 | |||
784 | UFSD("ENTER\n"); | ||
785 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); | ||
786 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); | ||
787 | |||
788 | ufs_inode->ui_uid = cpu_to_fs32(sb, inode->i_uid); | ||
789 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); | ||
790 | |||
791 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | ||
792 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); | ||
793 | ufs_inode->ui_atime.tv_usec = 0; | ||
794 | ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec); | ||
795 | ufs_inode->ui_ctime.tv_usec = 0; | ||
796 | ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec); | ||
797 | ufs_inode->ui_mtime.tv_usec = 0; | ||
798 | |||
799 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); | ||
800 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); | ||
801 | ufs_inode->ui_gen = cpu_to_fs32(sb, inode->i_generation); | ||
802 | |||
803 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { | ||
804 | /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */ | ||
805 | ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.u2_i_data[0]; | ||
806 | } else if (inode->i_blocks) { | ||
807 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) | ||
808 | ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.u2_i_data[i]; | ||
809 | } else { | ||
810 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) | ||
811 | ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i]; | ||
812 | } | ||
813 | |||
814 | if (!inode->i_nlink) | ||
815 | memset (ufs_inode, 0, sizeof(struct ufs2_inode)); | ||
816 | UFSD("EXIT\n"); | ||
817 | } | ||
818 | |||
819 | static int ufs_update_inode(struct inode * inode, int do_sync) | ||
820 | { | ||
821 | struct super_block *sb = inode->i_sb; | ||
822 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | ||
823 | struct buffer_head * bh; | ||
824 | |||
825 | UFSD("ENTER, ino %lu\n", inode->i_ino); | ||
826 | |||
827 | if (inode->i_ino < UFS_ROOTINO || | ||
828 | inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) { | ||
829 | ufs_warning (sb, "ufs_read_inode", "bad inode number (%lu)\n", inode->i_ino); | ||
830 | return -1; | ||
831 | } | ||
832 | |||
833 | bh = sb_bread(sb, ufs_inotofsba(inode->i_ino)); | ||
834 | if (!bh) { | ||
835 | ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino); | ||
836 | return -1; | ||
837 | } | ||
838 | if (uspi->fs_magic == UFS2_MAGIC) { | ||
839 | struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data; | ||
840 | |||
841 | ufs2_update_inode(inode, | ||
842 | ufs2_inode + ufs_inotofsbo(inode->i_ino)); | ||
843 | } else { | ||
844 | struct ufs_inode *ufs_inode = (struct ufs_inode *) bh->b_data; | ||
845 | |||
846 | ufs1_update_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino)); | ||
847 | } | ||
799 | 848 | ||
800 | mark_buffer_dirty(bh); | 849 | mark_buffer_dirty(bh); |
801 | if (do_sync) | 850 | if (do_sync) |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 1427e44bfd2a..cf74548aa85a 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -95,14 +95,16 @@ | |||
95 | /* | 95 | /* |
96 | * Print contents of ufs_super_block, useful for debugging | 96 | * Print contents of ufs_super_block, useful for debugging |
97 | */ | 97 | */ |
98 | static void ufs_print_super_stuff(struct super_block *sb, unsigned flags, | 98 | static void ufs_print_super_stuff(struct super_block *sb, |
99 | struct ufs_super_block_first *usb1, | 99 | struct ufs_super_block_first *usb1, |
100 | struct ufs_super_block_second *usb2, | 100 | struct ufs_super_block_second *usb2, |
101 | struct ufs_super_block_third *usb3) | 101 | struct ufs_super_block_third *usb3) |
102 | { | 102 | { |
103 | u32 magic = fs32_to_cpu(sb, usb3->fs_magic); | ||
104 | |||
103 | printk("ufs_print_super_stuff\n"); | 105 | printk("ufs_print_super_stuff\n"); |
104 | printk(" magic: 0x%x\n", fs32_to_cpu(sb, usb3->fs_magic)); | 106 | printk(" magic: 0x%x\n", magic); |
105 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { | 107 | if (fs32_to_cpu(sb, usb3->fs_magic) == UFS2_MAGIC) { |
106 | printk(" fs_size: %llu\n", (unsigned long long) | 108 | printk(" fs_size: %llu\n", (unsigned long long) |
107 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size)); | 109 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size)); |
108 | printk(" fs_dsize: %llu\n", (unsigned long long) | 110 | printk(" fs_dsize: %llu\n", (unsigned long long) |
@@ -119,6 +121,12 @@ static void ufs_print_super_stuff(struct super_block *sb, unsigned flags, | |||
119 | printk(" cs_nbfree(No of free blocks): %llu\n", | 121 | printk(" cs_nbfree(No of free blocks): %llu\n", |
120 | (unsigned long long) | 122 | (unsigned long long) |
121 | fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree)); | 123 | fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree)); |
124 | printk(KERN_INFO" cs_nifree(Num of free inodes): %llu\n", | ||
125 | (unsigned long long) | ||
126 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree)); | ||
127 | printk(KERN_INFO" cs_nffree(Num of free frags): %llu\n", | ||
128 | (unsigned long long) | ||
129 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree)); | ||
122 | } else { | 130 | } else { |
123 | printk(" sblkno: %u\n", fs32_to_cpu(sb, usb1->fs_sblkno)); | 131 | printk(" sblkno: %u\n", fs32_to_cpu(sb, usb1->fs_sblkno)); |
124 | printk(" cblkno: %u\n", fs32_to_cpu(sb, usb1->fs_cblkno)); | 132 | printk(" cblkno: %u\n", fs32_to_cpu(sb, usb1->fs_cblkno)); |
@@ -201,7 +209,7 @@ static void ufs_print_cylinder_stuff(struct super_block *sb, | |||
201 | printk("\n"); | 209 | printk("\n"); |
202 | } | 210 | } |
203 | #else | 211 | #else |
204 | # define ufs_print_super_stuff(sb, flags, usb1, usb2, usb3) /**/ | 212 | # define ufs_print_super_stuff(sb, usb1, usb2, usb3) /**/ |
205 | # define ufs_print_cylinder_stuff(sb, cg) /**/ | 213 | # define ufs_print_cylinder_stuff(sb, cg) /**/ |
206 | #endif /* CONFIG_UFS_DEBUG */ | 214 | #endif /* CONFIG_UFS_DEBUG */ |
207 | 215 | ||
@@ -424,7 +432,6 @@ static int ufs_read_cylinder_structures(struct super_block *sb) | |||
424 | { | 432 | { |
425 | struct ufs_sb_info *sbi = UFS_SB(sb); | 433 | struct ufs_sb_info *sbi = UFS_SB(sb); |
426 | struct ufs_sb_private_info *uspi = sbi->s_uspi; | 434 | struct ufs_sb_private_info *uspi = sbi->s_uspi; |
427 | unsigned flags = sbi->s_flags; | ||
428 | struct ufs_buffer_head * ubh; | 435 | struct ufs_buffer_head * ubh; |
429 | unsigned char * base, * space; | 436 | unsigned char * base, * space; |
430 | unsigned size, blks, i; | 437 | unsigned size, blks, i; |
@@ -448,11 +455,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) | |||
448 | if (i + uspi->s_fpb > blks) | 455 | if (i + uspi->s_fpb > blks) |
449 | size = (blks - i) * uspi->s_fsize; | 456 | size = (blks - i) * uspi->s_fsize; |
450 | 457 | ||
451 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 458 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); |
452 | ubh = ubh_bread(sb, | ||
453 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_csaddr) + i, size); | ||
454 | else | ||
455 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); | ||
456 | 459 | ||
457 | if (!ubh) | 460 | if (!ubh) |
458 | goto failed; | 461 | goto failed; |
@@ -547,6 +550,7 @@ static void ufs_put_cstotal(struct super_block *sb) | |||
547 | cpu_to_fs32(sb, uspi->cs_total.cs_nffree); | 550 | cpu_to_fs32(sb, uspi->cs_total.cs_nffree); |
548 | } | 551 | } |
549 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); | 552 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); |
553 | ufs_print_super_stuff(sb, usb1, usb2, usb3); | ||
550 | UFSD("EXIT\n"); | 554 | UFSD("EXIT\n"); |
551 | } | 555 | } |
552 | 556 | ||
@@ -574,7 +578,9 @@ static void ufs_put_super_internal(struct super_block *sb) | |||
574 | size = uspi->s_bsize; | 578 | size = uspi->s_bsize; |
575 | if (i + uspi->s_fpb > blks) | 579 | if (i + uspi->s_fpb > blks) |
576 | size = (blks - i) * uspi->s_fsize; | 580 | size = (blks - i) * uspi->s_fsize; |
581 | |||
577 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); | 582 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); |
583 | |||
578 | ubh_memcpyubh (ubh, space, size); | 584 | ubh_memcpyubh (ubh, space, size); |
579 | space += size; | 585 | space += size; |
580 | ubh_mark_buffer_uptodate (ubh, 1); | 586 | ubh_mark_buffer_uptodate (ubh, 1); |
@@ -888,7 +894,7 @@ magic_found: | |||
888 | } | 894 | } |
889 | 895 | ||
890 | 896 | ||
891 | ufs_print_super_stuff(sb, flags, usb1, usb2, usb3); | 897 | ufs_print_super_stuff(sb, usb1, usb2, usb3); |
892 | 898 | ||
893 | /* | 899 | /* |
894 | * Check, if file system was correctly unmounted. | 900 | * Check, if file system was correctly unmounted. |
@@ -971,7 +977,12 @@ magic_found: | |||
971 | uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3); | 977 | uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3); |
972 | uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave); | 978 | uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave); |
973 | uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew); | 979 | uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew); |
974 | uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr); | 980 | |
981 | if (uspi->fs_magic == UFS2_MAGIC) | ||
982 | uspi->s_csaddr = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_csaddr); | ||
983 | else | ||
984 | uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr); | ||
985 | |||
975 | uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize); | 986 | uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize); |
976 | uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize); | 987 | uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize); |
977 | uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak); | 988 | uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak); |
@@ -1058,7 +1069,6 @@ static void ufs_write_super(struct super_block *sb) | |||
1058 | unsigned flags; | 1069 | unsigned flags; |
1059 | 1070 | ||
1060 | lock_kernel(); | 1071 | lock_kernel(); |
1061 | |||
1062 | UFSD("ENTER\n"); | 1072 | UFSD("ENTER\n"); |
1063 | flags = UFS_SB(sb)->s_flags; | 1073 | flags = UFS_SB(sb)->s_flags; |
1064 | uspi = UFS_SB(sb)->s_uspi; | 1074 | uspi = UFS_SB(sb)->s_uspi; |
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index 5014604d0a50..24ce39820560 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h | |||
@@ -263,7 +263,7 @@ typedef __u16 __bitwise __fs16; | |||
263 | */ | 263 | */ |
264 | #define ufs_inotocg(x) ((x) / uspi->s_ipg) | 264 | #define ufs_inotocg(x) ((x) / uspi->s_ipg) |
265 | #define ufs_inotocgoff(x) ((x) % uspi->s_ipg) | 265 | #define ufs_inotocgoff(x) ((x) % uspi->s_ipg) |
266 | #define ufs_inotofsba(x) (ufs_cgimin(ufs_inotocg(x)) + ufs_inotocgoff(x) / uspi->s_inopf) | 266 | #define ufs_inotofsba(x) (((u64)ufs_cgimin(ufs_inotocg(x))) + ufs_inotocgoff(x) / uspi->s_inopf) |
267 | #define ufs_inotofsbo(x) ((x) % uspi->s_inopf) | 267 | #define ufs_inotofsbo(x) ((x) % uspi->s_inopf) |
268 | 268 | ||
269 | /* | 269 | /* |
@@ -756,7 +756,7 @@ struct ufs_sb_private_info { | |||
756 | __u32 s_npsect; /* # sectors/track including spares */ | 756 | __u32 s_npsect; /* # sectors/track including spares */ |
757 | __u32 s_interleave; /* hardware sector interleave */ | 757 | __u32 s_interleave; /* hardware sector interleave */ |
758 | __u32 s_trackskew; /* sector 0 skew, per track */ | 758 | __u32 s_trackskew; /* sector 0 skew, per track */ |
759 | __u32 s_csaddr; /* blk addr of cyl grp summary area */ | 759 | __u64 s_csaddr; /* blk addr of cyl grp summary area */ |
760 | __u32 s_cssize; /* size of cyl grp summary area */ | 760 | __u32 s_cssize; /* size of cyl grp summary area */ |
761 | __u32 s_cgsize; /* cylinder group size */ | 761 | __u32 s_cgsize; /* cylinder group size */ |
762 | __u32 s_ntrak; /* tracks per cylinder */ | 762 | __u32 s_ntrak; /* tracks per cylinder */ |
diff --git a/include/linux/ufs_fs_i.h b/include/linux/ufs_fs_i.h index f50ce3b0cd52..fef77d52b029 100644 --- a/include/linux/ufs_fs_i.h +++ b/include/linux/ufs_fs_i.h | |||
@@ -20,7 +20,6 @@ struct ufs_inode_info { | |||
20 | __fs64 u2_i_data[15]; | 20 | __fs64 u2_i_data[15]; |
21 | } i_u1; | 21 | } i_u1; |
22 | __u32 i_flags; | 22 | __u32 i_flags; |
23 | __u32 i_gen; | ||
24 | __u32 i_shadow; | 23 | __u32 i_shadow; |
25 | __u32 i_unused1; | 24 | __u32 i_unused1; |
26 | __u32 i_unused2; | 25 | __u32 i_unused2; |