Re: [PATCH 1/2] pnfs/blocklayout: update last_write_offset in prepare_layoutcommit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2016-07-28 at 14:41 -0400, Benjamin Coddington wrote:
> Block/SCSI layout write completion may add committable extents to the
> extent tree before updating the layout's last-written byte under the
> inode
> lock.  If a sync happens before this value is updated, then
> prepare_layoutcommit may find and encode these extents which would
> produce
> a LAYOUTCOMMIT request whose encoded extents are larger than the
> request's
> loca_length.
> 
> Fix this by updating the last_write_offset to match the currently
> encoded
> extents.
> 
> Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
> ---
>  fs/nfs/blocklayout/extent_tree.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfs/blocklayout/extent_tree.c
> b/fs/nfs/blocklayout/extent_tree.c
> index 992bcb19c11e..18ae1fd2175e 100644
> --- a/fs/nfs/blocklayout/extent_tree.c
> +++ b/fs/nfs/blocklayout/extent_tree.c
> @@ -518,7 +518,7 @@ static __be32 *encode_scsi_range(struct
> pnfs_block_extent *be, __be32 *p)
>  }
>  
>  static int ext_tree_encode_commit(struct pnfs_block_layout *bl,
> __be32 *p,
> -		size_t buffer_size, size_t *count)
> +		size_t buffer_size, size_t *count, __u64 *lastbyte)
>  {
>  	struct pnfs_block_extent *be;
>  	int ret = 0;
> @@ -541,6 +541,8 @@ static int ext_tree_encode_commit(struct
> pnfs_block_layout *bl, __be32 *p,
>  		else
>  			p = encode_block_extent(be, p);
>  		be->be_tag = EXTENT_COMMITTING;
> +		if ((ext_f_end(be) << SECTOR_SHIFT) - 1 > *lastbyte)
> +			*lastbyte = (ext_f_end(be) << SECTOR_SHIFT) 
> - 1;

Won't this cause the file size to be always sector aligned on the
server? I was assuming that we would have to store the lastbyte
atomically with setting up the commit in ext_tree_mark_written().

>  	}
>  	spin_unlock(&bl->bl_ext_lock);
>  
> @@ -564,7 +566,7 @@ ext_tree_prepare_commit(struct
> nfs4_layoutcommit_args *arg)
>  	arg->layoutupdate_pages = &arg->layoutupdate_page;
>  
>  retry:
> -	ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size,
> &count);
> +	ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size,
> &count, &arg->lastbytewritten);
>  	if (unlikely(ret)) {
>  		ext_tree_free_commitdata(arg, buffer_size);
>  ��.n��������+%������w��{.n�����{��w���jg��������ݢj����G�������j:+v���w�m������w�������h�����٥




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux