[Ocfs2-tools-devel] [PATCH 3/7] libocfs2: Add extended slot map support

Sunil Mushran Sunil.Mushran at oracle.com
Fri Jan 11 15:31:03 PST 2008


Why are we exposing ocfs2_read_slot_map_extended() and its
write equivalent?

Joel Becker wrote:
> Add the code for reading, writing, loading, and storing the extended
> format.  Also introduce the ocfs2_format_slot_map() function.
>
> The new format allows for larger node numbers (up to UINT32_MAX), more slots
> (it is sized as a regular file), and has extra space for future updates.
>
> Signed-of-by: Joel Becker <joel.becker at oracle.com>
> ---
>  libocfs2/feature_string.c |    5 +
>  libocfs2/include/ocfs2.h  |   17 ++
>  libocfs2/ocfs2_err.et     |    2 +-
>  libocfs2/slot_map.c       |  422 +++++++++++++++++++++++++++++++++++++++------
>  4 files changed, 388 insertions(+), 58 deletions(-)
>
> diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
> index 40720b8..54674f3 100644
> --- a/libocfs2/feature_string.c
> +++ b/libocfs2/feature_string.c
> @@ -73,6 +73,11 @@ static struct fs_feature_flags ocfs2_supported_features[] = {
>  		 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},
>  	},
>  	{
> +		"extended-slotmap",
> +		{0, OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP, 0},
> +		{0, OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP, 0},
> +	},
> +	{
>  		NULL,
>  		{0, 0, 0},
>  		{0, 0, 0}
> diff --git a/libocfs2/include/ocfs2.h b/libocfs2/include/ocfs2.h
> index 21e9452..3074504 100644
> --- a/libocfs2/include/ocfs2.h
> +++ b/libocfs2/include/ocfs2.h
> @@ -557,14 +557,23 @@ errcode_t ocfs2_meta_unlock(ocfs2_filesys *fs, ocfs2_cached_inode *ci);
>  
>  /* Low level */
>  void ocfs2_swap_slot_map(struct ocfs2_slot_map *sm, int num_slots);
> +void ocfs2_swap_slot_map_extended(struct ocfs2_slot_map_extended *se,
> +				  int num_slots);
>  errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
>  			      int num_slots,
>  			      struct ocfs2_slot_map **map_ret);
> +errcode_t ocfs2_read_slot_map_extended(ocfs2_filesys *fs,
> +				       int num_slots,
> +				       struct ocfs2_slot_map_extended **map_ret);
>  errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
>  			       int num_slots,
>  			       struct ocfs2_slot_map *sm);
> +errcode_t ocfs2_write_slot_map_extended(ocfs2_filesys *fs,
> +					int num_slots,
> +					struct ocfs2_slot_map_extended *se);
>  
>  /* High level */
> +errcode_t ocfs2_format_slot_map(ocfs2_filesys *fs);
>  errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
>  			      struct ocfs2_slot_map_data **data_ret);
>  errcode_t ocfs2_store_slot_map(ocfs2_filesys *fs,
> @@ -763,6 +772,14 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super_block *osb)
>  	return 0;
>  }
>  
> +static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super_block *osb)
> +{
> +	if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP)
> +		return 1;
> +	return 0;
> +}
> +
> +
>  /*
>   * shamelessly lifted from the kernel
>   *
> diff --git a/libocfs2/ocfs2_err.et b/libocfs2/ocfs2_err.et
> index c29c925..5e46e13 100644
> --- a/libocfs2/ocfs2_err.et
> +++ b/libocfs2/ocfs2_err.et
> @@ -34,7 +34,7 @@ ec	OCFS2_ET_SHORT_READ,
>  	"Attempt to read block from filesystem resulted in short read"
>  
>  ec	OCFS2_ET_SHORT_WRITE,
> -	"Attempt to read block from filesystem resulted in short write"
> +	"Attempt to write block to the filesystem resulted in short write"
>  
>  ec	OCFS2_ET_NO_MEMORY,
>  	"Memory allocation failed"
> diff --git a/libocfs2/slot_map.c b/libocfs2/slot_map.c
> index 8349c6a..daaf97e 100644
> --- a/libocfs2/slot_map.c
> +++ b/libocfs2/slot_map.c
> @@ -6,12 +6,12 @@
>   * This program is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU General Public
>   * License, version 2,  as published by the Free Software Foundation.
> - * 
> + *
>   * This program is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>   * General Public License for more details.
> - * 
> + *
>   * You should have received a copy of the GNU General Public
>   * License along with this program; if not, write to the
>   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> @@ -23,6 +23,12 @@
>  
>  #include "ocfs2.h"
>  
> +/* Just so we can pass it about */
> +union ocfs2_slot_map_wrapper {
> +	struct ocfs2_slot_map *mw_map;
> +	struct ocfs2_slot_map_extended *mw_map_extended;
> +};
> +
>  void ocfs2_swap_slot_map(struct ocfs2_slot_map *sm, int num_slots)
>  {
>  	int i;
> @@ -34,15 +40,30 @@ void ocfs2_swap_slot_map(struct ocfs2_slot_map *sm, int num_slots)
>  		sm->sm_slots[i] = bswap_16(sm->sm_slots[i]);
>  }
>  
> -errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
> -			      int num_slots,
> -			      struct ocfs2_slot_map **map_ret)
> +void ocfs2_swap_slot_map_extended(struct ocfs2_slot_map_extended *se,
> +				  int num_slots)
> +{
> +	int i;
> +
> +	if (!cpu_is_big_endian)
> +		return;
> +
> +	for (i = 0; i < num_slots; i++)
> +		se->se_slots[i].es_node_num =
> +			bswap_32(se->se_slots[i].es_node_num);
> +}
> +
> +static errcode_t __ocfs2_read_slot_map(ocfs2_filesys *fs,
> +				       int num_slots,
> +				       union ocfs2_slot_map_wrapper *wrap)
>  {
>  	errcode_t ret;
>  	uint64_t blkno;
>  	char *slot_map_buf;
>  	struct ocfs2_slot_map *sm;
> +	struct ocfs2_slot_map_extended *se;
>  	int bytes_needed, len;
> +	int extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
>  
>  	ret = ocfs2_lookup_system_inode(fs, SLOT_MAP_SYSTEM_INODE, 0,
>  					&blkno);
> @@ -53,70 +74,209 @@ errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
>  	if (ret)
>  		return ret;
>  
> -	bytes_needed = ocfs2_blocks_in_bytes(fs,
> -					     num_slots * sizeof(__le16));
> +	if (extended)
> +		bytes_needed =
> +			num_slots * sizeof(struct ocfs2_extended_slot);
> +	else
> +		bytes_needed = num_slots * sizeof(__le16);
> +
>  	if (bytes_needed > len) {
>  		ocfs2_free(&slot_map_buf);
>  		return OCFS2_ET_SHORT_READ;
>  	}
>  
> -	sm = (struct ocfs2_slot_map *)slot_map_buf;
> -	ocfs2_swap_slot_map(sm, num_slots);
> +	if (extended) {
> +		se = (struct ocfs2_slot_map_extended *)slot_map_buf;
> +		ocfs2_swap_slot_map_extended(se, num_slots);
> +		wrap->mw_map_extended = se;
> +	} else {
> +		sm = (struct ocfs2_slot_map *)slot_map_buf;
> +		ocfs2_swap_slot_map(sm, num_slots);
> +		wrap->mw_map = sm;
> +	}
>  
> -	*map_ret = sm;
> +	return 0;
> +}
>  
> +errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
> +			      int num_slots,
> +			      struct ocfs2_slot_map **map_ret)
> +{
> +	errcode_t ret;
> +	union ocfs2_slot_map_wrapper wrap = {
> +		.mw_map = NULL,
> +	};
> +
> +	ret = __ocfs2_read_slot_map(fs, num_slots, &wrap);
> +	if (ret)
> +		return ret;
> +
> +	*map_ret = wrap.mw_map;
> + 	return 0;
> +}
> +
> +errcode_t ocfs2_read_slot_map_extended(ocfs2_filesys *fs,
> +				       int num_slots,
> +				       struct ocfs2_slot_map_extended **map_ret)
> +{
> +	errcode_t ret;
> +	union ocfs2_slot_map_wrapper wrap = {
> +		.mw_map_extended = NULL,
> +	};
> +
> +	ret = __ocfs2_read_slot_map(fs, num_slots, &wrap);
> +	if (ret)
> +		return ret;
> +
> +	*map_ret = wrap.mw_map_extended;
>  	return 0;
>  }
>  
> -errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
> -			       int num_slots,
> -			       struct ocfs2_slot_map *sm)
> +static errcode_t __ocfs2_write_slot_map(ocfs2_filesys *fs,
> +					int num_slots,
> +					union ocfs2_slot_map_wrapper *wrap)
>  {
>  	errcode_t ret, tret;
> -	ocfs2_cached_inode *ci;
> -	uint64_t blkno, bytes;
> -	uint32_t wrote;
> +	ocfs2_cached_inode *ci = NULL;
> +	uint64_t blkno;
> +	unsigned int size, bytes, wrote, blocks;
> +	void *buf = NULL;
> +	int extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
>  
>  	ret = ocfs2_lookup_system_inode(fs, SLOT_MAP_SYSTEM_INODE, 0,
>  					&blkno);
>  	if (ret)
> -		return ret;
> +		goto out;
>  
> -	ret = ocfs2_read_cached_inode(fs, blkno, &ci);
> -	if (ret)
> -		return ret;
> +	if (extended)
> +		size = num_slots * sizeof(struct ocfs2_extended_slot);
> +	else
> +		size = num_slots * sizeof(__le16);
>  
> -	bytes = (uint64_t)num_slots * sizeof(__le16);
> +	blocks = ocfs2_blocks_in_bytes(fs, size);
> +	bytes = blocks << OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
> +	ret = ocfs2_malloc_blocks(fs->fs_io, blocks, &buf);
> +	if (ret)
> +		goto out;
> +	memset(buf, 0, bytes);
> +
> +	if (extended) {
> +		memcpy(buf, wrap->mw_map_extended, size);
> +		ocfs2_swap_slot_map_extended(buf, num_slots);
> +	} else {
> +		memcpy(buf, wrap->mw_map, size);
> +		ocfs2_swap_slot_map(buf, num_slots);
> +	}
>  
> -	ocfs2_swap_slot_map(sm, num_slots);
> +	ret = ocfs2_read_cached_inode(fs, blkno, &ci);
> +	if (ret)
> +		goto out;
>  
> -	ret = ocfs2_file_write(ci, sm, bytes, 0, &wrote);
> -	tret = ocfs2_free_cached_inode(fs, ci);
> +	ret = ocfs2_file_write(ci, buf, bytes, 0, &wrote);
>  	if (ret)
> -		return ret;
> -	if (wrote != bytes)
> -		return OCFS2_ET_SHORT_WRITE;
> +		goto out;
>  
>  	/*
> -	 * The error from free_cached_inode() is only important if
> -	 * there were no other problems.
> +	 * This is wacky.  We have to write a block (bytes), but &wrote
> +	 * might return only i_size (size).  Handle both.
>  	 */
> -	if (tret)
> -		return tret;
> +	if ((wrote != bytes) && (wrote != size))
> +		ret = OCFS2_ET_SHORT_WRITE;
> +
> +out:
> +	if (ci) {
> +		tret = ocfs2_free_cached_inode(fs, ci);
> +		/*
> +		 * The error from free_cached_inode() is only important if
> +		 * there were no other problems.
> +		 */
> +		if (!ret)
> +			ret = tret;
> +	}
> +	if (buf)
> +		ocfs2_free(&buf);
> +	return ret;
> +}
>  
> -	return 0;
> +errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
> +			       int num_slots,
> +			       struct ocfs2_slot_map *sm)
> +{
> +	union ocfs2_slot_map_wrapper wrap = {
> +		.mw_map = sm,
> +	};
> +
> +	return __ocfs2_write_slot_map(fs, num_slots, &wrap);
>  }
>  
> -errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
> -			      struct ocfs2_slot_map_data **data_ret)
> +errcode_t ocfs2_write_slot_map_extended(ocfs2_filesys *fs,
> +					int num_slots,
> +					struct ocfs2_slot_map_extended *se)
> +{
> +	union ocfs2_slot_map_wrapper wrap = {
> +		.mw_map_extended = se,
> +	};
> +
> +	return __ocfs2_write_slot_map(fs, num_slots, &wrap);
> +}
> +
> +static void ocfs2_slot_map_to_data(ocfs2_filesys *fs,
> +				   struct ocfs2_slot_map_data *md,
> +				   union ocfs2_slot_map_wrapper *wrap)
> +{
> +	int i;
> +	struct ocfs2_slot_map *sm = wrap->mw_map;
> +	struct ocfs2_slot_map_extended *se = wrap->mw_map_extended;
> +	int extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
> +
> +	for (i = 0; i < md->md_num_slots; i++) {
> +		if (extended) {
> +			if (se->se_slots[i].es_valid) {
> +				md->md_slots[i].sd_valid = 1;
> +				md->md_slots[i].sd_node_num = se->se_slots[i].es_node_num;
> +			} else
> +				md->md_slots[i].sd_valid = 0;
> +		} else {
> +			if (sm->sm_slots[i] != (uint16_t)OCFS2_INVALID_SLOT) {
> +				md->md_slots[i].sd_valid = 1;
> +				md->md_slots[i].sd_node_num = sm->sm_slots[i];
> +			} else
> +				md->md_slots[i].sd_valid = 0;
> +		}
> +	}
> +}
> +
> +static void ocfs2_slot_data_to_map(ocfs2_filesys *fs,
> +				   struct ocfs2_slot_map_data *md,
> +				   union ocfs2_slot_map_wrapper *wrap)
> +{
> +	int i;
> +	struct ocfs2_slot_map *sm = wrap->mw_map;
> +	struct ocfs2_slot_map_extended *se = wrap->mw_map_extended;
> +	int extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
> +
> +	for (i = 0; i < md->md_num_slots; i++) {
> +		if (extended) {
> +			if (md->md_slots[i].sd_valid) {
> +				se->se_slots[i].es_valid = 1;
> +				se->se_slots[i].es_node_num = md->md_slots[i].sd_node_num;
> +			} else
> +				se->se_slots[i].es_valid = 0;
> +		} else {
> +			if (md->md_slots[i].sd_valid)
> +				sm->sm_slots[i] = (uint16_t)md->md_slots[i].sd_node_num;
> +			else
> +				sm->sm_slots[i] = (uint16_t)OCFS2_INVALID_SLOT;
> +		}
> +	}
> +}
> +
> +static errcode_t ocfs2_alloc_slot_map_data(int num_slots,
> +					   struct ocfs2_slot_map_data **md_ret)
>  {
>  	errcode_t ret;
> -	int i, num_slots;
> -	struct ocfs2_slot_map *sm;
>  	struct ocfs2_slot_map_data *md;
>  
> -	num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
> -
>  	ret = ocfs2_malloc0(sizeof(struct ocfs2_slot_map_data) +
>  			    (sizeof(struct ocfs2_slot_data) * num_slots),
>  			    &md);
> @@ -126,18 +286,31 @@ errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
>  	md->md_num_slots = num_slots;
>  	md->md_slots = (struct ocfs2_slot_data *)((char *)md + sizeof(struct ocfs2_slot_map_data));
>  
> -	ret = ocfs2_read_slot_map(fs, num_slots, &sm);
> +	*md_ret = md;
> +	return 0;
> +}
> +
> +errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
> +			      struct ocfs2_slot_map_data **data_ret)
> +{
> +	errcode_t ret;
> +	int num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;;
> +	struct ocfs2_slot_map_data *md;
> +	union ocfs2_slot_map_wrapper wrap = {
> +		.mw_map = NULL,
> +	};
> +
> +	ret = ocfs2_alloc_slot_map_data(num_slots, &md);
> +	if (ret)
> +		return ret;
> +
> +	ret = __ocfs2_read_slot_map(fs, num_slots, &wrap);
>  	if (ret) {
>  		ocfs2_free(&md);
>  		return ret;
>  	}
>  
> -	for (i = 0; i < num_slots; i++) {
> -		if (sm->sm_slots[i] != (uint16_t)OCFS2_INVALID_SLOT) {
> -			md->md_slots[i].sd_valid = 1;
> -			md->md_slots[i].sd_node_num = sm->sm_slots[i];
> -		}
> -	}
> +	ocfs2_slot_map_to_data(fs, md, &wrap);
>  
>  	*data_ret = md;
>  	return 0;
> @@ -147,25 +320,160 @@ errcode_t ocfs2_store_slot_map(ocfs2_filesys *fs,
>  			       struct ocfs2_slot_map_data *md)
>  {
>  	errcode_t ret;
> -	struct ocfs2_slot_map *sm;
> -	int i, num_slots, bytes;
> +	char *slot_map_buf;
> +	int bytes;
> +	int extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
> +	union ocfs2_slot_map_wrapper wrap;
>  
> -	num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
> -	bytes = num_slots * sizeof(__le16);
> +	if (extended)
> +		bytes = md->md_num_slots * sizeof(struct ocfs2_extended_slot);
> +	else
> +		bytes = md->md_num_slots * sizeof(__le16);
>  
> -	ret = ocfs2_malloc0(bytes, &sm);
> +	ret = ocfs2_malloc0(bytes, &slot_map_buf);
>  	if (ret)
>  		return ret;
> +	wrap.mw_map = (struct ocfs2_slot_map *)slot_map_buf;
> +
> +	ocfs2_slot_data_to_map(fs, md, &wrap);
> +	ret = __ocfs2_write_slot_map(fs, md->md_num_slots, &wrap);
>  
> -	for (i = 0; i < num_slots; i++) {
> -		if (md->md_slots[i].sd_valid)
> -			sm->sm_slots[i] = md->md_slots[i].sd_node_num;
> -		else
> -			sm->sm_slots[i] = OCFS2_INVALID_SLOT;
> +	ocfs2_free(&slot_map_buf);
> +
> +	return ret;
> +}
> +
> +struct slotmap_format {
> +	int extended;
> +	int needed_slots;
> +	int actual_slots;
> +	unsigned int needed_bytes;
> +	ocfs2_cached_inode *ci;
> +};
> +
> +static errcode_t ocfs2_size_slot_map(ocfs2_filesys *fs,
> +				     struct slotmap_format *sf)
> +{
> +	errcode_t ret ;
> +	struct ocfs2_dinode *di;
> +	unsigned int clusters;
> +	uint64_t new_size;
> +
> +	di = sf->ci->ci_inode;
> +	if (sf->needed_bytes == di->i_size) {
> +		ret = 0;
> +		goto out;
>  	}
>  
> -	ret = ocfs2_write_slot_map(fs, num_slots, sm);
> -	ocfs2_free(&sm);
> +	clusters = sf->needed_bytes + fs->fs_clustersize - 1;
> +	clusters = clusters >> OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
> +	if (!clusters) {
> +		ret = OCFS2_ET_INTERNAL_FAILURE;
> +		goto out;
> +	}
> +
> +	if (clusters > di->i_clusters) {
> +		ret = ocfs2_extend_allocation(fs, sf->ci->ci_blkno,
> +					      (clusters - di->i_clusters));
> +		if (ret)
> +			goto out;
> +
> +		/* We don't cache in the library right now, so any
> +		 * work done in extend_allocation won't be reflected
> +		 * in our now stale copy. */
> +		ocfs2_free_cached_inode(fs, sf->ci);
> +		ret = ocfs2_read_cached_inode(fs, sf->ci->ci_blkno,
> +					      &sf->ci);
> +		if (ret) {
> +			sf->ci = NULL;
> +			goto out;
> +		}
> +		di = sf->ci->ci_inode;
> +	} else if (clusters < di->i_clusters) {
> +		new_size = clusters <<
> +				OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
> +		ret = ocfs2_truncate(fs, sf->ci->ci_blkno, new_size);
> +		if (ret)
> +			goto out;
> +
> +		ocfs2_free_cached_inode(fs, sf->ci);
> +		ret = ocfs2_read_cached_inode(fs, sf->ci->ci_blkno,
> +					      &sf->ci);
> +		if (ret) {
> +			sf->ci = NULL;
> +			goto out;
> +		}
> +		di = sf->ci->ci_inode;
> +	}
> +
> +	/*
> +	 * Now that we've adjusted the allocation, write out the
> +	 * correct i_size.  By design, the slot map's i_size encompasses
> +	 * the full allocation.
> +	 */
> +	di->i_size = di->i_clusters <<
> +			OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
> +	di->i_mtime = time(NULL);
> +
> +	ret = ocfs2_write_inode(fs, sf->ci->ci_blkno, (char *)di);
> +	if (ret)
> +		goto out;
> +
> +out:
> +	return ret;
> +}
> +
> +errcode_t ocfs2_format_slot_map(ocfs2_filesys *fs)
> +{
> +	errcode_t ret;
> +	uint64_t blkno;
> +	struct slotmap_format sf;
> +	struct ocfs2_slot_map_data *md = NULL;
> +
> +	ret = ocfs2_lookup_system_inode(fs, SLOT_MAP_SYSTEM_INODE, 0,
> +					&blkno);
> +	if (ret)
> +		goto out;
> +
> +	ret = ocfs2_read_cached_inode(fs, blkno, &sf.ci);
> +	if (ret)
> +		goto out;
> +
> +	/* verify it is a system file */
> +	if (!(sf.ci->ci_inode->i_flags & OCFS2_VALID_FL) ||
> +	    !(sf.ci->ci_inode->i_flags & OCFS2_SYSTEM_FL)) {
> +		ret = OCFS2_ET_INTERNAL_FAILURE;
> +		goto out;
> +	}
> +
> +	sf.extended = ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super));
> +	sf.needed_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
> +	if (sf.extended)
> +		sf.needed_bytes = sf.needed_slots * sizeof(struct ocfs2_extended_slot);
> +	else
> +		sf.needed_bytes = sf.needed_slots * sizeof(__le16);
> +
> +	ret = ocfs2_size_slot_map(fs, &sf);
> +	if (ret)
> +		goto out;
> +
> +	if (sf.extended)
> +		sf.actual_slots = sf.ci->ci_inode->i_size / sizeof(struct ocfs2_extended_slot);
> +	else
> +		sf.actual_slots = sf.ci->ci_inode->i_size / sizeof(__le16);
> +
> +	/* This returns an empty map that covers the entire allocation */
> +	ret = ocfs2_alloc_slot_map_data(sf.actual_slots, &md);
> +	if (ret)
> +		return ret;
> +
> +	ret = ocfs2_store_slot_map(fs, md);
> +
> +out:
> +	if (sf.ci)
> +		ocfs2_free_cached_inode(fs, sf.ci);
> +	if (md)
> +		ocfs2_free(&md);
>  
>  	return ret;
>  }
>   




More information about the Ocfs2-tools-devel mailing list