On 06/09/2010 02:10 PM, Boaz Harrosh wrote: > > These changes are crafted based on the similar > conversion done to ext2 by Nick Piggin. > > * Remove the deprecated ->truncate vector. Let exofs_setattr > take care of on-disk size updates. > * Call truncate_pagecache on the unused pages if > write_begin/end fails. > * Cleanup exofs_delete_inode that did stupid inode > writes and updates on an inode that will be > removed. > * And finally get rid of exofs_get_block. We never > had any blocks it was all for calling nobh_truncate_page. > nobh_truncate_page is not actually needed in exofs since > the last page is complete and gone, just like all the other > pages. There is no partial blocks in exofs. > > I've tested with this patch, and there are no apparent > failures, so far. > > CC: Nick Piggin <npiggin@xxxxxxx> > CC: Christoph Hellwig <hch@xxxxxx> > Signed-off-by: Boaz Harrosh <bharrosh@xxxxxxxxxxx> Al hi. Please take this through your tree. And/or tell me if you need it reorder with your ->evict patches. Thanks Boaz > --- > fs/exofs/exofs.h | 1 - > fs/exofs/file.c | 1 - > fs/exofs/inode.c | 114 ++++++++++++++++++++---------------------------------- > 3 files changed, 42 insertions(+), 74 deletions(-) > > diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h > index 22721b2..0706ce9 100644 > --- a/fs/exofs/exofs.h > +++ b/fs/exofs/exofs.h > @@ -256,7 +256,6 @@ static inline int exofs_oi_read(struct exofs_i_info *oi, > } > > /* inode.c */ > -void exofs_truncate(struct inode *inode); > int exofs_setattr(struct dentry *, struct iattr *); > int exofs_write_begin(struct file *file, struct address_space *mapping, > loff_t pos, unsigned len, unsigned flags, > diff --git a/fs/exofs/file.c b/fs/exofs/file.c > index fef6899..f9bfe2b 100644 > --- a/fs/exofs/file.c > +++ b/fs/exofs/file.c > @@ -86,6 +86,5 @@ const struct file_operations exofs_file_operations = { > }; > > const struct inode_operations exofs_file_inode_operations = { > - .truncate = exofs_truncate, > .setattr = exofs_setattr, > }; > diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c > index 4bfc1f4..5510a5e 100644 > --- a/fs/exofs/inode.c > +++ b/fs/exofs/inode.c > @@ -710,7 +710,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping, > fsdata); > if (ret) { > EXOFS_DBGMSG("simple_write_begin faild\n"); > - return ret; > + goto out; > } > > page = *pagep; > @@ -725,7 +725,14 @@ int exofs_write_begin(struct file *file, struct address_space *mapping, > EXOFS_DBGMSG("__readpage_filler faild\n"); > } > } > +out: > + if (unlikely(ret)) { > + struct inode *inode = mapping->host; > + loff_t to = pos + len; > > + if (to > inode->i_size) > + truncate_pagecache(inode, to, inode->i_size); > + } > return ret; > } > > @@ -750,6 +757,10 @@ static int exofs_write_end(struct file *file, struct address_space *mapping, > int ret; > > ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata); > + if (unlikely(ret && pos + len > inode->i_size)) > + truncate_pagecache(inode, pos + len, inode->i_size); > + > + /* TODO: once simple_write_end marks inode dirty remove */ > if (i_size != inode->i_size) > mark_inode_dirty(inode); > return ret; > @@ -808,91 +819,53 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode) > return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0); > } > > -/* > - * get_block_t - Fill in a buffer_head > - * An OSD takes care of block allocation so we just fake an allocation by > - * putting in the inode's sector_t in the buffer_head. > - * TODO: What about the case of create==0 and @iblock does not exist in the > - * object? > - */ > -static int exofs_get_block(struct inode *inode, sector_t iblock, > - struct buffer_head *bh_result, int create) > -{ > - map_bh(bh_result, inode->i_sb, iblock); > - return 0; > -} > - > const struct osd_attr g_attr_logical_length = ATTR_DEF( > OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); > > -static int _do_truncate(struct inode *inode) > +static int _do_truncate(struct inode *inode, loff_t newsize) > { > struct exofs_i_info *oi = exofs_i(inode); > - loff_t isize = i_size_read(inode); > int ret; > > inode->i_mtime = inode->i_ctime = CURRENT_TIME; > > - nobh_truncate_page(inode->i_mapping, isize, exofs_get_block); > + ret = exofs_oi_truncate(oi, (u64)newsize); > + if (likely(!ret)) > + truncate_setsize(inode, newsize); > > - ret = exofs_oi_truncate(oi, (u64)isize); > - EXOFS_DBGMSG("(0x%lx) size=0x%llx\n", inode->i_ino, isize); > + EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n", > + inode->i_ino, newsize, ret); > return ret; > } > > /* > - * Truncate a file to the specified size - all we have to do is set the size > - * attribute. We make sure the object exists first. > - */ > -void exofs_truncate(struct inode *inode) > -{ > - struct exofs_i_info *oi = exofs_i(inode); > - int ret; > - > - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) > - || S_ISLNK(inode->i_mode))) > - return; > - if (exofs_inode_is_fast_symlink(inode)) > - return; > - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) > - return; > - > - /* if we are about to truncate an object, and it hasn't been > - * created yet, wait > - */ > - if (unlikely(wait_obj_created(oi))) > - goto fail; > - > - ret = _do_truncate(inode); > - if (ret) > - goto fail; > - > -out: > - mark_inode_dirty(inode); > - return; > -fail: > - make_bad_inode(inode); > - goto out; > -} > - > -/* > - * Set inode attributes - just call generic functions. > + * Set inode attributes - update size attribute on OSD if needed, > + * otherwise just call generic functions. > */ > int exofs_setattr(struct dentry *dentry, struct iattr *iattr) > { > struct inode *inode = dentry->d_inode; > int error; > > + /* if we are about to modify an object, and it hasn't been > + * created yet, wait > + */ > + error = wait_obj_created(exofs_i(inode)); > + if (unlikely(error)) > + return error; > + > error = inode_change_ok(inode, iattr); > - if (error) > + if (unlikely(error)) > return error; > > if ((iattr->ia_valid & ATTR_SIZE) && > iattr->ia_size != i_size_read(inode)) { > - int error; > + error = inode_newsize_ok(inode, iattr->ia_size); > + if (unlikely(error)) > + return error; > > - error = vmtruncate(inode, iattr->ia_size); > - if (error) > + error = _do_truncate(inode, iattr->ia_size); > + if (unlikely(error)) > return error; > } > > @@ -1345,28 +1318,25 @@ void exofs_delete_inode(struct inode *inode) > > truncate_inode_pages(&inode->i_data, 0); > > + /* TODO: should do better here */ > if (is_bad_inode(inode)) > goto no_delete; > > - mark_inode_dirty(inode); > - exofs_update_inode(inode, inode_needs_sync(inode)); > - > inode->i_size = 0; > - if (inode->i_blocks) > - exofs_truncate(inode); > - > clear_inode(inode); > > - ret = exofs_get_io_state(&sbi->layout, &ios); > - if (unlikely(ret)) { > - EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); > - return; > - } > - > /* if we are deleting an obj that hasn't been created yet, wait */ > if (!obj_created(oi)) { > BUG_ON(!obj_2bcreated(oi)); > wait_event(oi->i_wq, obj_created(oi)); > + /* ignore the error attempt a remove anyway */ > + } > + > + /* Now Remove the OSD objects */ > + ret = exofs_get_io_state(&sbi->layout, &ios); > + if (unlikely(ret)) { > + EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); > + return; > } > > ios->obj.id = exofs_oi_objno(oi); -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html