diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2012-11-12 22:54:08 +0100 | 
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2012-11-12 22:54:08 +0100 | 
| commit | 8a6ff8a0a2bc51b29681aab093b349c9eb32acf5 (patch) | |
| tree | 7ee7315a4aa9b33cba73cf46e59187157a00866a /fs/btrfs/send.c | |
| parent | 65829ef5a0b9bdffa34b35479853d24e547cfde8 (diff) | |
| parent | 75984df05d86956541795f01e62d7dc67bc522fd (diff) | |
Merge tag 'for-3.8-at91_header_clean' of git://github.com/at91linux/linux-at91 into next/headers
From Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>:
arm: at91: mach header cleanup
This first patch serie start the cleanup of the header in mach
by moving all the platform data to include/linux/platform_data
and move the board header and drivers header next to them
* tag 'for-3.8-at91_header_clean' of git://github.com/at91linux/linux-at91:
  arm: at91: move at91rm9200 rtc header in drivers/rtc
  arm: at91: move reset controller header to arm/arm/mach-at91
  arm: at91: move pit define to the driver
  arm: at91: move at91_shdwc.h to arch/arm/mach-at91
  arm: at91: move board header to arch/arm/mach-at91
  arn: at91: move at91_tc.h to arch/arm/mach-at91
  arm: at91 move at91_aic.h to arch/arm/mach-at91
  arm: at91 move board.h to arch/arm/mach-at91
  arm: at91: move platfarm_data to include/linux/platform_data/atmel.h
  arm: at91: drop machine defconfig
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/btrfs/send.c')
| -rw-r--r-- | fs/btrfs/send.c | 156 | 
1 files changed, 95 insertions, 61 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index c7beb543a4a..e78b297b0b0 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -745,31 +745,36 @@ typedef int (*iterate_inode_ref_t)(int num, u64 dir, int index,  				   void *ctx);  /* - * Helper function to iterate the entries in ONE btrfs_inode_ref. + * Helper function to iterate the entries in ONE btrfs_inode_ref or + * btrfs_inode_extref.   * The iterate callback may return a non zero value to stop iteration. This can   * be a negative value for error codes or 1 to simply stop it.   * - * path must point to the INODE_REF when called. + * path must point to the INODE_REF or INODE_EXTREF when called.   */  static int iterate_inode_ref(struct send_ctx *sctx,  			     struct btrfs_root *root, struct btrfs_path *path,  			     struct btrfs_key *found_key, int resolve,  			     iterate_inode_ref_t iterate, void *ctx)  { -	struct extent_buffer *eb; +	struct extent_buffer *eb = path->nodes[0];  	struct btrfs_item *item;  	struct btrfs_inode_ref *iref; +	struct btrfs_inode_extref *extref;  	struct btrfs_path *tmp_path;  	struct fs_path *p; -	u32 cur; -	u32 len; +	u32 cur = 0;  	u32 total; -	int slot; +	int slot = path->slots[0];  	u32 name_len;  	char *start;  	int ret = 0; -	int num; +	int num = 0;  	int index; +	u64 dir; +	unsigned long name_off; +	unsigned long elem_size; +	unsigned long ptr;  	p = fs_path_alloc_reversed(sctx);  	if (!p) @@ -781,24 +786,40 @@ static int iterate_inode_ref(struct send_ctx *sctx,  		return -ENOMEM;  	} -	eb = path->nodes[0]; -	slot = path->slots[0]; -	item = btrfs_item_nr(eb, slot); -	iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); -	cur = 0; -	len = 0; -	total = btrfs_item_size(eb, item); -	num = 0; +	if (found_key->type == BTRFS_INODE_REF_KEY) { +		ptr = (unsigned long)btrfs_item_ptr(eb, slot, +						    struct btrfs_inode_ref); +		item = btrfs_item_nr(eb, slot); +		total = btrfs_item_size(eb, item); +		elem_size = sizeof(*iref); +	} else { +		ptr = btrfs_item_ptr_offset(eb, slot); +		total = btrfs_item_size_nr(eb, slot); +		elem_size = sizeof(*extref); +	} +  	while (cur < total) {  		fs_path_reset(p); -		name_len = btrfs_inode_ref_name_len(eb, iref); -		index = btrfs_inode_ref_index(eb, iref); +		if (found_key->type == BTRFS_INODE_REF_KEY) { +			iref = (struct btrfs_inode_ref *)(ptr + cur); +			name_len = btrfs_inode_ref_name_len(eb, iref); +			name_off = (unsigned long)(iref + 1); +			index = btrfs_inode_ref_index(eb, iref); +			dir = found_key->offset; +		} else { +			extref = (struct btrfs_inode_extref *)(ptr + cur); +			name_len = btrfs_inode_extref_name_len(eb, extref); +			name_off = (unsigned long)&extref->name; +			index = btrfs_inode_extref_index(eb, extref); +			dir = btrfs_inode_extref_parent(eb, extref); +		} +  		if (resolve) { -			start = btrfs_iref_to_path(root, tmp_path, iref, eb, -						found_key->offset, p->buf, -						p->buf_len); +			start = btrfs_ref_to_path(root, tmp_path, name_len, +						  name_off, eb, dir, +						  p->buf, p->buf_len);  			if (IS_ERR(start)) {  				ret = PTR_ERR(start);  				goto out; @@ -809,9 +830,10 @@ static int iterate_inode_ref(struct send_ctx *sctx,  						p->buf_len + p->buf - start);  				if (ret < 0)  					goto out; -				start = btrfs_iref_to_path(root, tmp_path, iref, -						eb, found_key->offset, p->buf, -						p->buf_len); +				start = btrfs_ref_to_path(root, tmp_path, +							  name_len, name_off, +							  eb, dir, +							  p->buf, p->buf_len);  				if (IS_ERR(start)) {  					ret = PTR_ERR(start);  					goto out; @@ -820,21 +842,16 @@ static int iterate_inode_ref(struct send_ctx *sctx,  			}  			p->start = start;  		} else { -			ret = fs_path_add_from_extent_buffer(p, eb, -					(unsigned long)(iref + 1), name_len); +			ret = fs_path_add_from_extent_buffer(p, eb, name_off, +							     name_len);  			if (ret < 0)  				goto out;  		} - -		len = sizeof(*iref) + name_len; -		iref = (struct btrfs_inode_ref *)((char *)iref + len); -		cur += len; - -		ret = iterate(num, found_key->offset, index, p, ctx); +		cur += elem_size + name_len; +		ret = iterate(num, dir, index, p, ctx);  		if (ret)  			goto out; -  		num++;  	} @@ -998,7 +1015,8 @@ static int get_inode_path(struct send_ctx *sctx, struct btrfs_root *root,  	}  	btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]);  	if (found_key.objectid != ino || -		found_key.type != BTRFS_INODE_REF_KEY) { +	    (found_key.type != BTRFS_INODE_REF_KEY && +	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {  		ret = -ENOENT;  		goto out;  	} @@ -1551,8 +1569,8 @@ static int get_first_ref(struct send_ctx *sctx,  	struct btrfs_key key;  	struct btrfs_key found_key;  	struct btrfs_path *path; -	struct btrfs_inode_ref *iref;  	int len; +	u64 parent_dir;  	path = alloc_path_for_send();  	if (!path) @@ -1568,27 +1586,41 @@ static int get_first_ref(struct send_ctx *sctx,  	if (!ret)  		btrfs_item_key_to_cpu(path->nodes[0], &found_key,  				path->slots[0]); -	if (ret || found_key.objectid != key.objectid || -	    found_key.type != key.type) { +	if (ret || found_key.objectid != ino || +	    (found_key.type != BTRFS_INODE_REF_KEY && +	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {  		ret = -ENOENT;  		goto out;  	} -	iref = btrfs_item_ptr(path->nodes[0], path->slots[0], -			struct btrfs_inode_ref); -	len = btrfs_inode_ref_name_len(path->nodes[0], iref); -	ret = fs_path_add_from_extent_buffer(name, path->nodes[0], -			(unsigned long)(iref + 1), len); +	if (key.type == BTRFS_INODE_REF_KEY) { +		struct btrfs_inode_ref *iref; +		iref = btrfs_item_ptr(path->nodes[0], path->slots[0], +				      struct btrfs_inode_ref); +		len = btrfs_inode_ref_name_len(path->nodes[0], iref); +		ret = fs_path_add_from_extent_buffer(name, path->nodes[0], +						     (unsigned long)(iref + 1), +						     len); +		parent_dir = found_key.offset; +	} else { +		struct btrfs_inode_extref *extref; +		extref = btrfs_item_ptr(path->nodes[0], path->slots[0], +					struct btrfs_inode_extref); +		len = btrfs_inode_extref_name_len(path->nodes[0], extref); +		ret = fs_path_add_from_extent_buffer(name, path->nodes[0], +					(unsigned long)&extref->name, len); +		parent_dir = btrfs_inode_extref_parent(path->nodes[0], extref); +	}  	if (ret < 0)  		goto out;  	btrfs_release_path(path); -	ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL, +	ret = get_inode_info(root, parent_dir, NULL, dir_gen, NULL, NULL,  			NULL, NULL);  	if (ret < 0)  		goto out; -	*dir = found_key.offset; +	*dir = parent_dir;  out:  	btrfs_free_path(path); @@ -2430,7 +2462,8 @@ verbose_printk("btrfs: send_create_inode %llu\n", ino);  		TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p);  	} else if (S_ISCHR(mode) || S_ISBLK(mode) ||  		   S_ISFIFO(mode) || S_ISSOCK(mode)) { -		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, rdev); +		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev)); +		TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode);  	}  	ret = send_cmd(sctx); @@ -3226,7 +3259,8 @@ static int process_all_refs(struct send_ctx *sctx,  		btrfs_item_key_to_cpu(eb, &found_key, slot);  		if (found_key.objectid != key.objectid || -		    found_key.type != key.type) +		    (found_key.type != BTRFS_INODE_REF_KEY && +		     found_key.type != BTRFS_INODE_EXTREF_KEY))  			break;  		ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb, @@ -3987,7 +4021,7 @@ static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end)  	if (sctx->cur_ino == 0)  		goto out;  	if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid && -	    sctx->cmp_key->type <= BTRFS_INODE_REF_KEY) +	    sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY)  		goto out;  	if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs))  		goto out; @@ -4033,22 +4067,21 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)  	if (ret < 0)  		goto out; -	if (!S_ISLNK(sctx->cur_inode_mode)) { -		if (!sctx->parent_root || sctx->cur_inode_new) { +	if (!sctx->parent_root || sctx->cur_inode_new) { +		need_chown = 1; +		if (!S_ISLNK(sctx->cur_inode_mode))  			need_chmod = 1; -			need_chown = 1; -		} else { -			ret = get_inode_info(sctx->parent_root, sctx->cur_ino, -					NULL, NULL, &right_mode, &right_uid, -					&right_gid, NULL); -			if (ret < 0) -				goto out; +	} else { +		ret = get_inode_info(sctx->parent_root, sctx->cur_ino, +				NULL, NULL, &right_mode, &right_uid, +				&right_gid, NULL); +		if (ret < 0) +			goto out; -			if (left_uid != right_uid || left_gid != right_gid) -				need_chown = 1; -			if (left_mode != right_mode) -				need_chmod = 1; -		} +		if (left_uid != right_uid || left_gid != right_gid) +			need_chown = 1; +		if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode) +			need_chmod = 1;  	}  	if (S_ISREG(sctx->cur_inode_mode)) { @@ -4335,7 +4368,8 @@ static int changed_cb(struct btrfs_root *left_root,  	if (key->type == BTRFS_INODE_ITEM_KEY)  		ret = changed_inode(sctx, result); -	else if (key->type == BTRFS_INODE_REF_KEY) +	else if (key->type == BTRFS_INODE_REF_KEY || +		 key->type == BTRFS_INODE_EXTREF_KEY)  		ret = changed_ref(sctx, result);  	else if (key->type == BTRFS_XATTR_ITEM_KEY)  		ret = changed_xattr(sctx, result);  | 
