linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Allison Henderson <allison.henderson@oracle.com>
To: Dave Chinner <david@fromorbit.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 02/17] Set up infastructure for deferred attribute operations
Date: Mon, 9 Oct 2017 14:25:04 -0700	[thread overview]
Message-ID: <acc1732a-7c7a-5a11-ace3-e052134b1590@oracle.com> (raw)
In-Reply-To: <20171009042026.GJ3666@dastard>



On 10/8/2017 9:20 PM, Dave Chinner wrote:
> 
> On Fri, Oct 06, 2017 at 03:05:33PM -0700, Allison Henderson wrote:
>> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> hi Allison,
> 
> I'm just having a quick browse, not a complete review. This is a
> really good start for deferred attributes, but I think there's bits
> we'll have to redesign slightly for performance reasons.
> 
> First: needs a commit message to describe the design and structure,
> so the reviewer is not left to guess. :P
> 
>> ---
>> :100644 100644 b3edd66... 8d2c152... M	fs/xfs/Makefile
>> :100644 100644 b00ec1f... 5325ec2... M	fs/xfs/libxfs/xfs_attr.c
>> :100644 100644 2ea26b1... 38ae64a... M	fs/xfs/libxfs/xfs_attr_leaf.c
>> :100644 100644 d4f046d... ef0f8bf... M	fs/xfs/libxfs/xfs_defer.h
>> :100644 100644 8372e9b... 3778c8e... M	fs/xfs/libxfs/xfs_log_format.h
>> :100644 100644 0220159... 5372063... M	fs/xfs/libxfs/xfs_types.h
>> :100644 100644 8542606... 06c4081... M	fs/xfs/xfs_attr.h
>> :000000 100644 0000000... 419f90a... A	fs/xfs/xfs_attr_item.c
>> :000000 100644 0000000... aec854f... A	fs/xfs/xfs_attr_item.h
>> :100644 100644 d9a3a55... a206d51... M	fs/xfs/xfs_super.c
>> :100644 100644 815b53d2.. 66c3c5f... M	fs/xfs/xfs_trans.h
>> :000000 100644 0000000... 183c841... A	fs/xfs/xfs_trans_attr.c
> 
> This info isn't needed. Diffstat is sufficient.
> 
>> @@ -254,7 +261,9 @@ typedef struct xfs_trans_header {
>>   	{ XFS_LI_CUI,		"XFS_LI_CUI" }, \
>>   	{ XFS_LI_CUD,		"XFS_LI_CUD" }, \
>>   	{ XFS_LI_BUI,		"XFS_LI_BUI" }, \
>> -	{ XFS_LI_BUD,		"XFS_LI_BUD" }
>> +	{ XFS_LI_BUD,		"XFS_LI_BUD" }, \
>> +	{ XFS_LI_ATTRI,		"XFS_LI_ATTRI" }, \
>> +	{ XFS_LI_ATTRD,		"XFS_LI_ATTRD" }
> 
> "attr intent", "attr done"?
> 
> What object/action are we taking here? Set, flip-flags or remove? Or
> something else?
> 

Yes, "intent" and "done" was the idea I was going for. The actions are 
set and remove. The info needed for both operations seemed similar 
enough that it seemed excessive to make another intent/done type.  The 
xfs_attr struct has an attr_op_flags that marks it as a set or a remove 
action.  I will add some comments in the code to help clarify.


>>   
>>   /*
>>    * Inode Log Item Format definitions.
>> @@ -863,4 +872,45 @@ struct xfs_icreate_log {
>>   	__be32		icl_gen;	/* inode generation number to use */
>>   };
>>   
>> +/* Flags for defered attribute operations */
>> +#define ATTR_OP_FLAGS_SET	0x01	/* Set the attribute */
>> +#define ATTR_OP_FLAGS_REMOVE	0x02	/* Remove the attribute */
>> +#define ATTR_OP_FLAGS_MAX	0x02	/* Max flags */
>> +
>> +/*
>> + * ATTRI/ATTRD log format definitions
>> + */
>> +struct xfs_attr {
>> +	xfs_ino_t	attr_ino;
>> +	uint32_t	attr_op_flags;
>> +	uint32_t	attr_nameval_len;
>> +	uint32_t	attr_name_len;
>> +	uint32_t        attr_flags;
>> +	uint8_t		attr_nameval[MAX_NAMEVAL_LEN];
>> +};
> 
> "struct xfs_attr" is very generic. This ends up in the log on disk,
> right? So it's a log format structure? struct xfs_attr_log_format?
> 
> This also needs padding to ensure it's size is 64bit aligned.
> 
>> +/*
>> + * This is the structure used to lay out an attri log item in the
>> + * log.  The attri_attrs field is a variable size array whose
>> + * size is given by attri_nattrs.
>> + */
>> +struct xfs_attri_log_format {
>> +	uint16_t		attri_type;	/* attri log item type */
>> +	uint16_t		attri_size;	/* size of this item */
>> +	uint64_t		attri_id;	/* attri identifier */
>> +	struct xfs_attr		attri_attr;	/* attribute */
>> +};
> 
> That's got a 4 byte hole in it between attri_size and attri_id,
> so needs explicit padding. What's attri_id supposed to be and how is
> it used?
> 
> Also, i'd drop the "attri" from these, so.....


Hmm, I don't think attri_id is used.  I had used the extent free intent 
code as a sort of template for this and probably missed culling out the 
id.  I will get this struct cleaned up and padded out.

> 
>> +
>> +/*
>> + * This is the structure used to lay out an attrd log item in the
>> + * log.  The attrd_attrs array is a variable size array whose
>> + * size is given by attrd_nattrs;
>> + */
>> +struct xfs_attrd_log_format {
>> +	uint16_t		attrd_type;	/* attrd log item type */
>> +	uint16_t		attrd_size;	/* size of this item */
>> +	uint64_t		attrd_attri_id;	/* id of corresponding attri */
>> +	struct xfs_attr		attrd_attr;	/* attribute */
>> +};
> 
> .... these can use the same struct xfs_attr_log_format structure.
> 

Alrighty

>>   #endif /* __XFS_LOG_FORMAT_H__ */
>> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
>> index 0220159..5372063 100644
>> --- a/fs/xfs/libxfs/xfs_types.h
>> +++ b/fs/xfs/libxfs/xfs_types.h
>> @@ -23,6 +23,7 @@ typedef uint32_t	prid_t;		/* project ID */
>>   typedef uint32_t	xfs_agblock_t;	/* blockno in alloc. group */
>>   typedef uint32_t	xfs_agino_t;	/* inode # within allocation grp */
>>   typedef uint32_t	xfs_extlen_t;	/* extent length in blocks */
>> +typedef uint32_t	xfs_attrlen_t;	/* attr length */
>>   typedef uint32_t	xfs_agnumber_t;	/* allocation group number */
>>   typedef int32_t		xfs_extnum_t;	/* # of extents in a file */
>>   typedef int16_t		xfs_aextnum_t;	/* # extents in an attribute fork */
>> diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
>> index 8542606..06c4081 100644
>> --- a/fs/xfs/xfs_attr.h
>> +++ b/fs/xfs/xfs_attr.h
>> @@ -18,6 +18,8 @@
>>   #ifndef __XFS_ATTR_H__
>>   #define	__XFS_ATTR_H__
>>   
>> +#include "libxfs/xfs_defer.h"
>> +
>>   struct xfs_inode;
>>   struct xfs_da_args;
>>   struct xfs_attr_list_context;
>> @@ -65,6 +67,10 @@ struct xfs_attr_list_context;
>>    */
>>   #define	ATTR_MAX_VALUELEN	(64*1024)	/* max length of a value */
>>   
>> +/* Max name length in the xfs_attr_item */
>> +#define MAX_NAME_LEN		255
> 
> Should be defined in xfs_da_format.h where the entries and
> name length types are defined. SHould also try to derive it from
> the namelen variable of one of the types rather than hard code it.
> 
>> +#define MAX_NAMEVAL_LEN (MAX_NAME_LEN + ATTR_MAX_VALUELEN)
> 
> as should this, I think.
>> +
>>   /*
>>    * Define how lists of attribute names are returned to the user from
>>    * the attr_list() call.  A large, 32bit aligned, buffer is passed in
>> @@ -87,6 +93,19 @@ typedef struct attrlist_ent {	/* data from attr_list() */
>>   } attrlist_ent_t;
>>   
>>   /*
>> + * List of attrs to commit later.
>> + */
>> +struct xfs_attr_item {
>> +	xfs_ino_t	  xattri_ino;
>> +	uint32_t	  xattri_op_flags;
>> +	uint32_t	  xattri_nameval_len; /* length of name and val */
>> +	uint32_t	  xattri_name_len;    /* length of name */
>> +	uint32_t	  xattri_flags;       /* attr flags */
>> +	char		  xattri_nameval[MAX_NAMEVAL_LEN];
>> +	struct list_head  xattri_list;
>> +};
> 
> Ok, that's a ~65kB structure.
> 
> Oh, that means the ATTRI/ATTRD log format structures are also 65kB
> structures. That's going to need fixing - that far too big an
> allocation to be doing for tiny little xattrs like parent pointers.
> 

Ok, I will see if I can come up with something more dynamic.

> 
> 
>> +xfs_attri_item_free(
>> +	struct xfs_attri_log_item	*attrip)
>> +{
>> +	kmem_free(attrip->attri_item.li_lv_shadow);
>> +	kmem_free(attrip);
>> +}
>> +
>> +/*
>> + * This returns the number of iovecs needed to log the given attri item.
>> + * We only need 1 iovec for an attri item.  It just logs the attri_log_format
>> + * structure.
>> + */
>> +static inline int
>> +xfs_attri_item_sizeof(
>> +	struct xfs_attri_log_item *attrip)
>> +{
>> +	return sizeof(struct xfs_attri_log_format);
>> +}
>> +
>> +STATIC void
>> +xfs_attri_item_size(
>> +	struct xfs_log_item	*lip,
>> +	int			*nvecs,
>> +	int			*nbytes)
>> +{
>> +	*nvecs += 1;
>> +	*nbytes += xfs_attri_item_sizeof(ATTRI_ITEM(lip));
>> +}
> 
> This will trigger 65kB allocations.....
> 
>> +
>> +/*
>> + * This is called to fill in the vector of log iovecs for the
>> + * given attri log item. We use only 1 iovec, and we point that
>> + * at the attri_log_format structure embedded in the attri item.
>> + * It is at this point that we assert that all of the attr
>> + * slots in the attri item have been filled.
>> + */
>> +STATIC void
>> +xfs_attri_item_format(
>> +	struct xfs_log_item	*lip,
>> +	struct xfs_log_vec	*lv)
>> +{
>> +	struct xfs_attri_log_item	*attrip = ATTRI_ITEM(lip);
>> +	struct xfs_log_iovec	*vecp = NULL;
>> +
>> +	attrip->attri_format.attri_type = XFS_LI_ATTRI;
>> +	attrip->attri_format.attri_size = 1;
>> +
>> +	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTRI_FORMAT,
>> +			&attrip->attri_format,
>> +			xfs_attri_item_sizeof(attrip));
>> +}
> 
> ANd we'll always copy 65kB structures here even if the attribute
> is only a few tens of bytes. That's just going to burn through log
> bandwidth and really needs fixing.
> 
> THe log item (and log format) structures really need to point to the
> attribute name/value information rather than contain copies of them.
> That way the information that is logged and the allocations required
> are sized exactly for the attribute being created/removed. The cost
> of dynamically allocating the buffers is less than the cost of
> unnecessarily copying and logging 64k on eveery attribute operation.
> 
> Indeed, for a remove operation there is no value, so we should only
> be logging an intent with a name (a few tens of bytes), not a 65kb
> structure....
> 
> I'll stop here for the moment, because most of this code is going to
> change to support dynamic allocation of name/value buffers, anyway.
> 
> Cheers,
> 
> Dave.
> 

Alrighty, thanks for the review Dave.  I will work on getting these 
things updated and send out another set once I get it working.

Thank you!

Allison Henderson

  reply	other threads:[~2017-10-09 21:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-06 22:05 [PATCH 00/17] Parent Pointers V2 Allison Henderson
2017-10-06 22:05 ` [PATCH 01/17] Add helper functions xfs_attr_set_args and xfs_attr_remove_args Allison Henderson
2017-10-06 22:05 ` [PATCH 02/17] Set up infastructure for deferred attribute operations Allison Henderson
2017-10-09  4:20   ` Dave Chinner
2017-10-09 21:25     ` Allison Henderson [this message]
2017-10-09 22:51       ` Allison Henderson
2017-10-09 23:27         ` Dave Chinner
2017-10-06 22:05 ` [PATCH 03/17] Add xfs_attr_set_defered and xfs_attr_remove_defered Allison Henderson
2017-10-12  4:38   ` Darrick J. Wong
2017-10-06 22:05 ` [PATCH 04/17] Remove all strlen calls in all xfs_attr_* functions for attr names Allison Henderson
2017-10-06 22:05 ` [PATCH 05/17] xfs: get directory offset when adding directory name Allison Henderson
2017-10-06 22:05 ` [PATCH 06/17] xfs: get directory offset when removing " Allison Henderson
2017-10-06 22:05 ` [PATCH 07/17] xfs: get directory offset when replacing a " Allison Henderson
2017-10-06 22:05 ` [PATCH 08/17] xfs: add parent pointer support to attribute code Allison Henderson
2017-10-06 22:05 ` [PATCH 09/17] xfs: define parent pointer xattr format Allison Henderson
2017-10-06 22:05 ` [PATCH 10/17] :xfs: extent transaction reservations for parent attributes Allison Henderson
2017-10-06 22:05 ` [PATCH 11/17] Add the extra space requirements for parent pointer attributes when calculating the minimum log size during mkfs Allison Henderson
2017-10-06 22:05 ` [PATCH 12/17] xfs: parent pointer attribute creation Allison Henderson
2017-10-06 22:05 ` [PATCH 13/17] xfs: add parent attributes to link Allison Henderson
2017-10-06 22:05 ` [PATCH 14/17] xfs: remove parent pointers in unlink Allison Henderson
2017-10-06 22:05 ` [PATCH 15/17] xfs_bmap_add_attrfork(): re-add error handling from set_attrforkoff() call Allison Henderson
2017-10-06 22:05 ` [PATCH 16/17] Add parent pointers to rename Allison Henderson
2017-10-06 22:05 ` [PATCH 17/17] Add the parent pointer support to the superblock version 5 Allison Henderson
  -- strict thread matches above, loose matches on Subject: below --
2017-10-18 22:55 [PATCH 00/17] Parent Pointers V3 Allison Henderson
2017-10-18 22:55 ` [PATCH 02/17] Set up infastructure for deferred attribute operations Allison Henderson
2017-10-19 19:02   ` Darrick J. Wong
2017-10-21  1:08     ` Allison Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=acc1732a-7c7a-5a11-ace3-e052134b1590@oracle.com \
    --to=allison.henderson@oracle.com \
    --cc=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).