* [PATCH v8 1/4] fat: add fat_fallocate operation
@ 2014-12-09 7:17 Namjae Jeon
2014-12-09 14:21 ` Lukáš Czerner
0 siblings, 1 reply; 5+ messages in thread
From: Namjae Jeon @ 2014-12-09 7:17 UTC (permalink / raw)
To: OGAWA Hirofumi, Andrew Morton; +Cc: linux-fsdevel
Implement preallocation via the fallocate syscall on VFAT partitions.
This patch is based on an earlier patch of the same name which had some
issues detailed below and did not get accepted. Refer
https://lkml.org/lkml/2007/12/22/130.
a) The preallocated space was not persistent when the
FALLOC_FL_KEEP_SIZE flag was set. It will deallocate cluster at evict
time.
b) There was no need to zero out the clusters when the flag was set
Instead of doing an expanding truncate, just allocate clusters and add
them to the fat chain. This reduces preallocation time.
Compatibility with windows:
There are no issues when FALLOC_FL_KEEP_SIZE is not set because it just
does an expanding truncate. Thus reading from the preallocated area on
windows returns null until data is written to it.
When a file with preallocated area using the FALLOC_FL_KEEP_SIZE was
written to on windows, the windows driver freed-up the preallocated
clusters and allocated new clusters for the new data. The freed up
clusters gets reflected in the free space available for the partition
which can be seen from the Volume properties.
The windows chkdsk tool also does not report any errors on a disk
containing files with preallocated space.
And there is also no issue using linux fat fsck. because discard
preallocated clusters at repair time.
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
---
fs/fat/fat.h | 1 +
fs/fat/file.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/fat/inode.c | 34 +++++++++++++++++++++++++++++--
3 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 64e295e..df72581 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -387,6 +387,7 @@ static inline unsigned long fat_dir_hash(int logstart)
{
return hash_32(logstart, FAT_HASH_BITS);
}
+extern int fat_add_cluster(struct inode *inode);
/* fat/misc.c */
extern __printf(3, 4) __cold
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 8429c68..cebe7c9 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -17,8 +17,12 @@
#include <linux/blkdev.h>
#include <linux/fsnotify.h>
#include <linux/security.h>
+#include <linux/falloc.h>
#include "fat.h"
+static long fat_fallocate(struct file *file, int mode,
+ loff_t offset, loff_t len);
+
static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr)
{
u32 attr;
@@ -182,6 +186,7 @@ const struct file_operations fat_file_operations = {
#endif
.fsync = fat_file_fsync,
.splice_read = generic_file_splice_read,
+ .fallocate = fat_fallocate,
};
static int fat_cont_expand(struct inode *inode, loff_t size)
@@ -220,6 +225,62 @@ out:
return err;
}
+/*
+ * Preallocate space for a file. This implements fat's fallocate file
+ * operation, which gets called from sys_fallocate system call. User
+ * space requests len bytes at offset. If FALLOC_FL_KEEP_SIZE is set
+ * we just allocate clusters without zeroing them out. Otherwise we
+ * allocate and zero out clusters via an expanding truncate.
+ */
+static long fat_fallocate(struct file *file, int mode,
+ loff_t offset, loff_t len)
+{
+ int nr_cluster; /* Number of clusters to be allocated */
+ loff_t mm_bytes; /* Number of bytes to be allocated for file */
+ loff_t ondisksize; /* block aligned on-disk size in bytes*/
+ struct inode *inode = file->f_mapping->host;
+ struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ int err = 0;
+
+ /* No support for hole punch or other fallocate flags. */
+ if (mode & ~FALLOC_FL_KEEP_SIZE)
+ return -EOPNOTSUPP;
+
+ /* No support for dir */
+ if (!S_ISREG(inode->i_mode))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&inode->i_mutex);
+ if (mode & FALLOC_FL_KEEP_SIZE) {
+ ondisksize = inode->i_blocks << 9;
+ if ((offset + len) <= ondisksize)
+ goto error;
+
+ /* First compute the number of clusters to be allocated */
+ mm_bytes = offset + len - ondisksize;
+ nr_cluster = (mm_bytes + (sbi->cluster_size - 1)) >>
+ sbi->cluster_bits;
+
+ /* Start the allocation.We are not zeroing out the clusters */
+ while (nr_cluster-- > 0) {
+ err = fat_add_cluster(inode);
+ if (err)
+ goto error;
+ }
+ } else {
+ if ((offset + len) <= i_size_read(inode))
+ goto error;
+
+ /* This is just an expanding truncate */
+ err = fat_cont_expand(inode, (offset + len));
+ }
+
+error:
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
+
/* Free all clusters after the skip'th cluster. */
static int fat_free(struct inode *inode, int skip)
{
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7b41a2d..1f9e4d9 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -101,7 +101,7 @@ static struct fat_floppy_defaults {
},
};
-static int fat_add_cluster(struct inode *inode)
+int fat_add_cluster(struct inode *inode)
{
int err, cluster;
@@ -562,13 +562,43 @@ out:
EXPORT_SYMBOL_GPL(fat_build_inode);
+static int __fat_write_inode(struct inode *inode, int wait);
+
+static void fat_free_eofblocks(struct inode *inode)
+{
+ /* Release unwritten fallocated blocks on inode eviction. */
+ if ((inode->i_blocks << 9) >
+ round_up(MSDOS_I(inode)->mmu_private,
+ MSDOS_SB(inode->i_sb)->cluster_size)) {
+ int err;
+
+ fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
+ /* Fallocate results in updating the i_start/iogstart
+ * for the zero byte file. So, make it return to
+ * original state during evict and commit it to avoid
+ * any corruption on the next access to the cluster
+ * chain for the file.
+ */
+ err = __fat_write_inode(inode, inode_needs_sync(inode));
+ if (err) {
+ fat_msg(inode->i_sb, KERN_WARNING, "Failed to "
+ "update on disk inode for unused "
+ "fallocated blocks, inode could be "
+ "corrupted. Please run fsck");
+ }
+
+ }
+}
+
static void fat_evict_inode(struct inode *inode)
{
truncate_inode_pages_final(&inode->i_data);
if (!inode->i_nlink) {
inode->i_size = 0;
fat_truncate_blocks(inode, 0);
- }
+ } else
+ fat_free_eofblocks(inode);
+
invalidate_inode_buffers(inode);
clear_inode(inode);
fat_cache_inval_inode(inode);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v8 1/4] fat: add fat_fallocate operation
2014-12-09 7:17 [PATCH v8 1/4] fat: add fat_fallocate operation Namjae Jeon
@ 2014-12-09 14:21 ` Lukáš Czerner
2014-12-10 10:42 ` Namjae Jeon
0 siblings, 1 reply; 5+ messages in thread
From: Lukáš Czerner @ 2014-12-09 14:21 UTC (permalink / raw)
To: Namjae Jeon; +Cc: OGAWA Hirofumi, Andrew Morton, linux-fsdevel
Hi,
so if I understand that correctly, then the regular fallocate on fat
file system is the same extending truncate.
The only benefit is the FALLOC_FL_KEEP_SIZE mode, which however
behaves differently on fat than on any other linux file system so an
application using fallocate with FALLOC_FL_KEEP_SIZE would have to
be aware of the file system it is using. Because otherwise the
preallocated space can disappear randomly after close.
I am really not sure I am ok with that. This can actually break
existing applications which are using FALLOC_FL_KEEP_SIZE because
aside from the benefit of preallocating space it will also guarantee
that the space is available to use and allocated for the file, which
on fat file system after file is closed might no longer be true.
No programmer using fallocate will expect that. Can you please clarify
that situation ?
Thanks!
-Lukas
On Tue, 9 Dec 2014, Namjae Jeon wrote:
> Date: Tue, 09 Dec 2014 16:17:00 +0900
> From: Namjae Jeon <namjae.jeon@samsung.com>
> To: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
> Andrew Morton <akpm@linux-foundation.org>
> Cc: linux-fsdevel@vger.kernel.org
> Subject: [PATCH v8 1/4] fat: add fat_fallocate operation
>
> Implement preallocation via the fallocate syscall on VFAT partitions.
> This patch is based on an earlier patch of the same name which had some
> issues detailed below and did not get accepted. Refer
> https://lkml.org/lkml/2007/12/22/130.
>
> a) The preallocated space was not persistent when the
> FALLOC_FL_KEEP_SIZE flag was set. It will deallocate cluster at evict
> time.
>
> b) There was no need to zero out the clusters when the flag was set
> Instead of doing an expanding truncate, just allocate clusters and add
> them to the fat chain. This reduces preallocation time.
>
> Compatibility with windows:
>
> There are no issues when FALLOC_FL_KEEP_SIZE is not set because it just
> does an expanding truncate. Thus reading from the preallocated area on
> windows returns null until data is written to it.
>
> When a file with preallocated area using the FALLOC_FL_KEEP_SIZE was
> written to on windows, the windows driver freed-up the preallocated
> clusters and allocated new clusters for the new data. The freed up
> clusters gets reflected in the free space available for the partition
> which can be seen from the Volume properties.
>
> The windows chkdsk tool also does not report any errors on a disk
> containing files with preallocated space.
>
> And there is also no issue using linux fat fsck. because discard
> preallocated clusters at repair time.
>
> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
> Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
> ---
> fs/fat/fat.h | 1 +
> fs/fat/file.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/fat/inode.c | 34 +++++++++++++++++++++++++++++--
> 3 files changed, 94 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fat/fat.h b/fs/fat/fat.h
> index 64e295e..df72581 100644
> --- a/fs/fat/fat.h
> +++ b/fs/fat/fat.h
> @@ -387,6 +387,7 @@ static inline unsigned long fat_dir_hash(int logstart)
> {
> return hash_32(logstart, FAT_HASH_BITS);
> }
> +extern int fat_add_cluster(struct inode *inode);
>
> /* fat/misc.c */
> extern __printf(3, 4) __cold
> diff --git a/fs/fat/file.c b/fs/fat/file.c
> index 8429c68..cebe7c9 100644
> --- a/fs/fat/file.c
> +++ b/fs/fat/file.c
> @@ -17,8 +17,12 @@
> #include <linux/blkdev.h>
> #include <linux/fsnotify.h>
> #include <linux/security.h>
> +#include <linux/falloc.h>
> #include "fat.h"
>
> +static long fat_fallocate(struct file *file, int mode,
> + loff_t offset, loff_t len);
> +
> static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr)
> {
> u32 attr;
> @@ -182,6 +186,7 @@ const struct file_operations fat_file_operations = {
> #endif
> .fsync = fat_file_fsync,
> .splice_read = generic_file_splice_read,
> + .fallocate = fat_fallocate,
> };
>
> static int fat_cont_expand(struct inode *inode, loff_t size)
> @@ -220,6 +225,62 @@ out:
> return err;
> }
>
> +/*
> + * Preallocate space for a file. This implements fat's fallocate file
> + * operation, which gets called from sys_fallocate system call. User
> + * space requests len bytes at offset. If FALLOC_FL_KEEP_SIZE is set
> + * we just allocate clusters without zeroing them out. Otherwise we
> + * allocate and zero out clusters via an expanding truncate.
> + */
> +static long fat_fallocate(struct file *file, int mode,
> + loff_t offset, loff_t len)
> +{
> + int nr_cluster; /* Number of clusters to be allocated */
> + loff_t mm_bytes; /* Number of bytes to be allocated for file */
> + loff_t ondisksize; /* block aligned on-disk size in bytes*/
> + struct inode *inode = file->f_mapping->host;
> + struct super_block *sb = inode->i_sb;
> + struct msdos_sb_info *sbi = MSDOS_SB(sb);
> + int err = 0;
> +
> + /* No support for hole punch or other fallocate flags. */
> + if (mode & ~FALLOC_FL_KEEP_SIZE)
> + return -EOPNOTSUPP;
> +
> + /* No support for dir */
> + if (!S_ISREG(inode->i_mode))
> + return -EOPNOTSUPP;
> +
> + mutex_lock(&inode->i_mutex);
> + if (mode & FALLOC_FL_KEEP_SIZE) {
> + ondisksize = inode->i_blocks << 9;
> + if ((offset + len) <= ondisksize)
> + goto error;
> +
> + /* First compute the number of clusters to be allocated */
> + mm_bytes = offset + len - ondisksize;
> + nr_cluster = (mm_bytes + (sbi->cluster_size - 1)) >>
> + sbi->cluster_bits;
> +
> + /* Start the allocation.We are not zeroing out the clusters */
> + while (nr_cluster-- > 0) {
> + err = fat_add_cluster(inode);
> + if (err)
> + goto error;
> + }
> + } else {
> + if ((offset + len) <= i_size_read(inode))
> + goto error;
> +
> + /* This is just an expanding truncate */
> + err = fat_cont_expand(inode, (offset + len));
> + }
> +
> +error:
> + mutex_unlock(&inode->i_mutex);
> + return err;
> +}
> +
> /* Free all clusters after the skip'th cluster. */
> static int fat_free(struct inode *inode, int skip)
> {
> diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> index 7b41a2d..1f9e4d9 100644
> --- a/fs/fat/inode.c
> +++ b/fs/fat/inode.c
> @@ -101,7 +101,7 @@ static struct fat_floppy_defaults {
> },
> };
>
> -static int fat_add_cluster(struct inode *inode)
> +int fat_add_cluster(struct inode *inode)
> {
> int err, cluster;
>
> @@ -562,13 +562,43 @@ out:
>
> EXPORT_SYMBOL_GPL(fat_build_inode);
>
> +static int __fat_write_inode(struct inode *inode, int wait);
> +
> +static void fat_free_eofblocks(struct inode *inode)
> +{
> + /* Release unwritten fallocated blocks on inode eviction. */
> + if ((inode->i_blocks << 9) >
> + round_up(MSDOS_I(inode)->mmu_private,
> + MSDOS_SB(inode->i_sb)->cluster_size)) {
> + int err;
> +
> + fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
> + /* Fallocate results in updating the i_start/iogstart
> + * for the zero byte file. So, make it return to
> + * original state during evict and commit it to avoid
> + * any corruption on the next access to the cluster
> + * chain for the file.
> + */
> + err = __fat_write_inode(inode, inode_needs_sync(inode));
> + if (err) {
> + fat_msg(inode->i_sb, KERN_WARNING, "Failed to "
> + "update on disk inode for unused "
> + "fallocated blocks, inode could be "
> + "corrupted. Please run fsck");
> + }
> +
> + }
> +}
> +
> static void fat_evict_inode(struct inode *inode)
> {
> truncate_inode_pages_final(&inode->i_data);
> if (!inode->i_nlink) {
> inode->i_size = 0;
> fat_truncate_blocks(inode, 0);
> - }
> + } else
> + fat_free_eofblocks(inode);
> +
> invalidate_inode_buffers(inode);
> clear_inode(inode);
> fat_cache_inval_inode(inode);
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH v8 1/4] fat: add fat_fallocate operation
2014-12-09 14:21 ` Lukáš Czerner
@ 2014-12-10 10:42 ` Namjae Jeon
2014-12-10 10:45 ` Christoph Hellwig
0 siblings, 1 reply; 5+ messages in thread
From: Namjae Jeon @ 2014-12-10 10:42 UTC (permalink / raw)
To: 'Lukáš Czerner'
Cc: 'OGAWA Hirofumi', 'Andrew Morton', linux-fsdevel
>
> Hi,
Hi Lukas,
>
> so if I understand that correctly, then the regular fallocate on fat
> file system is the same extending truncate.
>
> The only benefit is the FALLOC_FL_KEEP_SIZE mode, which however
> behaves differently on fat than on any other linux file system so an
> application using fallocate with FALLOC_FL_KEEP_SIZE would have to
> be aware of the file system it is using. Because otherwise the
> preallocated space can disappear randomly after close.
>
> I am really not sure I am ok with that. This can actually break
> existing applications which are using FALLOC_FL_KEEP_SIZE because
> aside from the benefit of preallocating space it will also guarantee
> that the space is available to use and allocated for the file, which
> on fat file system after file is closed might no longer be true.
>
> No programmer using fallocate will expect that. Can you please clarify
> that situation ?
Your concern was already discussed. But we need to consider compatiablity
for fat fallocate support first. So it has a limitiation that make clean
state before umount(). i.e. preallocated blocks will be discarded at
evict time.
User have to call fallocate again if opening file after close().
And fallocate() will skip allocation if fallocated blocks is avaiable.
Instead, It gurrantee to be available fallocated blocks between open
and close(). And I updated such limitation of fat fallocate in
Documentation.
Thanks!
>
> Thanks!
> -Lukas
>
> On Tue, 9 Dec 2014, Namjae Jeon wrote:
>
> > Date: Tue, 09 Dec 2014 16:17:00 +0900
> > From: Namjae Jeon <namjae.jeon@samsung.com>
> > To: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
> > Andrew Morton <akpm@linux-foundation.org>
> > Cc: linux-fsdevel@vger.kernel.org
> > Subject: [PATCH v8 1/4] fat: add fat_fallocate operation
> >
> > Implement preallocation via the fallocate syscall on VFAT partitions.
> > This patch is based on an earlier patch of the same name which had some
> > issues detailed below and did not get accepted. Refer
> > https://lkml.org/lkml/2007/12/22/130.
> >
> > a) The preallocated space was not persistent when the
> > FALLOC_FL_KEEP_SIZE flag was set. It will deallocate cluster at evict
> > time.
> >
> > b) There was no need to zero out the clusters when the flag was set
> > Instead of doing an expanding truncate, just allocate clusters and add
> > them to the fat chain. This reduces preallocation time.
> >
> > Compatibility with windows:
> >
> > There are no issues when FALLOC_FL_KEEP_SIZE is not set because it just
> > does an expanding truncate. Thus reading from the preallocated area on
> > windows returns null until data is written to it.
> >
> > When a file with preallocated area using the FALLOC_FL_KEEP_SIZE was
> > written to on windows, the windows driver freed-up the preallocated
> > clusters and allocated new clusters for the new data. The freed up
> > clusters gets reflected in the free space available for the partition
> > which can be seen from the Volume properties.
> >
> > The windows chkdsk tool also does not report any errors on a disk
> > containing files with preallocated space.
> >
> > And there is also no issue using linux fat fsck. because discard
> > preallocated clusters at repair time.
> >
> > Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
> > Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
> > ---
> > fs/fat/fat.h | 1 +
> > fs/fat/file.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > fs/fat/inode.c | 34 +++++++++++++++++++++++++++++--
> > 3 files changed, 94 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/fat/fat.h b/fs/fat/fat.h
> > index 64e295e..df72581 100644
> > --- a/fs/fat/fat.h
> > +++ b/fs/fat/fat.h
> > @@ -387,6 +387,7 @@ static inline unsigned long fat_dir_hash(int logstart)
> > {
> > return hash_32(logstart, FAT_HASH_BITS);
> > }
> > +extern int fat_add_cluster(struct inode *inode);
> >
> > /* fat/misc.c */
> > extern __printf(3, 4) __cold
> > diff --git a/fs/fat/file.c b/fs/fat/file.c
> > index 8429c68..cebe7c9 100644
> > --- a/fs/fat/file.c
> > +++ b/fs/fat/file.c
> > @@ -17,8 +17,12 @@
> > #include <linux/blkdev.h>
> > #include <linux/fsnotify.h>
> > #include <linux/security.h>
> > +#include <linux/falloc.h>
> > #include "fat.h"
> >
> > +static long fat_fallocate(struct file *file, int mode,
> > + loff_t offset, loff_t len);
> > +
> > static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr)
> > {
> > u32 attr;
> > @@ -182,6 +186,7 @@ const struct file_operations fat_file_operations = {
> > #endif
> > .fsync = fat_file_fsync,
> > .splice_read = generic_file_splice_read,
> > + .fallocate = fat_fallocate,
> > };
> >
> > static int fat_cont_expand(struct inode *inode, loff_t size)
> > @@ -220,6 +225,62 @@ out:
> > return err;
> > }
> >
> > +/*
> > + * Preallocate space for a file. This implements fat's fallocate file
> > + * operation, which gets called from sys_fallocate system call. User
> > + * space requests len bytes at offset. If FALLOC_FL_KEEP_SIZE is set
> > + * we just allocate clusters without zeroing them out. Otherwise we
> > + * allocate and zero out clusters via an expanding truncate.
> > + */
> > +static long fat_fallocate(struct file *file, int mode,
> > + loff_t offset, loff_t len)
> > +{
> > + int nr_cluster; /* Number of clusters to be allocated */
> > + loff_t mm_bytes; /* Number of bytes to be allocated for file */
> > + loff_t ondisksize; /* block aligned on-disk size in bytes*/
> > + struct inode *inode = file->f_mapping->host;
> > + struct super_block *sb = inode->i_sb;
> > + struct msdos_sb_info *sbi = MSDOS_SB(sb);
> > + int err = 0;
> > +
> > + /* No support for hole punch or other fallocate flags. */
> > + if (mode & ~FALLOC_FL_KEEP_SIZE)
> > + return -EOPNOTSUPP;
> > +
> > + /* No support for dir */
> > + if (!S_ISREG(inode->i_mode))
> > + return -EOPNOTSUPP;
> > +
> > + mutex_lock(&inode->i_mutex);
> > + if (mode & FALLOC_FL_KEEP_SIZE) {
> > + ondisksize = inode->i_blocks << 9;
> > + if ((offset + len) <= ondisksize)
> > + goto error;
> > +
> > + /* First compute the number of clusters to be allocated */
> > + mm_bytes = offset + len - ondisksize;
> > + nr_cluster = (mm_bytes + (sbi->cluster_size - 1)) >>
> > + sbi->cluster_bits;
> > +
> > + /* Start the allocation.We are not zeroing out the clusters */
> > + while (nr_cluster-- > 0) {
> > + err = fat_add_cluster(inode);
> > + if (err)
> > + goto error;
> > + }
> > + } else {
> > + if ((offset + len) <= i_size_read(inode))
> > + goto error;
> > +
> > + /* This is just an expanding truncate */
> > + err = fat_cont_expand(inode, (offset + len));
> > + }
> > +
> > +error:
> > + mutex_unlock(&inode->i_mutex);
> > + return err;
> > +}
> > +
> > /* Free all clusters after the skip'th cluster. */
> > static int fat_free(struct inode *inode, int skip)
> > {
> > diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> > index 7b41a2d..1f9e4d9 100644
> > --- a/fs/fat/inode.c
> > +++ b/fs/fat/inode.c
> > @@ -101,7 +101,7 @@ static struct fat_floppy_defaults {
> > },
> > };
> >
> > -static int fat_add_cluster(struct inode *inode)
> > +int fat_add_cluster(struct inode *inode)
> > {
> > int err, cluster;
> >
> > @@ -562,13 +562,43 @@ out:
> >
> > EXPORT_SYMBOL_GPL(fat_build_inode);
> >
> > +static int __fat_write_inode(struct inode *inode, int wait);
> > +
> > +static void fat_free_eofblocks(struct inode *inode)
> > +{
> > + /* Release unwritten fallocated blocks on inode eviction. */
> > + if ((inode->i_blocks << 9) >
> > + round_up(MSDOS_I(inode)->mmu_private,
> > + MSDOS_SB(inode->i_sb)->cluster_size)) {
> > + int err;
> > +
> > + fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
> > + /* Fallocate results in updating the i_start/iogstart
> > + * for the zero byte file. So, make it return to
> > + * original state during evict and commit it to avoid
> > + * any corruption on the next access to the cluster
> > + * chain for the file.
> > + */
> > + err = __fat_write_inode(inode, inode_needs_sync(inode));
> > + if (err) {
> > + fat_msg(inode->i_sb, KERN_WARNING, "Failed to "
> > + "update on disk inode for unused "
> > + "fallocated blocks, inode could be "
> > + "corrupted. Please run fsck");
> > + }
> > +
> > + }
> > +}
> > +
> > static void fat_evict_inode(struct inode *inode)
> > {
> > truncate_inode_pages_final(&inode->i_data);
> > if (!inode->i_nlink) {
> > inode->i_size = 0;
> > fat_truncate_blocks(inode, 0);
> > - }
> > + } else
> > + fat_free_eofblocks(inode);
> > +
> > invalidate_inode_buffers(inode);
> > clear_inode(inode);
> > fat_cache_inval_inode(inode);
> >
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v8 1/4] fat: add fat_fallocate operation
2014-12-10 10:42 ` Namjae Jeon
@ 2014-12-10 10:45 ` Christoph Hellwig
2014-12-10 12:10 ` Namjae Jeon
0 siblings, 1 reply; 5+ messages in thread
From: Christoph Hellwig @ 2014-12-10 10:45 UTC (permalink / raw)
To: Namjae Jeon
Cc: 'Luk?? Czerner', 'OGAWA Hirofumi',
'Andrew Morton', linux-fsdevel
On Wed, Dec 10, 2014 at 07:42:16PM +0900, Namjae Jeon wrote:
> User have to call fallocate again if opening file after close().
> And fallocate() will skip allocation if fallocated blocks is avaiable.
> Instead, It gurrantee to be available fallocated blocks between open
> and close(). And I updated such limitation of fat fallocate in
> Documentation.
Documentation doesn't help, this breaks application exposed semantics.
If you think there is a use case for non-persistant preallocations
please propose a new fallocate flag for it, or given the lack of use
case probably just add a fat specific ioctl instead.
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH v8 1/4] fat: add fat_fallocate operation
2014-12-10 10:45 ` Christoph Hellwig
@ 2014-12-10 12:10 ` Namjae Jeon
0 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2014-12-10 12:10 UTC (permalink / raw)
To: 'Christoph Hellwig'
Cc: 'Luk?? Czerner', 'OGAWA Hirofumi',
'Andrew Morton', linux-fsdevel
>
> On Wed, Dec 10, 2014 at 07:42:16PM +0900, Namjae Jeon wrote:
> > User have to call fallocate again if opening file after close().
> > And fallocate() will skip allocation if fallocated blocks is avaiable.
> > Instead, It gurrantee to be available fallocated blocks between open
> > and close(). And I updated such limitation of fat fallocate in
> > Documentation.
>
> Documentation doesn't help, this breaks application exposed semantics.
>
> If you think there is a use case for non-persistant preallocations
> please propose a new fallocate flag for it, or given the lack of use
> case probably just add a fat specific ioctl instead.
Hi Christoph,
Yes, There are use cases from me and samba team also.
And it is fat's specific limitation. so looks better to add ioctl.
Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-12-10 12:10 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-09 7:17 [PATCH v8 1/4] fat: add fat_fallocate operation Namjae Jeon
2014-12-09 14:21 ` Lukáš Czerner
2014-12-10 10:42 ` Namjae Jeon
2014-12-10 10:45 ` Christoph Hellwig
2014-12-10 12:10 ` Namjae Jeon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox