2020-05-12 16:54:17 -07:00
/* SPDX-License-Identifier: GPL-2.0 */
2005-04-16 15:20:36 -07:00
/*
2005-11-02 14:58:39 +11:00
* Copyright ( c ) 2000 - 2001 , 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-16 15:20:36 -07:00
*/
# ifndef __XFS_DIR2_H__
2011-07-13 13:43:48 +02:00
# define __XFS_DIR2_H__
2005-04-16 15:20:36 -07:00
2017-01-17 11:41:42 -08:00
# include "xfs_da_format.h"
# include "xfs_da_btree.h"
2011-07-13 13:43:48 +02:00
struct xfs_da_args ;
2005-04-16 15:20:36 -07:00
struct xfs_inode ;
2006-06-20 13:04:51 +10:00
struct xfs_mount ;
2005-04-16 15:20:36 -07:00
struct xfs_trans ;
2013-08-12 20:49:37 +10:00
struct xfs_dir2_sf_hdr ;
struct xfs_dir2_sf_entry ;
struct xfs_dir2_data_hdr ;
struct xfs_dir2_data_entry ;
struct xfs_dir2_data_unused ;
2019-11-08 14:52:06 -08:00
struct xfs_dir3_icfree_hdr ;
struct xfs_dir3_icleaf_hdr ;
2005-04-16 15:20:36 -07:00
2022-03-09 10:16:12 -08:00
extern const struct xfs_name xfs_name_dotdot ;
2024-02-22 12:30:48 -08:00
extern const struct xfs_name xfs_name_dot ;
2008-04-10 12:22:07 +10:00
2024-02-22 12:30:49 -08:00
static inline bool
xfs_dir2_samename (
const struct xfs_name * n1 ,
const struct xfs_name * n2 )
{
if ( n1 = = n2 )
return true ;
if ( n1 - > len ! = n2 - > len )
return false ;
return ! memcmp ( n1 - > name , n2 - > name , n1 - > len ) ;
}
2014-12-04 09:43:17 +11:00
/*
2017-01-17 11:41:43 -08:00
* Convert inode mode to directory entry filetype
2014-12-04 09:43:17 +11:00
*/
2017-01-18 12:39:21 -08:00
extern unsigned char xfs_mode_to_ftype ( int mode ) ;
2014-12-04 09:43:17 +11:00
2005-04-16 15:20:36 -07:00
/*
2006-06-20 13:04:51 +10:00
* Generic directory interface routines
*/
extern void xfs_dir_startup ( void ) ;
2014-06-06 15:01:58 +10:00
extern int xfs_da_mount ( struct xfs_mount * mp ) ;
extern void xfs_da_unmount ( struct xfs_mount * mp ) ;
2006-06-20 13:04:51 +10:00
extern int xfs_dir_isempty ( struct xfs_inode * dp ) ;
extern int xfs_dir_init ( struct xfs_trans * tp , struct xfs_inode * dp ,
struct xfs_inode * pdp ) ;
extern int xfs_dir_createname ( struct xfs_trans * tp , struct xfs_inode * dp ,
2022-03-09 10:16:09 -08:00
const struct xfs_name * name , xfs_ino_t inum ,
2018-07-11 22:26:21 -07:00
xfs_extlen_t tot ) ;
2006-06-20 13:04:51 +10:00
extern int xfs_dir_lookup ( struct xfs_trans * tp , struct xfs_inode * dp ,
2022-03-09 10:16:09 -08:00
const struct xfs_name * name , xfs_ino_t * inum ,
2008-05-21 16:58:22 +10:00
struct xfs_name * ci_name ) ;
2006-06-20 13:04:51 +10:00
extern int xfs_dir_removename ( struct xfs_trans * tp , struct xfs_inode * dp ,
2008-04-10 12:22:07 +10:00
struct xfs_name * name , xfs_ino_t ino ,
2018-07-11 22:26:21 -07:00
xfs_extlen_t tot ) ;
2006-06-20 13:04:51 +10:00
extern int xfs_dir_replace ( struct xfs_trans * tp , struct xfs_inode * dp ,
2022-03-09 10:16:09 -08:00
const struct xfs_name * name , xfs_ino_t inum ,
2018-07-11 22:26:21 -07:00
xfs_extlen_t tot ) ;
2006-06-20 13:04:51 +10:00
extern int xfs_dir_canenter ( struct xfs_trans * tp , struct xfs_inode * dp ,
2014-09-09 11:57:52 +10:00
struct xfs_name * name ) ;
2006-06-20 13:04:51 +10:00
/*
2011-07-13 13:43:48 +02:00
* Direct call from the bmap code , bypassing the generic directory layer .
2005-04-16 15:20:36 -07:00
*/
2011-07-13 13:43:48 +02:00
extern int xfs_dir2_sf_to_block ( struct xfs_da_args * args ) ;
2008-05-21 16:58:22 +10:00
2013-08-12 20:49:37 +10:00
/*
* Interface routines used by userspace utilities
*/
2022-10-04 16:39:58 +11:00
extern int xfs_dir2_isblock ( struct xfs_da_args * args , bool * isblock ) ;
extern int xfs_dir2_isleaf ( struct xfs_da_args * args , bool * isleaf ) ;
2013-08-12 20:49:37 +10:00
extern int xfs_dir2_shrink_inode ( struct xfs_da_args * args , xfs_dir2_db_t db ,
struct xfs_buf * bp ) ;
2019-11-08 15:06:02 -08:00
extern void xfs_dir2_data_freescan ( struct xfs_mount * mp ,
2013-08-12 20:49:37 +10:00
struct xfs_dir2_data_hdr * hdr , int * loghead ) ;
2014-06-06 15:20:54 +10:00
extern void xfs_dir2_data_log_entry ( struct xfs_da_args * args ,
2013-10-29 22:11:48 +11:00
struct xfs_buf * bp , struct xfs_dir2_data_entry * dep ) ;
2014-06-06 15:20:54 +10:00
extern void xfs_dir2_data_log_header ( struct xfs_da_args * args ,
2013-08-12 20:49:37 +10:00
struct xfs_buf * bp ) ;
2014-06-06 15:20:54 +10:00
extern void xfs_dir2_data_log_unused ( struct xfs_da_args * args ,
struct xfs_buf * bp , struct xfs_dir2_data_unused * dup ) ;
extern void xfs_dir2_data_make_free ( struct xfs_da_args * args ,
2013-10-29 22:11:49 +11:00
struct xfs_buf * bp , xfs_dir2_data_aoff_t offset ,
xfs_dir2_data_aoff_t len , int * needlogp , int * needscanp ) ;
2018-03-23 10:06:51 -07:00
extern int xfs_dir2_data_use_free ( struct xfs_da_args * args ,
2013-10-29 22:11:49 +11:00
struct xfs_buf * bp , struct xfs_dir2_data_unused * dup ,
2013-08-12 20:49:37 +10:00
xfs_dir2_data_aoff_t offset , xfs_dir2_data_aoff_t len ,
int * needlogp , int * needscanp ) ;
extern struct xfs_dir2_data_free * xfs_dir2_data_freefind (
2013-10-29 22:11:49 +11:00
struct xfs_dir2_data_hdr * hdr , struct xfs_dir2_data_free * bf ,
struct xfs_dir2_data_unused * dup ) ;
2013-08-12 20:49:37 +10:00
2016-11-08 11:59:12 +11:00
extern int xfs_dir_ino_validate ( struct xfs_mount * mp , xfs_ino_t ino ) ;
2013-08-12 20:49:37 +10:00
extern const struct xfs_buf_ops xfs_dir3_block_buf_ops ;
extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops ;
extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops ;
extern const struct xfs_buf_ops xfs_dir3_free_buf_ops ;
extern const struct xfs_buf_ops xfs_dir3_data_buf_ops ;
2014-12-04 09:43:17 +11:00
/*
* Directory offset / block conversion functions .
*
* DB blocks here are logical directory block numbers , not filesystem blocks .
*/
/*
* Convert dataptr to byte in file space
*/
static inline xfs_dir2_off_t
xfs_dir2_dataptr_to_byte ( xfs_dir2_dataptr_t dp )
{
return ( xfs_dir2_off_t ) dp < < XFS_DIR2_DATA_ALIGN_LOG ;
}
/*
* Convert byte in file space to dataptr . It had better be aligned .
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr ( xfs_dir2_off_t by )
{
return ( xfs_dir2_dataptr_t ) ( by > > XFS_DIR2_DATA_ALIGN_LOG ) ;
}
/*
* Convert byte in space to ( DB ) block
*/
static inline xfs_dir2_db_t
xfs_dir2_byte_to_db ( struct xfs_da_geometry * geo , xfs_dir2_off_t by )
{
return ( xfs_dir2_db_t ) ( by > > geo - > blklog ) ;
}
/*
* Convert dataptr to a block number
*/
static inline xfs_dir2_db_t
xfs_dir2_dataptr_to_db ( struct xfs_da_geometry * geo , xfs_dir2_dataptr_t dp )
{
return xfs_dir2_byte_to_db ( geo , xfs_dir2_dataptr_to_byte ( dp ) ) ;
}
/*
* Convert byte in space to offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off ( struct xfs_da_geometry * geo , xfs_dir2_off_t by )
{
return ( xfs_dir2_data_aoff_t ) ( by & ( geo - > blksize - 1 ) ) ;
}
/*
* Convert dataptr to a byte offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off ( struct xfs_da_geometry * geo , xfs_dir2_dataptr_t dp )
{
return xfs_dir2_byte_to_off ( geo , xfs_dir2_dataptr_to_byte ( dp ) ) ;
}
/*
* Convert block and offset to byte in space
*/
static inline xfs_dir2_off_t
xfs_dir2_db_off_to_byte ( struct xfs_da_geometry * geo , xfs_dir2_db_t db ,
xfs_dir2_data_aoff_t o )
{
return ( ( xfs_dir2_off_t ) db < < geo - > blklog ) + o ;
}
/*
* Convert block ( DB ) to block ( dablk )
*/
static inline xfs_dablk_t
xfs_dir2_db_to_da ( struct xfs_da_geometry * geo , xfs_dir2_db_t db )
{
return ( xfs_dablk_t ) ( db < < ( geo - > blklog - geo - > fsblog ) ) ;
}
/*
* Convert byte in space to ( DA ) block
*/
static inline xfs_dablk_t
xfs_dir2_byte_to_da ( struct xfs_da_geometry * geo , xfs_dir2_off_t by )
{
return xfs_dir2_db_to_da ( geo , xfs_dir2_byte_to_db ( geo , by ) ) ;
}
/*
* Convert block and offset to dataptr
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr ( struct xfs_da_geometry * geo , xfs_dir2_db_t db ,
xfs_dir2_data_aoff_t o )
{
return xfs_dir2_byte_to_dataptr ( xfs_dir2_db_off_to_byte ( geo , db , o ) ) ;
}
/*
* Convert block ( dablk ) to block ( DB )
*/
static inline xfs_dir2_db_t
xfs_dir2_da_to_db ( struct xfs_da_geometry * geo , xfs_dablk_t da )
{
return ( xfs_dir2_db_t ) ( da > > ( geo - > blklog - geo - > fsblog ) ) ;
}
/*
* Convert block ( dablk ) to byte offset in space
*/
static inline xfs_dir2_off_t
xfs_dir2_da_to_byte ( struct xfs_da_geometry * geo , xfs_dablk_t da )
{
return xfs_dir2_db_off_to_byte ( geo , xfs_dir2_da_to_db ( geo , da ) , 0 ) ;
}
/*
* Directory tail pointer accessor functions . Based on block geometry .
*/
static inline struct xfs_dir2_block_tail *
xfs_dir2_block_tail_p ( struct xfs_da_geometry * geo , struct xfs_dir2_data_hdr * hdr )
{
return ( ( struct xfs_dir2_block_tail * )
( ( char * ) hdr + geo - > blksize ) ) - 1 ;
}
static inline struct xfs_dir2_leaf_tail *
xfs_dir2_leaf_tail_p ( struct xfs_da_geometry * geo , struct xfs_dir2_leaf * lp )
{
return ( struct xfs_dir2_leaf_tail * )
( ( char * ) lp + geo - > blksize -
sizeof ( struct xfs_dir2_leaf_tail ) ) ;
}
2017-10-17 21:37:44 -07:00
/*
* The Linux API doesn ' t pass down the total size of the buffer
* we read into down to the filesystem . With the filldir concept
* it ' s not needed for correct information , but the XFS dir2 leaf
* code wants an estimate of the buffer size to calculate it ' s
* readahead window and size the buffers used for mapping to
* physical blocks .
*
* Try to give it an estimate that ' s good enough , maybe at some
* point we can change the - > readdir prototype to include the
* buffer size . For now we use the current glibc buffer size .
* musl libc hardcodes 2 k and dietlibc uses PAGE_SIZE .
*/
# define XFS_READDIR_BUFSIZE (32768)
unsigned char xfs_dir3_get_dtype ( struct xfs_mount * mp , uint8_t filetype ) ;
2019-11-08 15:05:36 -08:00
unsigned int xfs_dir3_data_end_offset ( struct xfs_da_geometry * geo ,
2018-01-16 18:54:12 -08:00
struct xfs_dir2_data_hdr * hdr ) ;
2019-02-01 09:08:54 -08:00
bool xfs_dir2_namecheck ( const void * name , size_t length ) ;
2017-10-17 21:37:44 -07:00
2023-04-11 19:05:04 -07:00
/*
* The " ascii-ci " feature was created to speed up case - insensitive lookups for
* a Samba product . Because of the inherent problems with CI and UTF - 8
* encoding , etc , it was decided that Samba would be configured to export
* latin1 / iso 8859 - 1 encodings as that covered > 90 % of the target markets for
* the product . Hence the " ascii-ci " casefolding code could be encoded into
* the XFS directory operations and remove all the overhead of casefolding from
* Samba .
*
* To provide consistent hashing behavior between the userspace and kernel ,
* these functions prepare names for hashing by transforming specific bytes
* to other bytes . Robustness with other encodings is not guaranteed .
*/
static inline bool xfs_ascii_ci_need_xfrm ( unsigned char c )
{
if ( c > = 0x41 & & c < = 0x5a ) /* A-Z */
return true ;
if ( c > = 0xc0 & & c < = 0xd6 ) /* latin A-O with accents */
return true ;
if ( c > = 0xd8 & & c < = 0xde ) /* latin O-Y with accents */
return true ;
return false ;
}
static inline unsigned char xfs_ascii_ci_xfrm ( unsigned char c )
{
if ( xfs_ascii_ci_need_xfrm ( c ) )
c - = ' A ' - ' a ' ;
return c ;
}
2005-04-16 15:20:36 -07:00
# endif /* __XFS_DIR2_H__ */