diff options
| -rw-r--r-- | fs/ufs/dir.c | 21 | ||||
| -rw-r--r-- | fs/ufs/super.c | 5 | ||||
| -rw-r--r-- | include/linux/ufs_fs.h | 1 |
3 files changed, 17 insertions, 10 deletions
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 433b6f68403a..a6c0ca9f48bf 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
| @@ -106,12 +106,13 @@ static void ufs_check_page(struct page *page) | |||
| 106 | char *kaddr = page_address(page); | 106 | char *kaddr = page_address(page); |
| 107 | unsigned offs, rec_len; | 107 | unsigned offs, rec_len; |
| 108 | unsigned limit = PAGE_CACHE_SIZE; | 108 | unsigned limit = PAGE_CACHE_SIZE; |
| 109 | const unsigned chunk_mask = UFS_SB(sb)->s_uspi->s_dirblksize - 1; | ||
| 109 | struct ufs_dir_entry *p; | 110 | struct ufs_dir_entry *p; |
| 110 | char *error; | 111 | char *error; |
| 111 | 112 | ||
| 112 | if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { | 113 | if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { |
| 113 | limit = dir->i_size & ~PAGE_CACHE_MASK; | 114 | limit = dir->i_size & ~PAGE_CACHE_MASK; |
| 114 | if (limit & (UFS_SECTOR_SIZE - 1)) | 115 | if (limit & chunk_mask) |
| 115 | goto Ebadsize; | 116 | goto Ebadsize; |
| 116 | if (!limit) | 117 | if (!limit) |
| 117 | goto out; | 118 | goto out; |
| @@ -126,7 +127,7 @@ static void ufs_check_page(struct page *page) | |||
| 126 | goto Ealign; | 127 | goto Ealign; |
| 127 | if (rec_len < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, p))) | 128 | if (rec_len < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, p))) |
| 128 | goto Enamelen; | 129 | goto Enamelen; |
| 129 | if (((offs + rec_len - 1) ^ offs) & ~(UFS_SECTOR_SIZE-1)) | 130 | if (((offs + rec_len - 1) ^ offs) & ~chunk_mask) |
| 130 | goto Espan; | 131 | goto Espan; |
| 131 | if (fs32_to_cpu(sb, p->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg * | 132 | if (fs32_to_cpu(sb, p->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg * |
| 132 | UFS_SB(sb)->s_uspi->s_ncg)) | 133 | UFS_SB(sb)->s_uspi->s_ncg)) |
| @@ -310,6 +311,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) | |||
| 310 | int namelen = dentry->d_name.len; | 311 | int namelen = dentry->d_name.len; |
| 311 | struct super_block *sb = dir->i_sb; | 312 | struct super_block *sb = dir->i_sb; |
| 312 | unsigned reclen = UFS_DIR_REC_LEN(namelen); | 313 | unsigned reclen = UFS_DIR_REC_LEN(namelen); |
| 314 | const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize; | ||
| 313 | unsigned short rec_len, name_len; | 315 | unsigned short rec_len, name_len; |
| 314 | struct page *page = NULL; | 316 | struct page *page = NULL; |
| 315 | struct ufs_dir_entry *de; | 317 | struct ufs_dir_entry *de; |
| @@ -342,8 +344,8 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) | |||
| 342 | if ((char *)de == dir_end) { | 344 | if ((char *)de == dir_end) { |
| 343 | /* We hit i_size */ | 345 | /* We hit i_size */ |
| 344 | name_len = 0; | 346 | name_len = 0; |
| 345 | rec_len = UFS_SECTOR_SIZE; | 347 | rec_len = chunk_size; |
| 346 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE); | 348 | de->d_reclen = cpu_to_fs16(sb, chunk_size); |
| 347 | de->d_ino = 0; | 349 | de->d_ino = 0; |
| 348 | goto got_it; | 350 | goto got_it; |
| 349 | } | 351 | } |
| @@ -431,7 +433,7 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 431 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | 433 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
| 432 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 434 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
| 433 | unsigned long npages = ufs_dir_pages(inode); | 435 | unsigned long npages = ufs_dir_pages(inode); |
| 434 | unsigned chunk_mask = ~(UFS_SECTOR_SIZE - 1); | 436 | unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); |
| 435 | int need_revalidate = filp->f_version != inode->i_version; | 437 | int need_revalidate = filp->f_version != inode->i_version; |
| 436 | unsigned flags = UFS_SB(sb)->s_flags; | 438 | unsigned flags = UFS_SB(sb)->s_flags; |
| 437 | 439 | ||
| @@ -511,7 +513,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, | |||
| 511 | struct super_block *sb = inode->i_sb; | 513 | struct super_block *sb = inode->i_sb; |
| 512 | struct address_space *mapping = page->mapping; | 514 | struct address_space *mapping = page->mapping; |
| 513 | char *kaddr = page_address(page); | 515 | char *kaddr = page_address(page); |
| 514 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SECTOR_SIZE - 1); | 516 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); |
| 515 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); | 517 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); |
| 516 | struct ufs_dir_entry *pde = NULL; | 518 | struct ufs_dir_entry *pde = NULL; |
| 517 | struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); | 519 | struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); |
| @@ -556,6 +558,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
| 556 | struct super_block * sb = dir->i_sb; | 558 | struct super_block * sb = dir->i_sb; |
| 557 | struct address_space *mapping = inode->i_mapping; | 559 | struct address_space *mapping = inode->i_mapping; |
| 558 | struct page *page = grab_cache_page(mapping, 0); | 560 | struct page *page = grab_cache_page(mapping, 0); |
| 561 | const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize; | ||
| 559 | struct ufs_dir_entry * de; | 562 | struct ufs_dir_entry * de; |
| 560 | char *base; | 563 | char *base; |
| 561 | int err; | 564 | int err; |
| @@ -563,7 +566,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
| 563 | if (!page) | 566 | if (!page) |
| 564 | return -ENOMEM; | 567 | return -ENOMEM; |
| 565 | kmap(page); | 568 | kmap(page); |
| 566 | err = mapping->a_ops->prepare_write(NULL, page, 0, UFS_SECTOR_SIZE); | 569 | err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); |
| 567 | if (err) { | 570 | if (err) { |
| 568 | unlock_page(page); | 571 | unlock_page(page); |
| 569 | goto fail; | 572 | goto fail; |
| @@ -584,11 +587,11 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
| 584 | ((char *)de + fs16_to_cpu(sb, de->d_reclen)); | 587 | ((char *)de + fs16_to_cpu(sb, de->d_reclen)); |
| 585 | de->d_ino = cpu_to_fs32(sb, dir->i_ino); | 588 | de->d_ino = cpu_to_fs32(sb, dir->i_ino); |
| 586 | ufs_set_de_type(sb, de, dir->i_mode); | 589 | ufs_set_de_type(sb, de, dir->i_mode); |
| 587 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1)); | 590 | de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1)); |
| 588 | ufs_set_de_namlen(sb, de, 2); | 591 | ufs_set_de_namlen(sb, de, 2); |
| 589 | strcpy (de->d_name, ".."); | 592 | strcpy (de->d_name, ".."); |
| 590 | 593 | ||
| 591 | err = ufs_commit_chunk(page, 0, UFS_SECTOR_SIZE); | 594 | err = ufs_commit_chunk(page, 0, chunk_size); |
| 592 | fail: | 595 | fail: |
| 593 | kunmap(page); | 596 | kunmap(page); |
| 594 | page_cache_release(page); | 597 | page_cache_release(page); |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 8a8e9382ec09..209be95e9d18 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
| @@ -649,7 +649,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 649 | kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL); | 649 | kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL); |
| 650 | if (!uspi) | 650 | if (!uspi) |
| 651 | goto failed; | 651 | goto failed; |
| 652 | 652 | uspi->s_dirblksize = UFS_SECTOR_SIZE; | |
| 653 | super_block_offset=UFS_SBLOCK; | 653 | super_block_offset=UFS_SBLOCK; |
| 654 | 654 | ||
| 655 | /* Keep 2Gig file limit. Some UFS variants need to override | 655 | /* Keep 2Gig file limit. Some UFS variants need to override |
| @@ -718,6 +718,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 718 | break; | 718 | break; |
| 719 | 719 | ||
| 720 | case UFS_MOUNT_UFSTYPE_NEXTSTEP: | 720 | case UFS_MOUNT_UFSTYPE_NEXTSTEP: |
| 721 | /*TODO: check may be we need set special dir block size?*/ | ||
| 721 | UFSD("ufstype=nextstep\n"); | 722 | UFSD("ufstype=nextstep\n"); |
| 722 | uspi->s_fsize = block_size = 1024; | 723 | uspi->s_fsize = block_size = 1024; |
| 723 | uspi->s_fmask = ~(1024 - 1); | 724 | uspi->s_fmask = ~(1024 - 1); |
| @@ -733,6 +734,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 733 | break; | 734 | break; |
| 734 | 735 | ||
| 735 | case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD: | 736 | case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD: |
| 737 | /*TODO: check may be we need set special dir block size?*/ | ||
| 736 | UFSD("ufstype=nextstep-cd\n"); | 738 | UFSD("ufstype=nextstep-cd\n"); |
| 737 | uspi->s_fsize = block_size = 2048; | 739 | uspi->s_fsize = block_size = 2048; |
| 738 | uspi->s_fmask = ~(2048 - 1); | 740 | uspi->s_fmask = ~(2048 - 1); |
| @@ -754,6 +756,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 754 | uspi->s_fshift = 10; | 756 | uspi->s_fshift = 10; |
| 755 | uspi->s_sbsize = super_block_size = 2048; | 757 | uspi->s_sbsize = super_block_size = 2048; |
| 756 | uspi->s_sbbase = 0; | 758 | uspi->s_sbbase = 0; |
| 759 | uspi->s_dirblksize = 1024; | ||
| 757 | flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; | 760 | flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; |
| 758 | if (!(sb->s_flags & MS_RDONLY)) { | 761 | if (!(sb->s_flags & MS_RDONLY)) { |
| 759 | if (!silent) | 762 | if (!silent) |
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index 28967eda9d7b..d3a4f994a5dc 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h | |||
| @@ -789,6 +789,7 @@ struct ufs_sb_private_info { | |||
| 789 | 789 | ||
| 790 | __u32 s_maxsymlinklen;/* upper limit on fast symlinks' size */ | 790 | __u32 s_maxsymlinklen;/* upper limit on fast symlinks' size */ |
| 791 | __s32 fs_magic; /* filesystem magic */ | 791 | __s32 fs_magic; /* filesystem magic */ |
| 792 | unsigned int s_dirblksize; | ||
| 792 | }; | 793 | }; |
| 793 | 794 | ||
| 794 | /* | 795 | /* |
