All of lore.kernel.org
 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 15:51:42 -0700	[thread overview]
Message-ID: <8dafd7c1-fd4e-6ec4-28dd-72d4eeff602c@oracle.com> (raw)
In-Reply-To: <acc1732a-7c7a-5a11-ace3-e052134b1590@oracle.com>



On 10/09/2017 02:25 PM, Allison Henderson wrote:
>
>
> 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.
>>
Hmm, if this structure is meant to be stored on disk, is it really a 
good idea to put pointers in here as you mentioned in your conclusion 
below?  If we get remounted or rebooted and loose the pointer that may 
not work.  Or am I not understanding what you meant?

>>> +/*
>>> + * 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
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at 
> https://urldefense.proofpoint.com/v2/url?u=http-3A__vger.kernel.org_majordomo-2Dinfo.html&d=DwICaQ&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XFp4B05bcXkJ0dhYaFjd3F8telP01COkBp9cI7mKLb4&m=nw_o5VNTP1pgN6tnmVUK8si19OGGbovdt9cIHgFXjww&s=TVRphCUEAJj2sjtglo4hDCrG8TqgKrNeG3GP5bVT2Oo&e= 



  reply	other threads:[~2017-10-09 22:51 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
2017-10-09 22:51       ` Allison Henderson [this message]
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
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=8dafd7c1-fd4e-6ec4-28dd-72d4eeff602c@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.