2017-03-16 22:18:50 -08:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_INODE_H
# define _BCACHEFS_INODE_H
# include "opts.h"
2018-12-17 05:31:09 -05:00
extern const char * const bch2_inode_opts [ ] ;
2017-03-16 22:18:50 -08:00
const char * bch2_inode_invalid ( const struct bch_fs * , struct bkey_s_c ) ;
2021-10-29 21:14:23 -04:00
const char * bch2_inode_v2_invalid ( const struct bch_fs * , struct bkey_s_c ) ;
2018-11-09 01:24:07 -05:00
void bch2_inode_to_text ( struct printbuf * , struct bch_fs * , struct bkey_s_c ) ;
2017-03-16 22:18:50 -08:00
2018-11-01 15:10:01 -04:00
# define bch2_bkey_ops_inode (struct bkey_ops) { \
2017-03-16 22:18:50 -08:00
. key_invalid = bch2_inode_invalid , \
. val_to_text = bch2_inode_to_text , \
}
2021-10-29 21:14:23 -04:00
# define bch2_bkey_ops_inode_v2 (struct bkey_ops) { \
. key_invalid = bch2_inode_v2_invalid , \
. val_to_text = bch2_inode_to_text , \
}
static inline bool bkey_is_inode ( const struct bkey * k )
{
return k - > type = = KEY_TYPE_inode | |
k - > type = = KEY_TYPE_inode_v2 ;
}
2018-11-01 15:10:01 -04:00
const char * bch2_inode_generation_invalid ( const struct bch_fs * ,
struct bkey_s_c ) ;
void bch2_inode_generation_to_text ( struct printbuf * , struct bch_fs * ,
struct bkey_s_c ) ;
# define bch2_bkey_ops_inode_generation (struct bkey_ops) { \
. key_invalid = bch2_inode_generation_invalid , \
. val_to_text = bch2_inode_generation_to_text , \
}
2020-11-05 23:39:33 -05:00
#if 0
typedef struct {
u64 lo ;
u32 hi ;
} __packed __aligned ( 4 ) u96 ;
# endif
typedef u64 u96 ;
2017-03-16 22:18:50 -08:00
struct bch_inode_unpacked {
u64 bi_inum ;
2021-10-29 21:14:23 -04:00
u64 bi_journal_seq ;
2017-03-16 22:18:50 -08:00
__le64 bi_hash_seed ;
u32 bi_flags ;
u16 bi_mode ;
2018-12-13 06:01:30 -05:00
# define x(_name, _bits) u##_bits _name;
2017-03-16 22:18:50 -08:00
BCH_INODE_FIELDS ( )
2018-12-13 06:01:30 -05:00
# undef x
2017-03-16 22:18:50 -08:00
} ;
struct bkey_inode_buf {
2021-10-29 21:14:23 -04:00
struct bkey_i_inode_v2 inode ;
2017-03-16 22:18:50 -08:00
2018-12-13 06:01:30 -05:00
# define x(_name, _bits) + 8 + _bits / 8
2017-03-16 22:18:50 -08:00
u8 _pad [ 0 + BCH_INODE_FIELDS ( ) ] ;
2018-12-13 06:01:30 -05:00
# undef x
2017-03-16 22:18:50 -08:00
} __attribute__ ( ( packed , aligned ( 8 ) ) ) ;
2020-11-05 23:39:33 -05:00
void bch2_inode_pack ( struct bch_fs * , struct bkey_inode_buf * ,
const struct bch_inode_unpacked * ) ;
2021-10-29 21:14:23 -04:00
int bch2_inode_unpack ( struct bkey_s_c , struct bch_inode_unpacked * ) ;
2017-03-16 22:18:50 -08:00
2021-07-30 17:59:37 -04:00
void bch2_inode_unpacked_to_text ( struct printbuf * , struct bch_inode_unpacked * ) ;
2021-08-30 15:18:31 -04:00
int bch2_inode_peek ( struct btree_trans * , struct btree_iter * ,
2021-03-16 00:28:17 -04:00
struct bch_inode_unpacked * , subvol_inum , unsigned ) ;
2019-10-01 16:51:57 -04:00
int bch2_inode_write ( struct btree_trans * , struct btree_iter * ,
struct bch_inode_unpacked * ) ;
2019-10-02 18:35:36 -04:00
void bch2_inode_init_early ( struct bch_fs * ,
struct bch_inode_unpacked * ) ;
void bch2_inode_init_late ( struct bch_inode_unpacked * , u64 ,
uid_t , gid_t , umode_t , dev_t ,
struct bch_inode_unpacked * ) ;
2017-03-16 22:18:50 -08:00
void bch2_inode_init ( struct bch_fs * , struct bch_inode_unpacked * ,
uid_t , gid_t , umode_t , dev_t ,
struct bch_inode_unpacked * ) ;
2021-08-30 15:18:31 -04:00
int bch2_inode_create ( struct btree_trans * , struct btree_iter * ,
struct bch_inode_unpacked * , u32 , u64 ) ;
2017-03-16 22:18:50 -08:00
2022-01-12 02:13:21 -05:00
int bch2_inode_rm ( struct bch_fs * , subvol_inum ) ;
2017-03-16 22:18:50 -08:00
2021-11-06 00:03:40 -04:00
int bch2_inode_find_by_inum_trans ( struct btree_trans * , subvol_inum ,
struct bch_inode_unpacked * ) ;
2021-03-16 00:28:17 -04:00
int bch2_inode_find_by_inum ( struct bch_fs * , subvol_inum ,
struct bch_inode_unpacked * ) ;
2017-03-16 22:18:50 -08:00
static inline struct bch_io_opts bch2_inode_opts_get ( struct bch_inode_unpacked * inode )
{
struct bch_io_opts ret = { 0 } ;
2018-12-13 06:01:30 -05:00
# define x(_name, _bits) \
2017-03-16 22:18:50 -08:00
if ( inode - > bi_ # # _name ) \
opt_set ( ret , _name , inode - > bi_ # # _name - 1 ) ;
BCH_INODE_OPTS ( )
2018-12-13 06:01:30 -05:00
# undef x
2017-03-16 22:18:50 -08:00
return ret ;
}
2018-12-17 05:31:09 -05:00
static inline void bch2_inode_opt_set ( struct bch_inode_unpacked * inode ,
enum inode_opt_id id , u64 v )
2017-03-16 22:18:50 -08:00
{
switch ( id ) {
2018-12-17 05:31:09 -05:00
# define x(_name, ...) \
case Inode_opt_ # # _name : \
2017-03-16 22:18:50 -08:00
inode - > bi_ # # _name = v ; \
break ;
BCH_INODE_OPTS ( )
2018-12-13 06:01:30 -05:00
# undef x
2017-03-16 22:18:50 -08:00
default :
BUG ( ) ;
}
}
2018-12-17 05:31:09 -05:00
static inline u64 bch2_inode_opt_get ( struct bch_inode_unpacked * inode ,
enum inode_opt_id id )
2017-03-16 22:18:50 -08:00
{
2018-12-17 05:31:09 -05:00
switch ( id ) {
# define x(_name, ...) \
case Inode_opt_ # # _name : \
return inode - > bi_ # # _name ;
BCH_INODE_OPTS ( )
# undef x
default :
BUG ( ) ;
}
2017-03-16 22:18:50 -08:00
}
2019-10-09 12:50:39 -04:00
static inline struct bch_io_opts
io_opts ( struct bch_fs * c , struct bch_inode_unpacked * inode )
{
struct bch_io_opts opts = bch2_opts_to_inode_opts ( c - > opts ) ;
bch2_io_opts_apply ( & opts , bch2_inode_opts_get ( inode ) ) ;
return opts ;
}
2019-10-02 18:35:36 -04:00
static inline u8 mode_to_type ( umode_t mode )
{
return ( mode > > 12 ) & 15 ;
}
2021-10-28 16:16:55 -04:00
static inline u8 inode_d_type ( struct bch_inode_unpacked * inode )
{
return inode - > bi_subvol ? DT_SUBVOL : mode_to_type ( inode - > bi_mode ) ;
}
2019-09-25 16:19:52 -04:00
/* i_nlink: */
static inline unsigned nlink_bias ( umode_t mode )
{
return S_ISDIR ( mode ) ? 2 : 1 ;
}
static inline void bch2_inode_nlink_inc ( struct bch_inode_unpacked * bi )
{
if ( bi - > bi_flags & BCH_INODE_UNLINKED )
bi - > bi_flags & = ~ BCH_INODE_UNLINKED ;
else
bi - > bi_nlink + + ;
}
static inline void bch2_inode_nlink_dec ( struct bch_inode_unpacked * bi )
{
BUG_ON ( bi - > bi_flags & BCH_INODE_UNLINKED ) ;
if ( bi - > bi_nlink )
bi - > bi_nlink - - ;
else
bi - > bi_flags | = BCH_INODE_UNLINKED ;
}
static inline unsigned bch2_inode_nlink_get ( struct bch_inode_unpacked * bi )
{
return bi - > bi_flags & BCH_INODE_UNLINKED
? 0
: bi - > bi_nlink + nlink_bias ( bi - > bi_mode ) ;
}
static inline void bch2_inode_nlink_set ( struct bch_inode_unpacked * bi ,
unsigned nlink )
{
if ( nlink ) {
bi - > bi_nlink = nlink - nlink_bias ( bi - > bi_mode ) ;
bi - > bi_flags & = ~ BCH_INODE_UNLINKED ;
} else {
bi - > bi_nlink = 0 ;
bi - > bi_flags | = BCH_INODE_UNLINKED ;
}
}
2017-03-16 22:18:50 -08:00
# endif /* _BCACHEFS_INODE_H */