On Sunday, June 17, 2001 04:31:03 PM +0200 Stefan Traby <[EMAIL PROTECTED]>
wrote:
> Hi !
>
> I just found a single line with 1026 chars in syslog (I split it up here)
> Looks strange.
>
> Anyway, the filesystem seems fully ok, I do every night a full
> backup by rsync and there are no problems after that message
> occured.
>
> Jun 14 19:29:47 stefan kernel: vs-: reiserfs_get_block:
> [215 19151 0xaf5001 UNKNOWN] should not be found<4>vs-: reiserfs_get_block:
Probably nothing serious, these warning messages can be due to the way
holes are created when truncate is used to expand the file. If you are
using staroffice or vmware, you've probably hit this issue.
But before 2.4.6-pre3 and 2.4.5-ac10, there was a small memory leak
that could be triggered when you see these messages.
The good news is that I've been testing code that cleans up the
code to generate holes on expanding truncate. I've included it below
in case anyone wants to try a beta of it. I had originally written
code for truncate that properly adds indirect items, does tail
conversions etc to grow the file, but I was really unhappy with
the amount of duplication in function to reiserfs_get_block.
So, this is based on code from Viro to fix a similar issue on fat. It
more or less does a seek + empty write to the new file size for the
expanding truncate case. The only drawback is that it allocates a block
at the end of the file.
Anyway, this will not fix existing files (which you can safely continue
using), but it will prevent new files from generating the messages. This
is a beta only, feel free to wait for further testing before you apply.
-chris
--- 1.4/include/linux/fs.h Tue Jun 12 13:31:34 2001
+++ edited/include/linux/fs.h Mon Jun 18 00:21:16 2001
@@ -1316,6 +1316,9 @@
extern int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
extern int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
unsigned long *);
+
+int generic_cont_expand(struct inode *inode, loff_t size) ;
+
extern int block_sync_page(struct page *);
int generic_block_bmap(struct address_space *, long, get_block_t *);
--- 1.4/kernel/ksyms.c Mon Jun 11 15:15:27 2001
+++ edited/kernel/ksyms.c Sun Jun 17 22:56:05 2001
@@ -200,6 +200,7 @@
EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_prepare_write);
EXPORT_SYMBOL(block_sync_page);
+EXPORT_SYMBOL(generic_cont_expand);
EXPORT_SYMBOL(cont_prepare_write);
EXPORT_SYMBOL(generic_commit_write);
EXPORT_SYMBOL(block_truncate_page);
--- 1.4/fs/buffer.c Tue Jun 12 06:21:14 2001
+++ edited/fs/buffer.c Mon Jun 18 00:44:16 2001
@@ -1743,6 +1743,47 @@
return 0;
}
+int generic_cont_expand(struct inode *inode, loff_t size)
+{
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page;
+ unsigned long index, offset, limit;
+ int err;
+
+ limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+ if (limit != RLIM_INFINITY) {
+ if (size > limit) {
+ send_sig(SIGXFSZ, current, 0);
+ size = limit;
+ }
+ }
+ 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) {
+ char *p = page_address(page) ;
+ err = mapping->a_ops->commit_write(NULL, page, offset, offset);
+ }
+ UnlockPage(page);
+ page_cache_release(page);
+ if (err > 0)
+ err = 0;
+out:
+ return err;
+}
+
/*
* For moronic filesystems that do not allow holes in file.
* We may have to extend the file.
--- 1.2/fs/reiserfs/file.c Sat Apr 28 11:27:17 2001
+++ edited/fs/reiserfs/file.c Mon Jun 18 01:00:33 2001
@@ -116,6 +116,13 @@
if (inode_items_version(inode) == ITEM_VERSION_1 &&
attr->ia_size > MAX_NON_LFS)
return -EFBIG ;
+
+ /* fill in hole pointers in the expanding truncate case. */
+ if (attr->ia_size > inode->i_size) {
+ error = generic_cont_expand(inode, attr->ia_size) ;
+ if (error)
+ return error ;
+ }
}
error = inode_change_ok(inode, attr) ;
--- 1.4/fs/reiserfs/inode.c Wed Jun 13 14:38:36 2001
+++ edited/fs/reiserfs/inode.c Sun Jun 17 23:23:47 2001
@@ -1959,7 +1959,7 @@
/* we test for O_SYNC here so we can commit the transaction
** for any packed tails the file might have had
*/
- if (f->f_flags & O_SYNC) {
+ if (f && (f->f_flags & O_SYNC)) {
journal_begin(&th, inode->i_sb, 1) ;
reiserfs_prepare_for_journal(inode->i_sb,
SB_BUFFER_WITH_SB(inode->i_sb), 1) ;