clean up write_begin usage for directories in pagecache
For filesystem that implement directories in pagecache we call block_write_begin with an already allocated page for this code, while the normal regular file write path uses the default block_write_begin behaviour. Get rid of the __foofs_write_begin helper and opencode the normal write_begin call in foofs_write_begin, while adding a new foofs_prepare_chunk helper for the directory code. The added benefit is that foofs_prepare_chunk has a much saner calling convention. Note that the interruptible flag passed into block_write_begin is always ignored if we already pass in a page (see next patch for details), and we never were doing truncations of exessive blocks for this case either so we can switch directly to block_write_begin_newtrunc. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:

committed by
Al Viro

parent
282dc17884
commit
f4e420dc42
@@ -218,8 +218,7 @@ got_it:
|
||||
pos = page_offset(page) +
|
||||
(char*)de - (char*)page_address(page);
|
||||
lock_page(page);
|
||||
err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
memcpy (de->name, name, namelen);
|
||||
@@ -239,15 +238,13 @@ out_unlock:
|
||||
|
||||
int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page->mapping;
|
||||
struct inode *inode = (struct inode*)mapping->host;
|
||||
struct inode *inode = page->mapping->host;
|
||||
char *kaddr = (char*)page_address(page);
|
||||
loff_t pos = page_offset(page) + (char *)de - kaddr;
|
||||
int err;
|
||||
|
||||
lock_page(page);
|
||||
err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
|
||||
BUG_ON(err);
|
||||
de->inode = 0;
|
||||
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
|
||||
@@ -259,16 +256,14 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
|
||||
|
||||
int sysv_make_empty(struct inode *inode, struct inode *dir)
|
||||
{
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct page *page = grab_cache_page(mapping, 0);
|
||||
struct page *page = grab_cache_page(inode->i_mapping, 0);
|
||||
struct sysv_dir_entry * de;
|
||||
char *base;
|
||||
int err;
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE);
|
||||
if (err) {
|
||||
unlock_page(page);
|
||||
goto fail;
|
||||
@@ -341,15 +336,13 @@ not_empty:
|
||||
void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
|
||||
struct inode *inode)
|
||||
{
|
||||
struct address_space *mapping = page->mapping;
|
||||
struct inode *dir = mapping->host;
|
||||
struct inode *dir = page->mapping->host;
|
||||
loff_t pos = page_offset(page) +
|
||||
(char *)de-(char*)page_address(page);
|
||||
int err;
|
||||
|
||||
lock_page(page);
|
||||
err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
|
||||
BUG_ON(err);
|
||||
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
|
||||
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
|
||||
|
Reference in New Issue
Block a user