* [PATCH 1/6] fat: move fat_clusters_flush() to write_super()
@ 2005-11-07 17:32 OGAWA Hirofumi
2005-11-07 17:36 ` [PATCH] fat: use sb_find_get_block() instead of sb_getblk() OGAWA Hirofumi
0 siblings, 1 reply; 13+ messages in thread
From: OGAWA Hirofumi @ 2005-11-07 17:32 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
It is overkill to update the FS_INFO whenever modifying
prev_free/free_clusters, because those are just a hint.
So, this patch uses ->write_super() for updating FS_INFO instead.
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---
fs/fat/fatent.c | 8 ++++++--
fs/fat/inode.c | 10 ++++++++--
fs/fat/misc.c | 2 --
3 files changed, 14 insertions(+), 6 deletions(-)
diff -puN fs/fat/fatent.c~fat_write_super fs/fat/fatent.c
--- linux-2.6.14/fs/fat/fatent.c~fat_write_super 2005-11-07 02:14:05.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/fat/fatent.c 2005-11-07 03:46:35.000000000 +0900
@@ -476,6 +476,7 @@ int fat_alloc_clusters(struct inode *ino
sbi->prev_free = entry;
if (sbi->free_clusters != -1)
sbi->free_clusters--;
+ sb->s_dirt = 1;
cluster[idx_clus] = entry;
idx_clus++;
@@ -496,6 +497,7 @@ int fat_alloc_clusters(struct inode *ino
/* Couldn't allocate the free entries */
sbi->free_clusters = 0;
+ sb->s_dirt = 1;
err = -ENOSPC;
out:
@@ -509,7 +511,6 @@ out:
}
for (i = 0; i < nr_bhs; i++)
brelse(bhs[i]);
- fat_clusters_flush(sb);
if (err && idx_clus)
fat_free_clusters(inode, cluster[0]);
@@ -542,8 +543,10 @@ int fat_free_clusters(struct inode *inod
}
ops->ent_put(&fatent, FAT_ENT_FREE);
- if (sbi->free_clusters != -1)
+ if (sbi->free_clusters != -1) {
sbi->free_clusters++;
+ sb->s_dirt = 1;
+ }
if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -605,6 +608,7 @@ int fat_count_free_clusters(struct super
} while (fat_ent_next(sbi, &fatent));
}
sbi->free_clusters = free;
+ sb->s_dirt = 1;
fatent_brelse(&fatent);
out:
unlock_fat(sbi);
diff -puN fs/fat/inode.c~fat_write_super fs/fat/inode.c
--- linux-2.6.14/fs/fat/inode.c~fat_write_super 2005-11-07 02:14:05.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/fat/inode.c 2005-11-07 03:55:16.000000000 +0900
@@ -374,12 +374,17 @@ static void fat_clear_inode(struct inode
unlock_kernel();
}
-static void fat_put_super(struct super_block *sb)
+static void fat_write_super(struct super_block *sb)
{
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY))
fat_clusters_flush(sb);
+}
+
+static void fat_put_super(struct super_block *sb)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
if (sbi->nls_disk) {
unload_nls(sbi->nls_disk);
@@ -546,6 +551,7 @@ static struct super_operations fat_sops
.write_inode = fat_write_inode,
.delete_inode = fat_delete_inode,
.put_super = fat_put_super,
+ .write_super = fat_write_super,
.statfs = fat_statfs,
.clear_inode = fat_clear_inode,
.remount_fs = fat_remount,
diff -puN fs/fat/misc.c~fat_write_super fs/fat/misc.c
--- linux-2.6.14/fs/fat/misc.c~fat_write_super 2005-11-07 02:14:05.000000000 +0900
+++ linux-2.6.14-hirofumi/fs/fat/misc.c 2005-11-07 03:46:35.000000000 +0900
@@ -67,8 +67,6 @@ void fat_clusters_flush(struct super_blo
if (sbi->prev_free != -1)
fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
mark_buffer_dirty(bh);
- if (sb->s_flags & MS_SYNCHRONOUS)
- sync_dirty_buffer(bh);
}
brelse(bh);
}
_
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH] fat: use sb_find_get_block() instead of sb_getblk() 2005-11-07 17:32 [PATCH 1/6] fat: move fat_clusters_flush() to write_super() OGAWA Hirofumi @ 2005-11-07 17:36 ` OGAWA Hirofumi 2005-11-07 17:37 ` [PATCH 3/6] fat: add the read/writepages() OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:36 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel We don't need to allocate buffer for checking the buffer is uptodate. This use sb_find_get_block() instead, and if it returns NULL it's not uptodate. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/fat/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff -puN fs/fat/dir.c~fat_dir_readahead-optimize fs/fat/dir.c --- linux-2.6.14/fs/fat/dir.c~fat_dir_readahead-optimize 2005-11-07 03:58:44.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/dir.c 2005-11-07 03:58:44.000000000 +0900 @@ -45,8 +45,8 @@ static inline void fat_dir_readahead(str if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO)) return; - bh = sb_getblk(sb, phys); - if (bh && !buffer_uptodate(bh)) { + bh = sb_find_get_block(sb, phys); + if (bh == NULL || !buffer_uptodate(bh)) { for (sec = 0; sec < sbi->sec_per_clus; sec++) sb_breadahead(sb, phys + sec); } _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/6] fat: add the read/writepages() 2005-11-07 17:36 ` [PATCH] fat: use sb_find_get_block() instead of sb_getblk() OGAWA Hirofumi @ 2005-11-07 17:37 ` OGAWA Hirofumi 2005-11-07 17:39 ` [PATCH 4/6] fat: s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL/ OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:37 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/fat/inode.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff -puN fs/fat/inode.c~fat_read-writepages fs/fat/inode.c --- linux-2.6.14/fs/fat/inode.c~fat_read-writepages 2005-11-07 03:58:49.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/inode.c 2005-11-07 03:58:49.000000000 +0900 @@ -18,6 +18,7 @@ #include <linux/seq_file.h> #include <linux/msdos_fs.h> #include <linux/pagemap.h> +#include <linux/mpage.h> #include <linux/buffer_head.h> #include <linux/mount.h> #include <linux/vfs.h> @@ -90,9 +91,21 @@ static int fat_writepage(struct page *pa return block_write_full_page(page, fat_get_block, wbc); } +static int fat_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, fat_get_block); +} + static int fat_readpage(struct file *file, struct page *page) { - return block_read_full_page(page, fat_get_block); + return mpage_readpage(page, fat_get_block); +} + +static int fat_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, fat_get_block); } static int fat_prepare_write(struct file *file, struct page *page, @@ -122,7 +135,9 @@ static sector_t _fat_bmap(struct address static struct address_space_operations fat_aops = { .readpage = fat_readpage, + .readpages = fat_readpages, .writepage = fat_writepage, + .writepages = fat_writepages, .sync_page = block_sync_page, .prepare_write = fat_prepare_write, .commit_write = fat_commit_write, _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] fat: s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL/ 2005-11-07 17:37 ` [PATCH 3/6] fat: add the read/writepages() OGAWA Hirofumi @ 2005-11-07 17:39 ` OGAWA Hirofumi 2005-11-07 17:41 ` [PATCH 5/6] fat: support ->direct_IO() OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:39 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel All EXPORT_SYMBOL of fatfs is only for vfat/msdos. _GPL would be proper. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/fat/dir.c | 14 +++++++------- fs/fat/fatent.c | 2 +- fs/fat/file.c | 2 +- fs/fat/inode.c | 10 +++++----- fs/fat/misc.c | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff -puN fs/fat/dir.c~fat_export_symbol_gpl fs/fat/dir.c --- linux-2.6.14/fs/fat/dir.c~fat_export_symbol_gpl 2005-11-07 03:58:53.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/dir.c 2005-11-07 03:58:53.000000000 +0900 @@ -418,7 +418,7 @@ EODir: return err; } -EXPORT_SYMBOL(fat_search_long); +EXPORT_SYMBOL_GPL(fat_search_long); struct fat_ioctl_filldir_callback { struct dirent __user *dirent; @@ -780,7 +780,7 @@ int fat_get_dotdot_entry(struct inode *d return -ENOENT; } -EXPORT_SYMBOL(fat_get_dotdot_entry); +EXPORT_SYMBOL_GPL(fat_get_dotdot_entry); /* See if directory is empty */ int fat_dir_empty(struct inode *dir) @@ -803,7 +803,7 @@ int fat_dir_empty(struct inode *dir) return result; } -EXPORT_SYMBOL(fat_dir_empty); +EXPORT_SYMBOL_GPL(fat_dir_empty); /* * fat_subdirs counts the number of sub-directories of dir. It can be run @@ -849,7 +849,7 @@ int fat_scan(struct inode *dir, const un return -ENOENT; } -EXPORT_SYMBOL(fat_scan); +EXPORT_SYMBOL_GPL(fat_scan); static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) { @@ -936,7 +936,7 @@ int fat_remove_entries(struct inode *dir return 0; } -EXPORT_SYMBOL(fat_remove_entries); +EXPORT_SYMBOL_GPL(fat_remove_entries); static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, struct buffer_head **bhs, int nr_bhs) @@ -1048,7 +1048,7 @@ error: return err; } -EXPORT_SYMBOL(fat_alloc_new_dir); +EXPORT_SYMBOL_GPL(fat_alloc_new_dir); static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, int *nr_cluster, struct msdos_dir_entry **de, @@ -1264,4 +1264,4 @@ error_remove: return err; } -EXPORT_SYMBOL(fat_add_entries); +EXPORT_SYMBOL_GPL(fat_add_entries); diff -puN fs/fat/fatent.c~fat_export_symbol_gpl fs/fat/fatent.c --- linux-2.6.14/fs/fat/fatent.c~fat_export_symbol_gpl 2005-11-07 03:58:53.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/fatent.c 2005-11-07 03:58:53.000000000 +0900 @@ -581,7 +581,7 @@ error: return err; } -EXPORT_SYMBOL(fat_free_clusters); +EXPORT_SYMBOL_GPL(fat_free_clusters); int fat_count_free_clusters(struct super_block *sb) { diff -puN fs/fat/file.c~fat_export_symbol_gpl fs/fat/file.c --- linux-2.6.14/fs/fat/file.c~fat_export_symbol_gpl 2005-11-07 03:58:53.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/file.c 2005-11-07 03:58:53.000000000 +0900 @@ -173,7 +173,7 @@ out: return error; } -EXPORT_SYMBOL(fat_notify_change); +EXPORT_SYMBOL_GPL(fat_notify_change); /* Free all clusters after the skip'th cluster. */ static int fat_free(struct inode *inode, int skip) diff -puN fs/fat/inode.c~fat_export_symbol_gpl fs/fat/inode.c --- linux-2.6.14/fs/fat/inode.c~fat_export_symbol_gpl 2005-11-07 03:58:53.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/inode.c 2005-11-07 03:58:53.000000000 +0900 @@ -197,7 +197,7 @@ void fat_attach(struct inode *inode, lof spin_unlock(&sbi->inode_hash_lock); } -EXPORT_SYMBOL(fat_attach); +EXPORT_SYMBOL_GPL(fat_attach); void fat_detach(struct inode *inode) { @@ -208,7 +208,7 @@ void fat_detach(struct inode *inode) spin_unlock(&sbi->inode_hash_lock); } -EXPORT_SYMBOL(fat_detach); +EXPORT_SYMBOL_GPL(fat_detach); struct inode *fat_iget(struct super_block *sb, loff_t i_pos) { @@ -362,7 +362,7 @@ out: return inode; } -EXPORT_SYMBOL(fat_build_inode); +EXPORT_SYMBOL_GPL(fat_build_inode); static void fat_delete_inode(struct inode *inode) { @@ -557,7 +557,7 @@ int fat_sync_inode(struct inode *inode) return fat_write_inode(inode, 1); } -EXPORT_SYMBOL(fat_sync_inode); +EXPORT_SYMBOL_GPL(fat_sync_inode); static int fat_show_options(struct seq_file *m, struct vfsmount *mnt); static struct super_operations fat_sops = { @@ -1365,7 +1365,7 @@ out_fail: return error; } -EXPORT_SYMBOL(fat_fill_super); +EXPORT_SYMBOL_GPL(fat_fill_super); int __init fat_cache_init(void); void fat_cache_destroy(void); diff -puN fs/fat/misc.c~fat_export_symbol_gpl fs/fat/misc.c --- linux-2.6.14/fs/fat/misc.c~fat_export_symbol_gpl 2005-11-07 03:58:53.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/misc.c 2005-11-07 03:58:53.000000000 +0900 @@ -33,7 +33,7 @@ void fat_fs_panic(struct super_block *s, } } -EXPORT_SYMBOL(fat_fs_panic); +EXPORT_SYMBOL_GPL(fat_fs_panic); /* Flushes the number of free clusters on FAT32 */ /* XXX: Need to write one per FSINFO block. Currently only writes 1 */ @@ -192,7 +192,7 @@ void fat_date_unix2dos(int unix_date, __ *date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9)); } -EXPORT_SYMBOL(fat_date_unix2dos); +EXPORT_SYMBOL_GPL(fat_date_unix2dos); int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) { @@ -220,4 +220,4 @@ int fat_sync_bhs(struct buffer_head **bh return err; } -EXPORT_SYMBOL(fat_sync_bhs); +EXPORT_SYMBOL_GPL(fat_sync_bhs); _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/6] fat: support ->direct_IO() 2005-11-07 17:39 ` [PATCH 4/6] fat: s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL/ OGAWA Hirofumi @ 2005-11-07 17:41 ` OGAWA Hirofumi 2005-11-07 17:42 ` [PATCH 6/6] export/change sync_page_range/_nolock() OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:41 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel This patch add to support of ->direct_IO() for mostly read. The user of this seems to want to use for streaming read. So, current direct I/O has limitation, it can only overwrite. (For write operation, mainly we need to handle the hole etc..) Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/fat/cache.c | 14 ++++++-- fs/fat/dir.c | 6 +-- fs/fat/inode.c | 82 +++++++++++++++++++++++++++++++++++++++++------ include/linux/msdos_fs.h | 3 + 4 files changed, 89 insertions(+), 16 deletions(-) diff -puN fs/fat/cache.c~fat_direct-io fs/fat/cache.c --- linux-2.6.14/fs/fat/cache.c~fat_direct-io 2005-11-07 03:58:58.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/cache.c 2005-11-07 03:58:58.000000000 +0900 @@ -295,7 +295,8 @@ static int fat_bmap_cluster(struct inode return dclus; } -int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys) +int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, + unsigned long *mapped_blocks) { struct super_block *sb = inode->i_sb; struct msdos_sb_info *sbi = MSDOS_SB(sb); @@ -303,9 +304,12 @@ int fat_bmap(struct inode *inode, sector int cluster, offset; *phys = 0; + *mapped_blocks = 0; if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) { - if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) + if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) { *phys = sector + sbi->dir_start; + *mapped_blocks = 1; + } return 0; } last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1)) @@ -318,7 +322,11 @@ int fat_bmap(struct inode *inode, sector cluster = fat_bmap_cluster(inode, cluster); if (cluster < 0) return cluster; - else if (cluster) + else if (cluster) { *phys = fat_clus_to_blknr(sbi, cluster) + offset; + *mapped_blocks = sbi->sec_per_clus - offset; + if (*mapped_blocks > last_block - sector) + *mapped_blocks = last_block - sector; + } return 0; } diff -puN fs/fat/dir.c~fat_direct-io fs/fat/dir.c --- linux-2.6.14/fs/fat/dir.c~fat_direct-io 2005-11-07 03:58:58.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/dir.c 2005-11-07 03:58:58.000000000 +0900 @@ -68,8 +68,8 @@ static int fat__get_entry(struct inode * { struct super_block *sb = dir->i_sb; sector_t phys, iblock; - int offset; - int err; + unsigned long mapped_blocks; + int err, offset; next: if (*bh) @@ -77,7 +77,7 @@ next: *bh = NULL; iblock = *pos >> sb->s_blocksize_bits; - err = fat_bmap(dir, iblock, &phys); + err = fat_bmap(dir, iblock, &phys, &mapped_blocks); if (err || !phys) return -1; /* beyond EOF or error */ diff -puN fs/fat/inode.c~fat_direct-io fs/fat/inode.c --- linux-2.6.14/fs/fat/inode.c~fat_direct-io 2005-11-07 03:58:58.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/inode.c 2005-11-07 03:58:58.000000000 +0900 @@ -23,6 +23,7 @@ #include <linux/mount.h> #include <linux/vfs.h> #include <linux/parser.h> +#include <linux/uio.h> #include <asm/unaligned.h> #ifndef CONFIG_FAT_DEFAULT_IOCHARSET @@ -49,43 +50,77 @@ static int fat_add_cluster(struct inode return err; } -static int fat_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) +static int __fat_get_blocks(struct inode *inode, sector_t iblock, + unsigned long *max_blocks, + struct buffer_head *bh_result, int create) { struct super_block *sb = inode->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); sector_t phys; - int err; + unsigned long mapped_blocks; + int err, offset; - err = fat_bmap(inode, iblock, &phys); + err = fat_bmap(inode, iblock, &phys, &mapped_blocks); if (err) return err; if (phys) { map_bh(bh_result, sb, phys); + *max_blocks = min(mapped_blocks, *max_blocks); return 0; } if (!create) return 0; + if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) { fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)", MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private); return -EIO; } - if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) { + + offset = (unsigned long)iblock & (sbi->sec_per_clus - 1); + if (!offset) { + /* TODO: multiple cluster allocation would be desirable. */ err = fat_add_cluster(inode); if (err) return err; } - MSDOS_I(inode)->mmu_private += sb->s_blocksize; - err = fat_bmap(inode, iblock, &phys); + /* available blocks on this cluster */ + mapped_blocks = sbi->sec_per_clus - offset; + + *max_blocks = min(mapped_blocks, *max_blocks); + MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits; + + err = fat_bmap(inode, iblock, &phys, &mapped_blocks); if (err) return err; - if (!phys) - BUG(); + BUG_ON(!phys); + BUG_ON(*max_blocks != mapped_blocks); set_buffer_new(bh_result); map_bh(bh_result, sb, phys); return 0; } +static int fat_get_blocks(struct inode *inode, sector_t iblock, + unsigned long max_blocks, + struct buffer_head *bh_result, int create) +{ + struct super_block *sb = inode->i_sb; + int err; + + err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create); + if (err) + return err; + bh_result->b_size = max_blocks << sb->s_blocksize_bits; + return 0; +} + +static int fat_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + unsigned long max_blocks = 1; + return __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create); +} + static int fat_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, fat_get_block, wbc); @@ -128,6 +163,34 @@ static int fat_commit_write(struct file return err; } +static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, + loff_t offset, unsigned long nr_segs) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; + + if (rw == WRITE) { + /* + * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(), + * so we need to update the ->mmu_private to block boundary. + * + * But we must fill the remaining area or hole by nul for + * updating ->mmu_private. + */ + loff_t size = offset + iov_length(iov, nr_segs); + if (MSDOS_I(inode)->mmu_private < size) + return -EINVAL; + } + + /* + * FAT need to use the DIO_LOCKING for avoiding the race + * condition of fat_get_block() and ->truncate(). + */ + return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, + offset, nr_segs, fat_get_blocks, NULL); +} + static sector_t _fat_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping, block, fat_get_block); @@ -141,6 +204,7 @@ static struct address_space_operations f .sync_page = block_sync_page, .prepare_write = fat_prepare_write, .commit_write = fat_commit_write, + .direct_IO = fat_direct_IO, .bmap = _fat_bmap }; diff -puN include/linux/msdos_fs.h~fat_direct-io include/linux/msdos_fs.h --- linux-2.6.14/include/linux/msdos_fs.h~fat_direct-io 2005-11-07 03:58:58.000000000 +0900 +++ linux-2.6.14-hirofumi/include/linux/msdos_fs.h 2005-11-07 03:58:58.000000000 +0900 @@ -329,7 +329,8 @@ static inline void fatwchar_to16(__u8 *d extern void fat_cache_inval_inode(struct inode *inode); extern int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus); -extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys); +extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, + unsigned long *mapped_blocks); /* fat/dir.c */ extern struct file_operations fat_dir_operations; _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/6] export/change sync_page_range/_nolock() 2005-11-07 17:41 ` [PATCH 5/6] fat: support ->direct_IO() OGAWA Hirofumi @ 2005-11-07 17:42 ` OGAWA Hirofumi 2005-11-07 17:46 ` [PATCH 7/6] fat: Support a truncate() for expanding size OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:42 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel This exports/changes the sync_page_range/_nolock(). The fatfs needs sync_page_range/_nolock() for expanding truncate, and changes "size_t count" to "loff_t count". Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- include/linux/writeback.h | 4 +++- mm/filemap.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff -puN include/linux/writeback.h~export-sync_page_range_nolock include/linux/writeback.h --- linux-2.6.14/include/linux/writeback.h~export-sync_page_range_nolock 2005-11-07 03:59:03.000000000 +0900 +++ linux-2.6.14-hirofumi/include/linux/writeback.h 2005-11-07 03:59:03.000000000 +0900 @@ -108,7 +108,9 @@ void balance_dirty_pages_ratelimited(str int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0); int do_writepages(struct address_space *mapping, struct writeback_control *wbc); int sync_page_range(struct inode *inode, struct address_space *mapping, - loff_t pos, size_t count); + loff_t pos, loff_t count); +int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, + loff_t pos, loff_t count); /* pdflush.c */ extern int nr_pdflush_threads; /* Global so it can be exported to sysctl diff -puN mm/filemap.c~export-sync_page_range_nolock mm/filemap.c --- linux-2.6.14/mm/filemap.c~export-sync_page_range_nolock 2005-11-07 03:59:03.000000000 +0900 +++ linux-2.6.14-hirofumi/mm/filemap.c 2005-11-07 03:59:03.000000000 +0900 @@ -280,7 +280,7 @@ static int wait_on_page_writeback_range( * it is otherwise livelockable. */ int sync_page_range(struct inode *inode, struct address_space *mapping, - loff_t pos, size_t count) + loff_t pos, loff_t count) { pgoff_t start = pos >> PAGE_CACHE_SHIFT; pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; @@ -305,9 +305,8 @@ EXPORT_SYMBOL(sync_page_range); * as it forces O_SYNC writers to different parts of the same file * to be serialised right until io completion. */ -static int sync_page_range_nolock(struct inode *inode, - struct address_space *mapping, - loff_t pos, size_t count) +int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, + loff_t pos, loff_t count) { pgoff_t start = pos >> PAGE_CACHE_SHIFT; pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; @@ -322,6 +321,7 @@ static int sync_page_range_nolock(struct ret = wait_on_page_writeback_range(mapping, start, end); return ret; } +EXPORT_SYMBOL(sync_page_range_nolock); /** * filemap_fdatawait - walk the list of under-writeback pages of the given _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-07 17:42 ` [PATCH 6/6] export/change sync_page_range/_nolock() OGAWA Hirofumi @ 2005-11-07 17:46 ` OGAWA Hirofumi 2005-11-07 17:51 ` OGAWA Hirofumi 2005-11-08 1:06 ` Andrew Morton 0 siblings, 2 replies; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:46 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/fat/file.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff -puN fs/fat/file.c~fat_support-expand-truncate fs/fat/file.c --- linux-2.6.14/fs/fat/file.c~fat_support-expand-truncate 2005-11-07 03:59:07.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/file.c 2005-11-07 03:59:07.000000000 +0900 @@ -11,6 +11,7 @@ #include <linux/msdos_fs.h> #include <linux/smp_lock.h> #include <linux/buffer_head.h> +#include <linux/writeback.h> int fat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -124,6 +125,60 @@ struct file_operations fat_file_operatio .sendfile = generic_file_sendfile, }; +static int fat_cont_expand(struct inode *inode, loff_t size) +{ + struct address_space *mapping = inode->i_mapping; + struct page *page; + unsigned long index, limit; + loff_t count, pos, start; + unsigned int from, to; + int err; + + err = -EFBIG; + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit != RLIM_INFINITY && size > (loff_t)limit) { + send_sig(SIGXFSZ, current, 0); + goto out; + } + if (size > inode->i_sb->s_maxbytes) + goto out; + + start = inode->i_size; + count = size - inode->i_size; + /* calculate the stuff of last page */ + pos = size - 1; + index = pos >> PAGE_CACHE_SHIFT; + from = to = (pos & (PAGE_CACHE_SIZE - 1)) + 1; + + err = -ENOMEM; + page = grab_cache_page(mapping, index); + if (!page) + goto out; + err = mapping->a_ops->prepare_write(NULL, page, from, to); + if (unlikely(err)) { + /* + * ->prepare_write() may have instantiated a few blocks + * outside i_size. Trim these off again. + */ + unlock_page(page); + page_cache_release(page); + vmtruncate(inode, inode->i_size); + goto out; + } + + err = mapping->a_ops->commit_write(NULL, page, from, to); + + unlock_page(page); + page_cache_release(page); + + inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); + if (!err && IS_SYNC(inode)) + err = sync_page_range_nolock(inode, mapping, start, count); +out: + return err; +} + int fat_notify_change(struct dentry *dentry, struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); @@ -132,11 +187,17 @@ int fat_notify_change(struct dentry *den lock_kernel(); - /* FAT cannot truncate to a longer file */ + /* + * Expand the file. Since inode_setattr() updates ->i_size + * before calling the ->truncate(), but FAT needs to fill the + * hole before it. + */ if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_size > inode->i_size) { - error = -EPERM; - goto out; + error = fat_cont_expand(inode, attr->ia_size); + if (error || attr->ia_valid == ATTR_SIZE) + goto out; + attr->ia_valid &= ~ATTR_SIZE; } } _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-07 17:46 ` [PATCH 7/6] fat: Support a truncate() for expanding size OGAWA Hirofumi @ 2005-11-07 17:51 ` OGAWA Hirofumi 2005-11-08 1:06 ` Andrew Morton 1 sibling, 0 replies; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-07 17:51 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Sorry for broken index. [PATCH 1/7] fat: move fat_clusters_flush() to write_super() [PATCH 2/7] fat: use sb_find_get_block() instead of sb_getblk() [PATCH 3/7] fat: add the read/writepages() [PATCH 4/7] fat: s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL/ [PATCH 5/7] fat: support ->direct_IO() [PATCH 6/7] export/change sync_page_range/_nolock() [PATCH 7/7] fat: Support a truncate() for expanding size The above is right index. If I need to resend, please tell me. Note for reviewers, [6/7] patch is not a part of fatfs. Thanks. -- OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-07 17:46 ` [PATCH 7/6] fat: Support a truncate() for expanding size OGAWA Hirofumi 2005-11-07 17:51 ` OGAWA Hirofumi @ 2005-11-08 1:06 ` Andrew Morton 2005-11-08 3:19 ` OGAWA Hirofumi 1 sibling, 1 reply; 13+ messages in thread From: Andrew Morton @ 2005-11-08 1:06 UTC (permalink / raw) To: OGAWA Hirofumi; +Cc: linux-kernel OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote: > > +static int fat_cont_expand(struct inode *inode, loff_t size) Is it not possible to extend generic_cont_expand() so that fatfs can use it? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-08 1:06 ` Andrew Morton @ 2005-11-08 3:19 ` OGAWA Hirofumi 2005-11-08 4:19 ` Andrew Morton 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-08 3:19 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Andrew Morton <akpm@osdl.org> writes: > OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote: >> >> +static int fat_cont_expand(struct inode *inode, loff_t size) > > Is it not possible to extend generic_cont_expand() so that fatfs can use it? The generic_cont_expand() is too generic. If "size" is block boundary, generic_cont_expand() expands the ->i_size to "size + 1", after it, the caller of it will truncate to "size" by vmtruncate(). This sequence is not need if ->prepare_write() is cont_prepare_write(). The cont_prepare_write() will just fill the blocks with zero until "size" if blocks is not allocated yet. FAT is using cont_parepare_write(), so for avoiding the above extra work, is using own version. Probably, this version is generic only for cont_parepare_write(). Thanks. -- OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-08 3:19 ` OGAWA Hirofumi @ 2005-11-08 4:19 ` Andrew Morton 2005-11-08 5:22 ` OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: Andrew Morton @ 2005-11-08 4:19 UTC (permalink / raw) To: OGAWA Hirofumi; +Cc: linux-kernel OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote: > > Andrew Morton <akpm@osdl.org> writes: > > > OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote: > >> > >> +static int fat_cont_expand(struct inode *inode, loff_t size) > > > > Is it not possible to extend generic_cont_expand() so that fatfs can use it? > > The generic_cont_expand() is too generic. But can it be fixed?? > If "size" is block boundary, generic_cont_expand() expands the > ->i_size to "size + 1", after it, the caller of it will truncate to > "size" by vmtruncate(). Something like this? --- devel/fs/buffer.c~a 2005-11-07 20:17:49.000000000 -0800 +++ devel-akpm/fs/buffer.c 2005-11-07 20:18:59.000000000 -0800 @@ -2160,7 +2160,7 @@ int block_read_full_page(struct page *pa * truncates. Uses prepare/commit_write to allow the filesystem to * deal with the hole. */ -int generic_cont_expand(struct inode *inode, loff_t size) +static int __generic_cont_expand(struct inode *inode, loff_t size, int dont_do_that) { struct address_space *mapping = inode->i_mapping; struct page *page; @@ -2182,9 +2182,8 @@ int generic_cont_expand(struct inode *in ** skip the prepare. make sure we never send an offset for the start ** of a block */ - if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { + if (!dont_do_that && (offset & (inode->i_sb->s_blocksize - 1)) == 0) offset++; - } index = size >> PAGE_CACHE_SHIFT; err = -ENOMEM; page = grab_cache_page(mapping, index); @@ -2202,6 +2201,16 @@ out: return err; } +int generic_cont_expand(struct inode *inode, loff_t size) +{ + return __generic_cont_expand(inode, size, 0); +} + +int generic_cont_expand_dont_do_that(struct inode *inode, loff_t size) +{ + return __generic_cont_expand(inode, size, 1); +} + /* * For moronic filesystems that do not allow holes in file. * We may have to extend the file. _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-08 4:19 ` Andrew Morton @ 2005-11-08 5:22 ` OGAWA Hirofumi 2005-11-08 20:40 ` OGAWA Hirofumi 0 siblings, 1 reply; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-08 5:22 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Andrew Morton <akpm@osdl.org> writes: >> The generic_cont_expand() is too generic. > > But can it be fixed?? Oh, probably we can... >> If "size" is block boundary, generic_cont_expand() expands the >> ->i_size to "size + 1", after it, the caller of it will truncate to >> "size" by vmtruncate(). > > Something like this? > [...] > -int generic_cont_expand(struct inode *inode, loff_t size) > +static int __generic_cont_expand(struct inode *inode, loff_t size, int dont_do_that) > { > struct address_space *mapping = inode->i_mapping; > struct page *page; > @@ -2182,9 +2182,8 @@ int generic_cont_expand(struct inode *in > ** skip the prepare. make sure we never send an offset for the start > ** of a block > */ > - if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { > + if (!dont_do_that && (offset & (inode->i_sb->s_blocksize - 1)) == 0) > offset++; Yes. But, if size is the page boundary, index is different. Probably something like the below. And I'd like to do vmtruncate() if ->prepare_write() returns a error. The sync_page_range_nolock() can do by caller, so not necessary. Hmm, I'll rethink this at tonight (10 hours later), the result may be same after all though. Thanks. if (!dont_do_that) { offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ /* ugh. in prepare/commit_write, if from==to==start of block, we ** skip the prepare. make sure we never send an offset for the start ** of a block */ if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { offset++; } index = size >> PAGE_CACHE_SHIFT; } else { /* calculate the stuff of last page */ loff_t pos = size - 1; index = pos >> PAGE_CACHE_SHIFT; offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1; } -- OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/6] fat: Support a truncate() for expanding size 2005-11-08 5:22 ` OGAWA Hirofumi @ 2005-11-08 20:40 ` OGAWA Hirofumi 0 siblings, 0 replies; 13+ messages in thread From: OGAWA Hirofumi @ 2005-11-08 20:40 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes: >> -int generic_cont_expand(struct inode *inode, loff_t size) >> +static int __generic_cont_expand(struct inode *inode, loff_t size, int dont_do_that) >> { >> struct address_space *mapping = inode->i_mapping; >> struct page *page; >> @@ -2182,9 +2182,8 @@ int generic_cont_expand(struct inode *in >> ** skip the prepare. make sure we never send an offset for the start >> ** of a block >> */ >> - if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { >> + if (!dont_do_that && (offset & (inode->i_sb->s_blocksize - 1)) == 0) >> offset++; > > Yes. But, if size is the page boundary, index is different. > > Probably something like the below. And I'd like to do vmtruncate() > if ->prepare_write() returns a error. The sync_page_range_nolock() > can do by caller, so not necessary. > > Hmm, I'll rethink this at tonight (10 hours later), the result may be > same after all though. How about this patch? If ok, please replace fat-support-a-truncate-for-expanding-size.patch with this. Thanks. -- OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> [PATCH] fat: Support a truncate() for expanding size (generic_cont_expand) This patch changes generic_cont_expand(), in order to share the code with fatfs. - Use vmtruncate() if ->prepare_write() returns a error. Even if ->prepare_write() returns an error, it may already have added some blocks. So, this truncates blocks outside of ->i_size by vmtruncate(). - Add generic_cont_expand_simple(). The generic_cont_expand_simple() assumes that ->prepare_write() can handle the block boundary. With this, we don't need to care the extra byte. And for expanding a file size by truncate(), fatfs uses the added generic_cont_expand_simple(). Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> --- fs/buffer.c | 60 +++++++++++++++++++++++++++++++++----------- fs/fat/file.c | 31 ++++++++++++++++++++-- include/linux/buffer_head.h | 3 +- 3 files changed, 76 insertions(+), 18 deletions(-) diff -puN fs/fat/file.c~fat_support-expand-truncate fs/fat/file.c --- linux-2.6.14/fs/fat/file.c~fat_support-expand-truncate 2005-11-07 23:03:02.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/fat/file.c 2005-11-09 04:00:53.000000000 +0900 @@ -11,6 +11,7 @@ #include <linux/msdos_fs.h> #include <linux/smp_lock.h> #include <linux/buffer_head.h> +#include <linux/writeback.h> int fat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -124,6 +125,24 @@ struct file_operations fat_file_operatio .sendfile = generic_file_sendfile, }; +static int fat_cont_expand(struct inode *inode, loff_t size) +{ + struct address_space *mapping = inode->i_mapping; + loff_t start = inode->i_size, count = size - inode->i_size; + int err; + + err = generic_cont_expand_simple(inode, size); + if (err) + goto out; + + inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); + if (IS_SYNC(inode)) + err = sync_page_range_nolock(inode, mapping, start, count); +out: + return err; +} + int fat_notify_change(struct dentry *dentry, struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); @@ -132,11 +151,17 @@ int fat_notify_change(struct dentry *den lock_kernel(); - /* FAT cannot truncate to a longer file */ + /* + * Expand the file. Since inode_setattr() updates ->i_size + * before calling the ->truncate(), but FAT needs to fill the + * hole before it. + */ if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_size > inode->i_size) { - error = -EPERM; - goto out; + error = fat_cont_expand(inode, attr->ia_size); + if (error || attr->ia_valid == ATTR_SIZE) + goto out; + attr->ia_valid &= ~ATTR_SIZE; } } diff -puN fs/buffer.c~fat_support-expand-truncate fs/buffer.c --- linux-2.6.14/fs/buffer.c~fat_support-expand-truncate 2005-11-09 03:35:10.000000000 +0900 +++ linux-2.6.14-hirofumi/fs/buffer.c 2005-11-09 04:33:29.000000000 +0900 @@ -2160,11 +2160,12 @@ int block_read_full_page(struct page *pa * truncates. Uses prepare/commit_write to allow the filesystem to * deal with the hole. */ -int generic_cont_expand(struct inode *inode, loff_t size) +static int __generic_cont_expand(struct inode *inode, loff_t size, + pgoff_t index, unsigned int offset) { struct address_space *mapping = inode->i_mapping; struct page *page; - unsigned long index, offset, limit; + unsigned long limit; int err; err = -EFBIG; @@ -2176,24 +2177,24 @@ int generic_cont_expand(struct inode *in if (size > inode->i_sb->s_maxbytes) goto out; - offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ - - /* ugh. in prepare/commit_write, if from==to==start of block, we - ** skip the prepare. make sure we never send an offset for the start - ** of a block - */ - if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { - offset++; - } - index = size >> PAGE_CACHE_SHIFT; err = -ENOMEM; page = grab_cache_page(mapping, index); if (!page) goto out; err = mapping->a_ops->prepare_write(NULL, page, offset, offset); - if (!err) { - err = mapping->a_ops->commit_write(NULL, page, offset, offset); + if (err) { + /* + * ->prepare_write() may have instantiated a few blocks + * outside i_size. Trim these off again. + */ + unlock_page(page); + page_cache_release(page); + vmtruncate(inode, inode->i_size); + goto out; } + + err = mapping->a_ops->commit_write(NULL, page, offset, offset); + unlock_page(page); page_cache_release(page); if (err > 0) @@ -2202,6 +2203,36 @@ out: return err; } +int generic_cont_expand(struct inode *inode, loff_t size) +{ + pgoff_t index; + unsigned int offset; + + offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */ + + /* ugh. in prepare/commit_write, if from==to==start of block, we + ** skip the prepare. make sure we never send an offset for the start + ** of a block + */ + if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { + /* caller must handle this extra byte. */ + offset++; + } + index = size >> PAGE_CACHE_SHIFT; + + return __generic_cont_expand(inode, size, index, offset); +} + +int generic_cont_expand_simple(struct inode *inode, loff_t size) +{ + loff_t pos = size - 1; + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1; + + /* prepare/commit_write can handle even if from==to==start of block. */ + return __generic_cont_expand(inode, size, index, offset); +} + /* * For moronic filesystems that do not allow holes in file. * We may have to extend the file. @@ -3145,6 +3176,7 @@ EXPORT_SYMBOL(fsync_bdev); EXPORT_SYMBOL(generic_block_bmap); EXPORT_SYMBOL(generic_commit_write); EXPORT_SYMBOL(generic_cont_expand); +EXPORT_SYMBOL(generic_cont_expand_simple); EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(invalidate_bdev); EXPORT_SYMBOL(ll_rw_block); diff -puN include/linux/buffer_head.h~fat_support-expand-truncate include/linux/buffer_head.h --- linux-2.6.14/include/linux/buffer_head.h~fat_support-expand-truncate 2005-11-09 03:37:26.000000000 +0900 +++ linux-2.6.14-hirofumi/include/linux/buffer_head.h 2005-11-09 03:37:36.000000000 +0900 @@ -197,7 +197,8 @@ int block_read_full_page(struct page*, g int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*, loff_t *); -int generic_cont_expand(struct inode *inode, loff_t size) ; +int generic_cont_expand(struct inode *inode, loff_t size); +int generic_cont_expand_simple(struct inode *inode, loff_t size); int block_commit_write(struct page *page, unsigned from, unsigned to); int block_sync_page(struct page *); sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); _ ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2005-11-08 20:40 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-07 17:32 [PATCH 1/6] fat: move fat_clusters_flush() to write_super() OGAWA Hirofumi 2005-11-07 17:36 ` [PATCH] fat: use sb_find_get_block() instead of sb_getblk() OGAWA Hirofumi 2005-11-07 17:37 ` [PATCH 3/6] fat: add the read/writepages() OGAWA Hirofumi 2005-11-07 17:39 ` [PATCH 4/6] fat: s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL/ OGAWA Hirofumi 2005-11-07 17:41 ` [PATCH 5/6] fat: support ->direct_IO() OGAWA Hirofumi 2005-11-07 17:42 ` [PATCH 6/6] export/change sync_page_range/_nolock() OGAWA Hirofumi 2005-11-07 17:46 ` [PATCH 7/6] fat: Support a truncate() for expanding size OGAWA Hirofumi 2005-11-07 17:51 ` OGAWA Hirofumi 2005-11-08 1:06 ` Andrew Morton 2005-11-08 3:19 ` OGAWA Hirofumi 2005-11-08 4:19 ` Andrew Morton 2005-11-08 5:22 ` OGAWA Hirofumi 2005-11-08 20:40 ` OGAWA Hirofumi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox