mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 05:31:15 +00:00
fs: introduce new truncate sequence
Introduce a new truncate calling sequence into fs/mm subsystems. Rather than setattr > vmtruncate > truncate, have filesystems call their truncate sequence from ->setattr if filesystem specific operations are required. vmtruncate is deprecated, and truncate_pagecache and inode_newsize_ok helpers introduced previously should be used. simple_setattr is introduced for simple in-ram filesystems to implement the new truncate sequence. Eventually all filesystems should be converted to implement a setattr, and the default code in notify_change should go away. simple_setsize is also introduced to perform just the ATTR_SIZE portion of simple_setattr (ie. changing i_size and trimming pagecache). To implement the new truncate sequence: - filesystem specific manipulations (eg freeing blocks) must be done in the setattr method rather than ->truncate. - vmtruncate can not be used by core code to trim blocks past i_size in the event of write failure after allocation, so this must be performed in the fs code. - convert usage of helpers block_write_begin, nobh_write_begin, cont_write_begin, and *blockdev_direct_IO* to use _newtrunc postfixed variants. These avoid calling vmtruncate to trim blocks (see previous). - inode_setattr should not be used. generic_setattr is a new function to be used to copy simple attributes into the generic inode. - make use of the better opportunity to handle errors with the new sequence. Big problem with the previous calling sequence: the filesystem is not called until i_size has already changed. This means it is not allowed to fail the call, and also it does not know what the previous i_size was. Also, generic code calling vmtruncate to truncate allocated blocks in case of error had no good way to return a meaningful error (or, for example, atomically handle block deallocation). Cc: Christoph Hellwig <hch@lst.de> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
7000d3c424
commit
7bb46a6734
8 changed files with 300 additions and 63 deletions
|
@ -548,18 +548,18 @@ EXPORT_SYMBOL(truncate_pagecache);
|
|||
* NOTE! We have to be ready to update the memory sharing
|
||||
* between the file and the memory map for a potential last
|
||||
* incomplete page. Ugly, but necessary.
|
||||
*
|
||||
* This function is deprecated and simple_setsize or truncate_pagecache
|
||||
* should be used instead.
|
||||
*/
|
||||
int vmtruncate(struct inode *inode, loff_t offset)
|
||||
{
|
||||
loff_t oldsize;
|
||||
int error;
|
||||
|
||||
error = inode_newsize_ok(inode, offset);
|
||||
error = simple_setsize(inode, offset);
|
||||
if (error)
|
||||
return error;
|
||||
oldsize = inode->i_size;
|
||||
i_size_write(inode, offset);
|
||||
truncate_pagecache(inode, oldsize, offset);
|
||||
|
||||
if (inode->i_op->truncate)
|
||||
inode->i_op->truncate(inode);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue