+ fs-introduce-write_begin-write_end-and-perform_write-aops.patch added to -mm tree
Subsystems (4)
The patch titled
fs: introduce write_begin, write_end, and perform_write aops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch
*** Remember to use Documentation/SubmitChecklist when testing your code ***
See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
------------------------------------------------------
Subject: fs: introduce write_begin, write_end, and perform_write aops
From: Nick Piggin <[email protected]>
These are intended to replace prepare_write and commit_write with more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (which prepare_write is unable to do).
---
Documentation/filesystems/Locking | 9 - Documentation/filesystems/vfs.txt | 45 +++++ drivers/block/loop.c | 75 +++----- fs/buffer.c | 198 +++++++++++++++++++---- fs/libfs.c | 44 +++++ fs/namei.c | 47 +---- fs/splice.c | 70 -------- include/linux/buffer_head.h | 10 + include/linux/fs.h | 30 +++ include/linux/pagemap.h | 2 mm/filemap.c | 238 ++++++++++++++++++++++++---- 11 files changed, 562 insertions(+), 206 deletions(-)
Documentation/filesystems/Locking renamed from Documentation/filesystems/Locking~fs-introduce-write_begin-write_end-and-perform_write-aops +6 -3
@@ -178,15 +178,18 @@ prototypes: locking rules: All except set_page_dirty may block - BKL PageLocked(page) + BKL PageLocked(page) i_sem writepage: no yes, unlocks (see below) readpage: no yes, unlocks sync_page: no maybe writepages: no set_page_dirty no no readpages: no -prepare_write: no yes -commit_write: no yes +prepare_write: no yes yes +commit_write: no yes yes +write_begin: no locks the page yes +write_end: no yes, unlocks yes +perform_write: no n/a yes bmap: yes invalidatepage: no yes releasepage: no yes
Documentation/filesystems/vfs.txt renamed from Documentation/filesystems/vfs.txt~fs-introduce-write_begin-write_end-and-perform_write-aops +45 -0
57 lines not on this page · raw message
drivers/block/loop.c renamed from drivers/block/loop.c~fs-introduce-write_begin-write_end-and-perform_write-aops +29 -46
127 lines not on this page · raw message
fs/buffer.c renamed from fs/buffer.c~fs-introduce-write_begin-write_end-and-perform_write-aops +166 -32
222 lines not on this page · raw message
fs/libfs.c renamed from fs/libfs.c~fs-introduce-write_begin-write_end-and-perform_write-aops +44 -0
62 lines not on this page · raw message
fs/namei.c renamed from fs/namei.c~fs-introduce-write_begin-write_end-and-perform_write-aops +12 -35
65 lines not on this page · raw message
fs/splice.c renamed from fs/splice.c~fs-introduce-write_begin-write_end-and-perform_write-aops +8 -62
99 lines not on this page · raw message
include/linux/buffer_head.h renamed from include/linux/buffer_head.h~fs-introduce-write_begin-write_end-and-perform_write-aops +10 -0
@@ -203,6 +203,16 @@ void block_invalidatepage(struct page *pint block_write_full_page (struct page *page,get_block_t *get_block,struct writeback_control *wbc);int block_read_full_page (struct page *,get_block_t *); +int block_write_begin (struct file *,struct address_space *, +loff_t ,unsigned ,unsigned , +struct page **,void **,get_block_t *); +int block_write_end (struct file *,struct address_space *, +loff_t ,unsigned ,unsigned , +struct page *,void *); +int generic_write_end (struct file *,struct address_space *, +loff_t ,unsigned ,unsigned , +struct page *,void *); +void page_zero_new_buffers (struct page *page,unsigned from,unsigned to);int block_prepare_write (struct page *,unsigned ,unsigned ,get_block_t *);int cont_prepare_write (struct page *,unsigned ,unsigned ,get_block_t *,loff_t *);
include/linux/fs.h renamed from include/linux/fs.h~fs-introduce-write_begin-write_end-and-perform_write-aops +29 -1
@@ -391,6 +391,8 @@ enum positive_aop_returns { AOP_TRUNCATED_PAGE = 0x80001, }; +#define AOP_FLAG_UNINTERRUPTIBLE 0x0001/* will not do a short write */ +/* * oh the beauties of C type declarations. */
@@ -410,7 +412,7 @@ size_t iov_iter_copy_from_user_atomic(stsize_t iov_iter_copy_from_user (struct page *page,struct iov_iter *i,unsigned long offset,size_t bytes);void iov_iter_advance (struct iov_iter *i,size_t bytes); -int iov_iter_fault_in_readable (struct iov_iter *i); +int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes);size_t iov_iter_single_seg_count (struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i,
@@ -451,6 +453,14 @@ struct address_space_operations {*/ int (*prepare_write)(struct file *,struct page *,unsigned ,unsigned );int (*commit_write)(struct file *,struct page *,unsigned ,unsigned ); + +int (*write_begin)(struct file *,struct address_space *mapping, +loff_t pos,unsigned len,unsigned flags, +struct page **pagep,void **fsdata); +int (*write_end)(struct file *,struct address_space *mapping, +loff_t pos,unsigned len,unsigned copied, +struct page *page,void *fsdata); +/* Unfortunately this kludge is needed for FIBMAP. Don't use it */ sector_t (*bmap)(struct address_space *,sector_t );void (*invalidatepage) (struct page *,unsigned long );
@@ -465,6 +475,18 @@ struct address_space_operations {int (*launder_page) (struct page *); }; +/* +* pagecache_write_begin/pagecache_write_end must be used by general code +* to write into the pagecache. +*/ +int pagecache_write_begin (struct file *,struct address_space *mapping, +loff_t pos,unsigned len,unsigned flags, +struct page **pagep,void **fsdata); + +int pagecache_write_end (struct file *,struct address_space *mapping, +loff_t pos,unsigned len,unsigned copied, +struct page *page,void *fsdata); +struct backing_dev_info ;struct address_space {struct inode *host;/* owner: inode, block_device */
@@ -1920,6 +1942,12 @@ extern int simple_prepare_write(struct f unsigned offset, unsigned to);extern int simple_commit_write (struct file *file,struct page *page,unsigned offset,unsigned to); +extern int simple_write_begin (struct file *file,struct address_space *mapping, +loff_t pos,unsigned len,unsigned flags, +struct page **pagep,void **fsdata); +extern int simple_write_end (struct file *file,struct address_space *mapping, +loff_t pos,unsigned len,unsigned copied, +struct page *page,void *fsdata);extern struct dentry *simple_lookup (struct inode *,struct dentry *,struct nameidata *);extern ssize_t generic_read_dir (struct file *,char __user *,size_t ,loff_t *);
include/linux/pagemap.h renamed from include/linux/pagemap.h~fs-introduce-write_begin-write_end-and-perform_write-aops +2 -0
@@ -96,6 +96,8 @@ unsigned find_get_pages_contig(struct adunsigned find_get_pages_tag (struct address_space *mapping,pgoff_t *index,int tag,unsigned int nr_pages,struct page **pages); +struct page *__grab_cache_page (struct address_space *mapping,pgoff_t index); +/* * Returns locked page at given index in given cache, creating it if needed. */
mm/filemap.c renamed from mm/filemap.c~fs-introduce-write_begin-write_end-and-perform_write-aops +211 -27
313 lines not on this page · raw message
_
Patches currently in -mm which might be from [email protected] are
mm-fix-fault-vs-invalidate-race-for-linear-mappings.patch mm-fix-fault-vs-invalidate-race-for-linear-mappings-fix.patch mm-merge-populate-and-nopage-into-fault-fixes-nonlinear.patch mm-merge-nopfn-into-fault.patch
mm-remove-legacy-cruft.patch mm-debug-check-for-the-fault-vs-invalidate-race.patch mm-fix-clear_page_dirty_for_io-vs-fault-race.patch
git-arm-master.patch
slob-rework-freelist-handling.patch
slob-remove-bigblock-tracking.patch slob-improved-alignment-handling.patch mm-revert-kernel_ds-buffered-write-optimisation.patch revert-81b0c8713385ce1b1b9058e916edcf9561ad76d6.patch revert-6527c2bdf1f833cc18e8f42bd97973d583e4aa83.patch mm-clean-up-buffered-write-code.patch
mm-debug-write-deadlocks.patch
mm-trim-more-holes.patch
mm-buffered-write-cleanup.patch
mm-write-iovec-cleanup.patch
mm-fix-pagecache-write-deadlocks.patch
mm-buffered-write-iterator.patch
fs-fix-data-loss-on-error.patch fs-introduce-write_begin-write_end-and-perform_write-aops.patch mm-restore-kernel_ds-optimisations.patch
implement-simple-fs-aops.patch
block_dev-convert-to-new-aops.patch
ext2-convert-to-new-aops.patch
ext3-convert-to-new-aops.patch
ext4-convert-to-new-aops.patch
xfs-convert-to-new-aops.patch
fs-new-cont-helpers.patch
fat-convert-to-new-aops.patch
hfs-convert-to-new-aops.patch
hfsplus-convert-to-new-aops.patch
hpfs-convert-to-new-aops.patch
bfs-convert-to-new-aops.patch
qnx4-convert-to-new-aops.patch
reiserfs-use-generic-write.patch
reiserfs-convert-to-new-aops.patch reiserfs-use-generic_cont_expand_simple.patch with-reiserfs-no-longer-using-the-weird-generic_cont_expand-remove-it-completely.patch nfs-convert-to-new-aops.patch
smb-convert-to-new-aops.patch
fuse-convert-to-new-aops.patch
hostfs-convert-to-new-aops.patch
jffs2-convert-to-new-aops.patch
ufs-convert-to-new-aops.patch
udf-convert-to-new-aops.patch
sysv-convert-to-new-aops.patch
minix-convert-to-new-aops.patch
jfs-convert-to-new-aops.patch
mm-document-fault_data-and-flags.patch fs-introduce-some-page-buffer-invariants.patch fs-introduce-write_begin-write_end-and-perform_write-aops-revoke.patch
Quoted 11 lines · Andrew Morton
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
Quoted 7 lines
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).
OK, well now Andrew's merged a significant chunk of this work, I would like to try getting the clustered filesystem patches back in too (Steven, the last GFS2 patch you sent had rejects against this tree, so I dropped it... hope it isn't too much work to bring it back uptodate?).
The cluster filesystems aren't 100% happy with the backward-compat code, because pagecache_write_end cannot handle AOP_TRUNCATED_PAGE from ->commit_write... so if you were to try using loop over GFS2, it might go BUG. This is a bit bad of me, however the compat code would have been a whole lot uglier to support that, and I figure the cluster filesystems want to convert to the new aops ASAP anyway.
I doubt anybody but the filesystem developers would be using -mm in such a way, but even so I hope we can fix this before long.
Meanwhile, I'll look at redoing the rest of the filesystems that got left behind.
Andrew Morton
maintainerQuoted 33 lines · On Wed, 30 May 2007 05:13:54 +0200 Nick Piggin <[email protected]> wrote:
Quoted 11 lines · Andrew Morton
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
Quoted 7 lines
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).OK, well now Andrew's merged a significant chunk of this work, I would like to try getting the clustered filesystem patches back in too (Steven, the last GFS2 patch you sent had rejects against this tree, so I dropped it... hope it isn't too much work to bring it back uptodate?).
The cluster filesystems aren't 100% happy with the backward-compat code, because
pagecache_write_endcannot handleAOP_TRUNCATED_PAGEfrom ->commit_write... so if you were to try using loop over GFS2, it might go BUG. This is a bit bad of me, however the compat code would have been a whole lot uglier to support that, and I figure the cluster filesystems want to convert to the new aops ASAP anyway.
Quoted 5 lines
I doubt anybody but the filesystem developers would be using -mm in such a way, but even so I hope we can fix this before long.
Meanwhile, I'll look at redoing the rest of the filesystems that got left behind.
hm, I suppose that means I need to undrop git-ocfs2.patch. It has a mild disagreeement with the fault-vs-invalidate patches which I didn't feel like fixing.
Quoted 3 lines · Andrew Morton
hm, I suppose that means I need to undrop git-ocfs2.patch. It has a mild disagreeement with the fault-vs-invalidate patches which I didn't feel like fixing.
Erf, somehow I missed that it was dropped. I guess I'll take a look...
--Mark
--
Mark Fasheh
Senior Software Developer, Oracle
[email protected]
Andrew Morton
maintainerQuoted 6 lines · On Wed, 30 May 2007 15:44:43 -0700 Mark Fasheh <[email protected]> wrote:
Quoted 3 lines · Andrew Morton
hm, I suppose that means I need to undrop git-ocfs2.patch. It has a mild disagreeement with the fault-vs-invalidate patches which I didn't feel like fixing.
Erf, somehow I missed that it was dropped.
I didn't tell you ;)
Quoted 1 line
I guess I'll take a look...
It's the sort of mm-vs-mm thing which I get to fix, only I've been putting it off. As it now looks like the fault patches are moing away from death's door, I shall do that.
Hi,
Quoted 20 lines · Nick Piggin
Quoted 11 lines · Andrew Morton
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
Quoted 7 lines
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).
Quoted 6 lines
OK, well now Andrew's merged a significant chunk of this work, I would like to try getting the clustered filesystem patches back in too (Steven, the last GFS2 patch you sent had rejects against this tree, so I dropped it... hope it isn't too much work to bring it back uptodate?).
I think the following should do the trick... sorry for the delay, I was on holiday last week and I'm just catching up again. There is not a lot of change from the previous version, just a few small changes in the upstream code which had caused one chunk not to apply,
Steve.
---------------------------------------------------------------------------------
fs/gfs2/ops_address.c +128 -84
@@ -17,6 +17,7 @@#include <linux/mpage.h> #include <linux/fs.h> #include <linux/writeback.h> +#include <linux/swap.h> #include <linux/gfs2_ondisk.h> #include <linux/lm_interface.h>
@@ -349,45 +350,49 @@ out_unlock: }/** -* gfs2_prepare_write - Prepare to write a page to a file +* gfs2_write_begin - Begin to write to a file * @file: The file to write to -* @page: The page which is to be prepared for writing -* @from: From (byte range within page) -* @to: To (byte range within page) +* @mapping: The mapping in which to write +* @pos: The file offset at which to start writing +* @len: Length of the write +* @flags: Various flags +* @pagep: Pointer to return the page +* @fsdata: Pointer to return fs data (unused by GFS2) * * Returns: errno */ -static int gfs2_prepare_write (struct file *file,struct page *page, -unsigned from,unsigned to) +static int gfs2_write_begin (struct file *file,struct address_space *mapping, +loff_t pos,unsigned len,unsigned flags, +struct page **pagep,void **fsdata) { -struct gfs2_inode *ip =GFS2_I (page->mapping->host); -struct gfs2_sbd *sdp =GFS2_SB (page->mapping->host); +struct gfs2_inode *ip =GFS2_I (mapping->host); +struct gfs2_sbd *sdp =GFS2_SB (mapping->host);unsigned int data_blocks, ind_blocks, rblocks;int alloc_required;int error =0 ; -loff_t pos = ((loff_t )page->index <<PAGE_CACHE_SHIFT ) + from; -loff_t end = ((loff_t )page->index <<PAGE_CACHE_SHIFT ) + to;struct gfs2_alloc *al; -unsigned int write_len = to - from; +pgoff_t index = pos >>PAGE_CACHE_SHIFT ; +unsigned from = pos & (PAGE_CACHE_SIZE -1 ); +unsigned to = from + len; +struct page *page; - -gfs2_holder_init (ip->i_gl,LM_ST_EXCLUSIVE ,GL_ATIME |LM_FLAG_TRY_1CB , &ip->i_gh); +gfs2_holder_init (ip->i_gl,LM_ST_EXCLUSIVE ,GL_ATIME , &ip->i_gh); error =gfs2_glock_nq_atime (&ip->i_gh); -if (unlikely (error)) { -if (error ==GLR_TRYFAILED ) { -unlock_page (page); - error =AOP_TRUNCATED_PAGE ; -yield (); - } +if (unlikely (error)) goto out_uninit; - } -gfs2_write_calc_reserv (ip, write_len, &data_blocks, &ind_blocks); + error = -ENOMEM ; + page =__grab_cache_page (mapping, index); + *pagep = page; +if (!page) + goto out_unlock; + +gfs2_write_calc_reserv (ip, len, &data_blocks, &ind_blocks); - error =gfs2_write_alloc_required (ip, pos, write_len, &alloc_required); + error =gfs2_write_alloc_required (ip, pos, len, &alloc_required);if (error) - goto out_unlock; + goto out_putpage; ip->i_alloc.al_requested =0 ;
@@ -419,7 +424,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, goto out;if (gfs2_is_stuffed (ip)) { -if (end > sdp->sd_sb.sb_bsize -sizeof (struct gfs2_dinode )) { +if (pos + len > sdp->sd_sb.sb_bsize -sizeof (struct gfs2_dinode )) { error =gfs2_unstuff_dinode (ip, page);if (error ==0 ) goto prepare_write;
@@ -441,6 +446,10 @@ out_qunlock: out_alloc_put:gfs2_alloc_put (ip); } +out_putpage: +page_cache_release (page); +if (pos + len > ip->i_inode.i_size) +vmtruncate (&ip->i_inode, ip->i_inode.i_size); out_unlock:gfs2_glock_dq_m (1 , &ip->i_gh); out_uninit:
@@ -476,65 +485,118 @@ static void adjust_fs_space(struct inode *inode) }/** -* gfs2_commit_write - Commit write to a file +* gfs2_stuffed_write_end - Write end for stuffed files +* @inode: The inode +* @dibh: The buffer_head containing the on-disk inode +* @pos: The file position +* @len: The length of the write +* @copied: How much was actually copied by the VFS +* @page: The page +* +* This copies the data from the page into the inode block after +* the inode data structure itself. +* +* Returns: errno +*/ +static int gfs2_stuffed_write_end (struct inode *inode,struct buffer_head *dibh, +loff_t pos,unsigned len,unsigned copied, +struct page *page) +{ +struct gfs2_inode *ip =GFS2_I (inode); +struct gfs2_sbd *sdp =GFS2_SB (inode); +u64 to = pos + copied; +void *kaddr; +unsigned char *buf = dibh->b_data +sizeof (struct gfs2_dinode ); +struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; + +BUG_ON ((pos + len) > (dibh->b_size -sizeof (struct gfs2_dinode ))); + kaddr =kmap_atomic (page,KM_USER0 ); +memcpy (buf + pos, kaddr + pos, copied); +memset (kaddr + pos + copied,0 , len - copied); +flush_dcache_page (page); +kunmap_atomic (kaddr,KM_USER0 ); + +if (!PageUptodate (page)) +SetPageUptodate (page); +unlock_page (page); +mark_page_accessed (page); +page_cache_release (page); + +if (inode->i_size < to) { +i_size_write (inode, to); + ip->i_di.di_size = inode->i_size; + di->di_size =cpu_to_be64 (inode->i_size); +mark_inode_dirty (inode); + } + +if (inode == sdp->sd_rindex) +adjust_fs_space (inode); + +brelse (dibh); +gfs2_trans_end (sdp); +gfs2_glock_dq (&ip->i_gh); +gfs2_holder_uninit (&ip->i_gh); +return copied; +} + +/** +* gfs2_write_end * @file: The file to write to -* @page: The page containing the data -* @from: From (byte range within page) -* @to: To (byte range within page) +* @mapping: The address space to write to +* @pos: The file position +* @len: The length of the data +* @copied: +* @page: The page that has been written +* @fsdata: The fsdata (unused in GFS2) +* +* The main write_end function for GFS2. We have a separate one for +* stuffed files as they are slightly different, otherwise we just +* put our locking around the VFS provided functions. * * Returns: errno */ -static int gfs2_commit_write (struct file *file,struct page *page, -unsigned from,unsigned to) +static int gfs2_write_end (struct file *file,struct address_space *mapping, +loff_t pos,unsigned len,unsigned copied, +struct page *page,void *fsdata) {struct inode *inode = page->mapping->host;struct gfs2_inode *ip =GFS2_I (inode);struct gfs2_sbd *sdp =GFS2_SB (inode); -int error = -EOPNOTSUPP ;struct buffer_head *dibh;struct gfs2_alloc *al = &ip->i_alloc;struct gfs2_dinode *di; +unsigned int from = pos & (PAGE_CACHE_SIZE -1 ); +unsigned int to = from + len; +int ret; -if (gfs2_assert_withdraw (sdp,gfs2_glock_is_locked_by_me (ip->i_gl))) - goto fail_nounlock; +BUG_ON (gfs2_glock_is_locked_by_me (ip->i_gl) ==0 ); - error =gfs2_meta_inode_buffer (ip, &dibh); -if (error) - goto fail_endtrans; + ret =gfs2_meta_inode_buffer (ip, &dibh); +if (unlikely (ret)) { +unlock_page (page); +page_cache_release (page); + goto failed; + }gfs2_trans_add_bh (ip->i_gl, dibh,1 ); - di = (struct gfs2_dinode *)dibh->b_data; -if (gfs2_is_stuffed (ip)) { -u64 file_size; -void *kaddr; +if (gfs2_is_stuffed (ip)) +return gfs2_stuffed_write_end (inode, dibh, pos, len, copied, page); - file_size = ((u64 )page->index <<PAGE_CACHE_SHIFT ) + to; +if (sdp->sd_args.ar_data ==GFS2_DATA_ORDERED ||gfs2_is_jdata (ip)) +gfs2_page_add_databufs (ip, page, from, to); - kaddr =kmap_atomic (page,KM_USER0 ); -memcpy (dibh->b_data +sizeof (struct gfs2_dinode ) + from, - kaddr + from, to - from); -kunmap_atomic (kaddr,KM_USER0 ); + ret =generic_write_end (file, mapping, pos, len, copied, page, fsdata); -SetPageUptodate (page); - -if (inode->i_size < file_size) { -i_size_write (inode, file_size); +if (likely (ret >=0 )) { + copied = ret; +if ((pos + copied) > inode->i_size) { + di = (struct gfs2_dinode *)dibh->b_data; + ip->i_di.di_size = inode->i_size; + di->di_size =cpu_to_be64 (inode->i_size);mark_inode_dirty (inode); } - }else { -if (sdp->sd_args.ar_data ==GFS2_DATA_ORDERED || -gfs2_is_jdata (ip)) -gfs2_page_add_databufs (ip, page, from, to); - error =generic_commit_write (file, page, from, to); -if (error) - goto fail; - } - -if (ip->i_di.di_size < inode->i_size) { - ip->i_di.di_size = inode->i_size; - di->di_size =cpu_to_be64 (inode->i_size); }if (inode == sdp->sd_rindex)
@@ -542,33 +604,15 @@ static int gfs2_commit_write(struct file *file, struct page *page,brelse (dibh);gfs2_trans_end (sdp); +failed:if (al->al_requested) {gfs2_inplace_release (ip);gfs2_quota_unlock (ip);gfs2_alloc_put (ip); } -unlock_page (page); -gfs2_glock_dq_m (1 , &ip->i_gh); -lock_page (page); +gfs2_glock_dq (&ip->i_gh);gfs2_holder_uninit (&ip->i_gh); -return 0 ; - -fail: -brelse (dibh); -fail_endtrans: -gfs2_trans_end (sdp); -if (al->al_requested) { -gfs2_inplace_release (ip); -gfs2_quota_unlock (ip); -gfs2_alloc_put (ip); - } -unlock_page (page); -gfs2_glock_dq_m (1 , &ip->i_gh); -lock_page (page); -gfs2_holder_uninit (&ip->i_gh); -fail_nounlock: -ClearPageUptodate (page); -return error; +return ret; }/**
@@ -837,8 +881,8 @@ const struct address_space_operations gfs2_file_aops = { .readpage = gfs2_readpage, .readpages = gfs2_readpages, .sync_page = block_sync_page, - .prepare_write = gfs2_prepare_write, - .commit_write = gfs2_commit_write, + .write_begin = gfs2_write_begin, + .write_end = gfs2_write_end, .bmap = gfs2_bmap, .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage,
Quoted 29 lines · Steven Whitehouse
Hi,
Quoted 20 lines · Nick Piggin
Quoted 11 lines · Andrew Morton
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
Quoted 7 lines
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).Quoted 6 lines
OK, well now Andrew's merged a significant chunk of this work, I would like to try getting the clustered filesystem patches back in too (Steven, the last GFS2 patch you sent had rejects against this tree, so I dropped it... hope it isn't too much work to bring it back uptodate?).
Quoted 4 lines
I think the following should do the trick... sorry for the delay, I was on holiday last week and I'm just catching up again. There is not a lot of change from the previous version, just a few small changes in the upstream code which had caused one chunk not to apply,
OK thanks! I'll send this to Andrew after he releases the next -mm and hopefully picks up the patchset again.
Quoted 15 lines · On 14:19 Втр 29 Май , [email protected] wrote:
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>
Quoted 8 lines
These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).[[email protected]: API design contributions, code review and fixes]Signed-off-by Nick Piggin <[email protected]>Signed-off-by Mark Fasheh <[email protected]>Signed-off-by Andrew Morton <[email protected]>
I've finaly find time to review Nick's "write_begin/write_end aop" patch set. And i have some fixes and questions. My be i've missed somthing and it was already disscussed, but i cant find in LKML.
1) loop dev:
loop.c code itself is not perfect. In fact before Nick's patch partial write was't possible. Assumption what write chunks are always page aligned is realy weird ( see "index++" line). Fixed by "new aop loop fix" patch
2)block_write_begin:
After we enter to block_write_begin with *pagep == NULL and
some page was grabed we remember this page in *pagep
And if __block_prepare_write() we have to clear *pagep , as
it was before. Because this may confuse caller.
for example caller may have folowing code:
ret = block_write_begin(..., pagep,...)
if (ret && *pagep != NULL) {
unlock_page(*pagep);
page_cache_release(*pagep);
}
Fixed my "new aop block_write_begin fix" patch3) __page_symlink:
Nick's patch add folowing code:
+ err = pagecache_write_begin(NULL, mapping, 0,PAGE_CACHE_SIZE,
+ AOP_FLAG_UNINTERRUPTIBLE, &page,&fsdata);
symlink now consume whole page. I have only one question "WHY???". I don't see any advantages, but where are huge list of dissdvantages:
a) fs with blksize == 1k and pagesize == 16k after this patch waste more than 10x times disk space for nothing.
b) What happends if we want use fs with blksize == 4k on i386 after it was used by ia64 ??? (before this patch it was possible).
I dont prepare patch for this because i dont understand issue witch Nick aimed to fix.
4) iov_iter_fault_in_readable:
Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :) :
writev(3, [{"\1", 1}, {"\2"..., 4096}], 2) = -1 EFAULT (Bad address) this hidden bug, and it was invisiable because XXXX_fault_in_readable return value was ignored before. Lets iov_iter_fault_in_readable perform checks for all segments.
Fixed by :"iov_iter_fault_in_readable fix"
5) ext3_write_end:
Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
PATCH 1/1 new aop block_write_begin fix
After we enter to block_write_begin with *pagep == NULL and
some page was grabed we remember this page in *pagep And if __block_prepare_write() we have to clear *pagep , as it was before. Because this may confuse caller. for example caller may have folowing code:
ret = block_write_begin(..., pagep,...) if (ret && *pagep != NULL) {
unlock_page(*pagep); page_cache_release(*pagep);
}
fs/buffer.c +1 -0
@@ -1982,6 +1982,7 @@ int block_write_begin(struct file *file, struct address_space *mapping,if (ownpage) {unlock_page (page);page_cache_release (page); + *pagep =NULL ;/* * prepare_write() may have instantiated a few blocks
iov_iter_fault_in_readable fix
In reply to Dmitriy MonakhovFunction prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :)
/* TESTCASE BEGIN */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/mman.h>
#define SIZE (4096 * 2)
int main(int argc, char* argv[])
{
char* ptr[4];
struct iovec iov[2];
int fd, ret;
ptr[0] = mmap(NULL, SIZE, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
ptr[1] = mmap(NULL, SIZE, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
ptr[2] = mmap(NULL, SIZE, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
ptr[3] = mmap(NULL, SIZE, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
iov[0].iov_base = ptr[0] + (SIZE -1);
iov[0].iov_len = 1;
memset(ptr[0], 1, SIZE);
iov[1].iov_base = ptr[2];
iov[1].iov_len = SIZE;
memset(ptr[2], 2, SIZE);
fd = open(argv[1], O_CREAT|O_RDWR|O_TRUNC, 0666);
ret = writev(fd, iov, sizeof(iov) / sizeof(struct iovec));
return 0;
}
/* TESTCASE END*/
We will get folowing result:
writev(3, [{"\1", 1}, {"\2"..., 8192}], 2) = -1 EFAULT (Bad address)
this is hidden bug, and it was invisiable because XXXX_fault_in_readable return value was ignored before. Lets iov_iter_fault_in_readable perform checks for all segments.
include/linux/fs.h +1 -1
@@ -433,7 +433,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,size_t iov_iter_copy_from_user (struct page *page,struct iov_iter *i,unsigned long offset,size_t bytes);void iov_iter_advance (struct iov_iter *i,size_t bytes); -int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes); +int iov_iter_fault_in_readable (struct iov_iter *i,size_t *bytes);size_t iov_iter_single_seg_count (struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i,
mm/filemap.c +27 -5
@@ -1817,10 +1817,32 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) }EXPORT_SYMBOL (iov_iter_advance); -int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes) +int iov_iter_fault_in_readable (struct iov_iter *i,size_t * bytes) { -char __user *buf = i->iov->iov_base + i->iov_offset; -return fault_in_pages_readable (buf, bytes); +size_t len = *bytes; +int ret; +if (likely (i->nr_segs ==1 )) { + ret =fault_in_pages_readable (i->iov->iov_base, len); +if (ret) + *bytes =0 ; + }else { +const struct iovec *iov = i->iov; +size_t base = i->iov_offset; + *bytes =0 ; +while (len) { +int copy =min (len, iov->iov_len - base); +if ((ret =fault_in_pages_readable (iov->iov_base + base, copy))) +break ; + *bytes += copy; + len -= copy; + base += copy; +if (iov->iov_len == base) { + iov++; + base =0 ; + } + } + } +return ret; }EXPORT_SYMBOL (iov_iter_fault_in_readable);
@@ -2110,7 +2132,7 @@ static ssize_t generic_perform_write_2copy(struct file *file,* to check that the address is actually valid, when atomic * usercopies are used, below. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (iov_iter_fault_in_readable (i, &bytes) && !bytes)) { status = -EFAULT ;break ; }
@@ -2284,7 +2306,7 @@ again:* to check that the address is actually valid, when atomic * usercopies are used, below. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (iov_iter_fault_in_readable (i, &bytes)&& !bytes)) { status = -EFAULT ;break ; }
Re: iov_iter_fault_in_readable fix
Review
Quoted 2 lines · Dmitriy Monakhov
(quoted diff) +0
-0Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :)
Btw, could someone please start to collect all sniplets like this in a nice simple regression test suite? If no one wants to start a new one we should probably just put it into xfsqa (which should be useable for other filesystems aswell despite the name)
Quoted 119 lines
/* TESTCASE BEGIN */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/uio.h> #include <sys/mman.h> #define SIZE (4096 * 2) int main(int argc, char* argv[]) { char* ptr[4]; struct iovec iov[2]; int fd, ret; ptr[0] = mmap(NULL, SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); ptr[1] = mmap(NULL, SIZE, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); ptr[2] = mmap(NULL, SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); ptr[3] = mmap(NULL, SIZE, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); iov[0].iov_base = ptr[0] + (SIZE -1); iov[0].iov_len = 1; memset(ptr[0], 1, SIZE); iov[1].iov_base = ptr[2]; iov[1].iov_len = SIZE; memset(ptr[2], 2, SIZE); fd = open(argv[1], O_CREAT|O_RDWR|O_TRUNC, 0666); ret = writev(fd, iov, sizeof(iov) / sizeof(struct iovec)); return 0; } /* TESTCASE END*/ We will get folowing result: writev(3, [{"\1", 1}, {"\2"..., 8192}], 2) = -1 EFAULT (Bad address) this is hidden bug, and it was invisiable because XXXX_fault_in_readable(quoted diff) +0
-0return value was ignored before. Lets iov_iter_fault_in_readable perform checks for all segments.Signed-off-by Dmitriy Monakhov <[email protected]>include/linux/fs.h +1
-1@@ -433,7 +433,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,size_t iov_iter_copy_from_user (struct page *page,struct iov_iter *i,unsigned long offset,size_t bytes);void iov_iter_advance (struct iov_iter *i,size_t bytes); -int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes); +int iov_iter_fault_in_readable (struct iov_iter *i,size_t *bytes);size_t iov_iter_single_seg_count (struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i,mm/filemap.c +27
-6@@ -1817,10 +1817,32 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) }EXPORT_SYMBOL (iov_iter_advance); -int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes) +int iov_iter_fault_in_readable (struct iov_iter *i,size_t * bytes) { -char __user *buf = i->iov->iov_base + i->iov_offset; -return fault_in_pages_readable (buf, bytes); +size_t len = *bytes; +int ret; +if (likely (i->nr_segs ==1 )) { + ret =fault_in_pages_readable (i->iov->iov_base, len); +if (ret) + *bytes =0 ; + }else { +const struct iovec *iov = i->iov; +size_t base = i->iov_offset; + *bytes =0 ; +while (len) { +int copy =min (len, iov->iov_len - base); +if ((ret =fault_in_pages_readable (iov->iov_base + base, copy))) +break ; + *bytes += copy; + len -= copy; + base += copy; +if (iov->iov_len == base) { + iov++; + base =0 ; + } + } + } +return ret; }EXPORT_SYMBOL (iov_iter_fault_in_readable);@@ -2110,7 +2132,7 @@ static ssize_t generic_perform_write_2copy(struct file *file,* to check that the address is actually valid, when atomic * usercopies are used, below. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (iov_iter_fault_in_readable (i, &bytes) && !bytes)) { status = -EFAULT ;break ; }@@ -2284,7 +2306,7 @@ again:* to check that the address is actually valid, when atomic * usercopies are used, below. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (iov_iter_fault_in_readable (i, &bytes)&& !bytes)) { status = -EFAULT ;break ; } -
Quoted 4 lines
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
---end quoted text---
Re: iov_iter_fault_in_readable fix
Quoted 8 lines · Christoph Hellwig
Review
Quoted 2 lines · Dmitriy Monakhov
(quoted diff) +0
-0Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :)Btw, could someone please start to collect all sniplets like this in a nice simple regression test suite? If no one wants to start a new one we should probably just put it into xfsqa (which should be useable for other filesystems aswell despite the name)
Yeah, it can run a subset of the tests on NFS and UDF filesystems as well and there are some specific UDF-only tests in it too. I think the NFS test group is mostly generic tests that don't use or test specific XFS features.
I'd be happy to accumulate tests like these in xfsqa...
Cheers,
Dave.
Signature · 3 lines
Dave Chinner Principal Engineer SGI Australian Software Group
Re: iov_iter_fault_in_readable fix
Quoted 3 lines · David Chinner
Yeah, it can run a subset of the tests on NFS and UDF filesystems as well and there are some specific UDF-only tests in it too. I think the NFS test group is mostly generic tests that don't use or test specific XFS features.
Actually most testcases can run on any reasonable posixish filesystem, we just need some glue to tell the testsuite it's actually okay.
Re: iov_iter_fault_in_readable fix
In reply to Christoph HellwigQuoted 8 lines · Christoph Hellwig
Review
Quoted 2 lines · Dmitriy Monakhov
(quoted diff) +0
-0Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :)Btw, could someone please start to collect all sniplets like this in a nice simple regression test suite? If no one wants to start a new one we should probably just put it into xfsqa (which should be useable for other filesystems aswell despite the name)
I've prepared testcase (testcases/kernel/syscalls/writev/writev06.c) and sent it to ltp mailing list.
Quoted 20 lines · Dmitriy Monakhov
Quoted 19 lines · On 14:19 ?????? 29 ?????? , [email protected] wrote:
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).
Quoted 7 lines
Quoted 4 lines
[[email protected]: API design contributions, code review and fixes]Signed-off-by Nick Piggin <[email protected]>Signed-off-by Mark Fasheh <[email protected]>Signed-off-by Andrew Morton <[email protected]>I've finaly find time to review Nick's "write_begin/write_end aop" patch set. And i have some fixes and questions. My be i've missed somthing and it was already disscussed, but i cant find in LKML.
Thanks, that's really helpful.
Quoted 5 lines
1) loop dev:
loop.ccode itself is not perfect. In fact before Nick's patch partial write was't possible. Assumption what write chunks are always page aligned is realy weird ( see "index++" line). Fixed by "new aop loop fix" patch
I think you're right, fix looks good.
Quoted 12 lines
2)block_write_begin:
After we enter to block_write_begin with *pagep == NULL and some page was grabed we remember this page in *pagep And if __block_prepare_write() we have to clear *pagep , as it was before. Because this may confuse caller. for example caller may have folowing code: ret = block_write_begin(..., pagep,...) if (ret && *pagep != NULL) { unlock_page(*pagep); page_cache_release(*pagep); } Fixed my "new aop block_write_begin fix" patch
I don't think the caller can rely on that if it returns failure. But that is more defensive I guess. Maybe setting it to 1 or so would catch abusers.
Quoted 13 lines
3)
__page_symlink:
Nick's patch add folowing code:
+ err = pagecache_write_begin(NULL, mapping, 0,PAGE_CACHE_SIZE,
+AOP_FLAG_UNINTERRUPTIBLE, &page,&fsdata);
symlink now consume whole page. I have only one question "WHY???". I don't see any advantages, but where are huge list of dissdvantages:
a) fs with blksize == 1k and pagesize == 16k after this patch waste more than 10x times disk space for nothing.
b) What happends if we want use fs with blksize == 4k on i386 after it was used by ia64 ??? (before this patch it was possible).
Quoted 2 lines
I dont prepare patch for this because i dont understand issue witch Nick aimed to fix.
I don't know why myself :P I think it would be just fine to use len-1 as it did previously, so it must have been a typo?
Quoted 8 lines
4)
iov_iter_fault_in_readable:
Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :) :
writev(3, [{"\1", 1}, {"\2"..., 4096}], 2)= -1 EFAULT (Bad address) this hidden bug, and it was invisiable becauseXXXX_fault_in_readablereturn value was ignored before. Letsiov_iter_fault_in_readableperform checks for all segments.
Fixed by :"iov_iter_fault_in_readable fix"
OK thanks. I would rather just change this to use the length of the first iovec always (prefaulting multiple iovecs would have to be benchmarked on real apps that make heavy use of writev, I suspect).
Quoted 10 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
Quoted 54 lines · Nick Piggin
Quoted 20 lines · Dmitriy Monakhov
Quoted 19 lines · On 14:19 ?????? 29 ?????? , [email protected] wrote:
The patch titled
fs: introducewrite_begin,write_end, andperform_writeaops
has been added to the -mm tree. Its filename is
fs-introduce-write_begin-write_end-and-perform_write-aops.patch*** Remember to use
Documentation/SubmitChecklistwhen testing your code ***See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this
------------------------------------------------------
Subject: fs: introducewrite_begin,write_end, andperform_writeaops
From: Nick Piggin <[email protected]>These are intended to replace
prepare_writeandcommit_writewith more flexible alternatives that are also able to avoid the buffered write deadlock problems efficiently (whichprepare_writeis unable to do).Quoted 7 lines
Quoted 4 lines
[[email protected]: API design contributions, code review and fixes]Signed-off-by Nick Piggin <[email protected]>Signed-off-by Mark Fasheh <[email protected]>Signed-off-by Andrew Morton <[email protected]>I've finaly find time to review Nick's "write_begin/write_end aop" patch set. And i have some fixes and questions. My be i've missed somthing and it was already disscussed, but i cant find in LKML.
Thanks, that's really helpful.
Quoted 5 lines
1) loop dev:
loop.ccode itself is not perfect. In fact before Nick's patch partial write was't possible. Assumption what write chunks are always page aligned is realy weird ( see "index++" line). Fixed by "new aop loop fix" patchI think you're right, fix looks good.
Quoted 12 lines
2)block_write_begin:
After we enter to block_write_begin with *pagep == NULL and some page was grabed we remember this page in *pagep And if __block_prepare_write() we have to clear *pagep , as it was before. Because this may confuse caller. for example caller may have folowing code: ret = block_write_begin(..., pagep,...) if (ret && *pagep != NULL) { unlock_page(*pagep); page_cache_release(*pagep); } Fixed my "new aop block_write_begin fix" patch
Quoted 17 lines
I don't think the caller can rely on that if it returns failure. But that is more defensive I guess. Maybe setting it to 1 or so would catch abusers.
Quoted 12 lines
3)
__page_symlink:
Nick's patch add folowing code:
+ err = pagecache_write_begin(NULL, mapping, 0,PAGE_CACHE_SIZE,
+AOP_FLAG_UNINTERRUPTIBLE, &page,&fsdata);
symlink now consume whole page. I have only one question "WHY???". I don't see any advantages, but where are huge list of dissdvantages:
a) fs with blksize == 1k and pagesize == 16k after this patch waste more than 10x times disk space for nothing.
b) What happends if we want use fs with blksize == 4k on i386 after it was used by ia64 ??? (before this patch it was possible).
One more visiable effect caused by wrong symlink size:
fsstress cause folowing error:
<LOG BEGIN>
EXT3-fs unexpected failure: !buffer_revoked(bh); inconsistent data on diskext3_forget: aborting transaction: IO failure in __ext3_journal_revoke ext3_abort called.
EXT3-fs error (device dm-4): ext3_forget: error -5 when attempting revoke
Remounting filesystem read-only
Aborting journal on device dm-4.
journal commit I/O error
journal commit I/O error
journal commit I/O error
journal commit I/O error
journal commit I/O error
journal commit I/O error
EXT3-fs error (device dm-4) in ext3_free_blocks_sb: Journal has aborted
journal commit I/O error
journal commit I/O error
EXT3-fs error (device dm-4) in ext3_reserve_inode_write: Journal has aborted
EXT3-fs error (device dm-4) in ext3_truncate: IO failure journal commit I/O error
journal commit I/O error
journal commit I/O error
journal commit I/O error
EXT3-fs error (device dm-4) in ext3_reserve_inode_write: Journal has aborted
EXT3-fs error (device dm-4) in ext3_orphan_del: Journal has aborted EXT3-fs error (device dm-4) in ext3_reserve_inode_write: Journal has aborted
EXT3-fs error (device dm-4) in ext3_delete_inode: IO failure <LOG END>
After symlink size was fixed to len-1 problem dissappeared.
Quoted 41 lines
Quoted 3 lines
I dont prepare patch for this because i dont understand issue witch Nick aimed to fix.
I don't know why myself :P I think it would be just fine to use len-1 as it did previously, so it must have been a typo?
Quoted 8 lines
4)
iov_iter_fault_in_readable:
Function prerform check for signgle region, with out respect to segment nature of iovec, For example writev no longer works :) :
writev(3, [{"\1", 1}, {"\2"..., 4096}], 2)= -1 EFAULT (Bad address) this hidden bug, and it was invisiable becauseXXXX_fault_in_readablereturn value was ignored before. Letsiov_iter_fault_in_readableperform checks for all segments.
Fixed by :"iov_iter_fault_in_readable fix"OK thanks. I would rather just change this to use the length of the first iovec always (prefaulting multiple iovecs would have to be benchmarked on real apps that make heavy use of writev, I suspect).
Quoted 10 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
On Wed, 2007-06-13 at 13:43 +0200, Nick Piggin wrote:
..
Quoted 12 lines
Quoted 11 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
Quoted 2 lines
Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
It would be nice to go back to original order, but its not that simple with current structure of the code. With Nick's patches unlock_page() happens in generic_write_end(). journal_stop() needs to happen after generic_write_end(). :(
Mingming, can you take a look at the current & proposed order ? I ran into bunch of races when I tried to change the order for ->writepages() support earlier :(
Thanks,
Badari
Quoted 14 lines · Badari Pulavarty
On Wed, 2007-06-13 at 13:43 +0200, Nick Piggin wrote:
..Quoted 12 lines
Quoted 11 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
Quoted 7 lines
Quoted 2 lines
Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
It would be nice to go back to original order, but its not that simple with current structure of the code. With Nick's patches
unlock_page()happens ingeneric_write_end().journal_stop()needs to happen aftergeneric_write_end(). :(
Well we could use block_write_end?
Quoted 3 lines
Mingming, can you take a look at the current & proposed order ? I ran into bunch of races when I tried to change the order for ->writepages() support earlier :(
OK, it sounds like we probably want to revert to the original order at least for this patchset. If the new order is proven safe then that could be introduced later to simplify things...
Thanks,
Nick
Jan Kara
maintainerQuoted 14 lines · Nick Piggin
..
Quoted 12 lines
Quoted 11 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
Quoted 2 lines
Quoted 2 lines
Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
Sorry, I've missed beginning of this thread. But what problems can
exactly cause this ordering change? ext3_journal_stop has no need to be protected by the page lock - it can be even better that it's not protected as it can trigger commit and all that would happen unnecessarily under page lock...
Honza
Signature · 2 lines
Jan Kara <[email protected]> SuSE CR Labs
Quoted 14 lines · Jan Kara
Quoted 14 lines · Nick Piggin
..
Quoted 12 lines
Quoted 11 lines
5)
ext3_write_end:Before write_begin/write_end patch set we have folowing locking order: stop_journal(handle); unlock_page(page); But now order is oposite: unlock_page(page); stop_journal(handle); Can we got any race condition now? I'm not sure is it actual problem, may be somebody cant describe this.
Quoted 7 lines
Quoted 2 lines
Quoted 2 lines
Can we just change it to the original order? That would seem to be safest unless one of the ext3 devs explicitly acks it.
Sorry, I've missed beginning of this thread. But what problems can
exactly cause this ordering change?ext3_journal_stophas no need to be protected by the page lock - it can be even better that it's not protected as it can trigger commit and all that would happen unnecessarily under page lock...
Sure, if you think it is safe. I would rather it be done in a different patch though.