On Tue, May 18, 2010 at 09:06:54PM +0800, Yan, Zheng wrote:
> On Sat, Mar 20, 2010 at 12:26 PM, Sean Bartell
> <wingedtachikoma@xxxxxxxxx> wrote:
> > +int add_file_disk_extent(struct extent_iterate_data *priv, u64 file_off,
> > + u64 disk_off, u64 size)
> > +{
> > + BUG_ON(file_off < priv->last_file_off);
> > + int ret;
> > + u64 sectorsize = priv->root->sectorsize;
> > + u64 mask = sectorsize - 1;
> > + if (size == 0)
> > + return 0;
> > + if ((file_off & mask) != (disk_off & mask)) {
> > + /* It's unclear how to CoW this, so don't. */
> > + char *data = malloc(size);
> > + if (!data)
> > + return -ENOMEM;
> > + ret = read_disk_extent(priv->root, disk_off, size, data);
> > + if (ret) {
> > + free(data);
> > + return ret;
> > }
> > + ret = add_file_mem_extent(priv, file_off, size, data);
> > + free(data);
> > + return ret;
> > + }
> > + if (priv->type == EXTENT_ITERATE_TYPE_DISK
> > + && priv->file_off + priv->size == file_off
> > + && priv->disk_off + priv->size == disk_off) {
> > + /* It's a continuation of the same disk extent. */
> > + priv->size += size;
> > + return 0;
> > + }
> > + if (disk_off == 0 || disk_off & mask) {
>
> why "disk_off == 0" is needed here?
To btrfs, a disk offset of 0 represents a sparse extent. If the original
filesystem passes in an extent at 0, this chops off the first block to
prevent it from being mistakenly interpreted as a sparse extent.
> > + /* We need to have an aligned start, so give the first part to
> > + * add_file_mem_extent if necessary. */
> > + u64 mem_size = min_t(u64, sectorsize - (disk_off & mask), size);
> > + char *data = malloc(mem_size);
> > + if (!data)
> > + return -ENOMEM;
> > + ret = read_disk_extent(priv->root, disk_off, mem_size, data);
> > + if (ret) {
> > + free(data);
> > + return ret;
> > + }
> > + ret = add_file_mem_extent(priv, file_off, mem_size, data);
> > + free(data);
> > + if (ret)
> > + return ret;
> > + file_off += mem_size;
> > + disk_off += mem_size;
> > + size -= mem_size;
> > + if (size == 0)
> > + return 0;
> > + }
> > + ret = commit_file_extents(priv);
> > + if (ret)
> > + return ret;
> > + priv->type = EXTENT_ITERATE_TYPE_DISK;
> > + priv->size = size;
> > + priv->file_off = file_off;
> > + priv->disk_off = disk_off;
> > + return 0;
> > +}
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html