From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 7/6] fat: Support a truncate() for expanding size
Date: Tue, 08 Nov 2005 02:46:11 +0900 [thread overview]
Message-ID: <87r79ss658.fsf_-_@devron.myhome.or.jp> (raw)
In-Reply-To: <87vez4s6b7.fsf_-_@devron.myhome.or.jp> (OGAWA Hirofumi's message of "Tue, 08 Nov 2005 02:42:36 +0900")
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;
}
}
_
next prev parent reply other threads:[~2005-11-07 17:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` OGAWA Hirofumi [this message]
2005-11-07 17:51 ` [PATCH 7/6] fat: Support a truncate() for expanding size 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87r79ss658.fsf_-_@devron.myhome.or.jp \
--to=hirofumi@mail.parknet.co.jp \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.