grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 4/4] xfs: V5 filesystem format support


From: Jan Kara
Subject: Re: [PATCH 4/4] xfs: V5 filesystem format support
Date: Tue, 12 May 2015 15:47:40 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue 12-05-15 08:23:40, Andrei Borzenkov wrote:
...

> > @@ -123,17 +144,6 @@ struct grub_xfs_inode
> >    grub_uint16_t unused3;
> >    grub_uint8_t fork_offset;
> >    grub_uint8_t unused4[17];
> > -  union
> > -  {
> > -    char raw[156];
> > -    struct dir
> > -    {
> > -      struct grub_xfs_dir_header dirhead;
> > -      struct grub_xfs_dir_entry direntry[1];
> > -    } dir;
> > -    grub_xfs_extent extents[XFS_INODE_EXTENTS];
> > -    struct grub_xfs_btree_root btree;
> > -  } GRUB_PACKED data;
> 
> Can we make it grub_uint8_t xfs_v3_extra[76] or similar to avoid magic
> numbers later when computing data offset?

  Well, depending on fs version the size of "base" inode is different. I
have added defines like:
#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)

That should make things clearer.

> >  } GRUB_PACKED;
> >  
> >  struct grub_xfs_dirblock_tail
> > @@ -157,6 +167,8 @@ struct grub_xfs_data
> >    int pos;
> >    int bsize;
> >    grub_uint32_t agsize;
> > +  unsigned int hasftype:1;
> > +  unsigned int hascrc:1;
> >    struct grub_fshelp_node diropen;
> >  };
> >  
> > @@ -164,6 +176,24 @@ static grub_dl_t my_mod;
> >  
> >  
> >  
> > +static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
> > +{
> > +  return (grub_be_to_cpu16(data->sblock.version) & XFS_SB_VERSION_NUMBITS) 
> > == 5;
> 
> Could you define name for magic constant?

  Done.

> Also to avoid run-time computation:
> data->sblock.version &
> grub_cpu_to_b16_compile_time(XFS_SB_VERSION_NUMBITS) ==
> grub_cpu_to_b16_compile_time(5)

  OK.

...
> > @@ -261,6 +279,96 @@ grub_xfs_inode_size(struct grub_xfs_data *data)
> >     return 1 << data->sblock.log2_inode;
> >  }
> >  
> > +static void *
> > +grub_xfs_inode_data(struct grub_xfs_inode *inode)
> > +{
> > +   if (inode->version <= 2)
> > +           return ((char *)inode) + 100;
> 
> That is sizeof(struct grub_xfs_inode) in your patch, right?
> 
> > +   return ((char *)inode) + 176;
> 
> Please avoid magic numbers. At least give it meaningful name, or as
> suggested above just define structure to contain it.

  Used defines above.

> > +}
> > +
> > +static struct grub_xfs_dir_entry *
> > +grub_xfs_inline_de(struct grub_xfs_dir_header *head)
> > +{
> > +   /*
> > +    * With small inode numbers the header is 4 bytes smaller because of
> > +    * smaller parent pointer
> > +    */
> > +   return (void *)(((char *)head) + sizeof(struct grub_xfs_dir_header) -
> > +           (head->largeino ? 0 : sizeof(grub_uint32_t)));
> > +}
> > +
> > +static grub_uint8_t *
> > +grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
> > +                     struct grub_xfs_dir_entry *de)
> > +{
> > +   return ((grub_uint8_t *)(de + 1)) + de->len - 1 +
> The outer parens are somehow confusing.

  I can remove them but I find it better to explicitely show where the
typecast happens with parenthesis...

> 
> > +            (data->hasftype ? 1 : 0);
> > +}
> > +
> > +static struct grub_xfs_dir_entry *
> > +grub_xfs_inline_next_de(struct grub_xfs_data *data,
> > +                   struct grub_xfs_dir_header *head,
> > +                   struct grub_xfs_dir_entry *de)
> > +{
> > +  char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;
> > +
> > +  p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
> > +  if (data->hasftype)
> > +    p++;
> > +     
> > +  return (struct grub_xfs_dir_entry *)p;
> > +}
> > +
> > +static struct grub_xfs_dirblock_tail *
> > +grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
> > +{
> > +  int dirblksize = 1 << (data->sblock.log2_bsize + 
> > data->sblock.log2_dirblk);
> > +
> > +  return (struct grub_xfs_dirblock_tail *)
> > +    ((char *)dirblock + dirblksize - sizeof (struct 
> > grub_xfs_dirblock_tail));
> > +}
> > +
> > +static struct grub_xfs_dir2_entry *
> > +grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
> > +{
> > +  if (data->hascrc)
> > +    return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
> > +  return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
> > +}
> > +
> > +static inline int
> > +grub_xfs_round_dirent_size (int len)
> > +{
> > +  return (len + 7) & ~7;
> > +}
> 
> ALIGN_UP?
> 
> > +
> > +static struct grub_xfs_dir2_entry *
> > +grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry 
> > *de)
> > +{
> > +  int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;
> > +
> > +  if (data->hasftype)
> > +    size++;                /* File type */
> > +  return (struct grub_xfs_dir2_entry *)
> > +                   (((char *)de) + grub_xfs_round_dirent_size (size));
> 
> What's wrong with ALIGN_UP (size, 8)?

Nothing. I wasn't aware grub has the macro. Replaced.

> > +}
> > +
> > +static grub_uint64_t *
> > +grub_xfs_btree_keys(struct grub_xfs_data *data,
> > +               struct grub_xfs_btree_node *leaf)
> > +{
> > +  char *p = (char *)(leaf + 1);
> > +
> > +  if (data->hascrc)
> > +    p += 48;       /* crc, uuid, ... */
> > +  /*
> > +   * We have to first type to void * to avoid complaints about possible
> > +   * alignment issues on some architectures
> > +   */
> > +  return (grub_uint64_t *)(void *)p;
> 
> Leaving it as grub_uint64_t keys and using &keys[6] would avoid this
> warning as well, not? Also having keys[0] will likely simplify other
> places as well (we do require GCC in any case).

Well, the trouble with this is that we'd need two structures defined -
one for crc-enabled fs and one for old fs. That seemed like a wasted effort
to me when we could do:
  if (data->hascrc)
    p += 48;    /* crc, uuid, ... */
like the above. The same holds for inodes, directory entries, etc. I'd
prefer not to bloat the code with structure definitions we don't actually
use but if you really insisted, I could do that. So what do you think?

                                                                Honza
-- 
Jan Kara <address@hidden>
SUSE Labs, CR



reply via email to

[Prev in Thread] Current Thread [Next in Thread]