162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/fs/hpfs/hpfs_fn.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * function headers 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci//#define DBG 1162306a36Sopenharmony_ci//#define DEBUG_LOCKS 1262306a36Sopenharmony_ci#ifdef pr_fmt 1362306a36Sopenharmony_ci#undef pr_fmt 1462306a36Sopenharmony_ci#endif 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <linux/mutex.h> 1962306a36Sopenharmony_ci#include <linux/pagemap.h> 2062306a36Sopenharmony_ci#include <linux/buffer_head.h> 2162306a36Sopenharmony_ci#include <linux/slab.h> 2262306a36Sopenharmony_ci#include <linux/sched/signal.h> 2362306a36Sopenharmony_ci#include <linux/blkdev.h> 2462306a36Sopenharmony_ci#include <asm/unaligned.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include "hpfs.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define EIOERROR EIO 2962306a36Sopenharmony_ci#define EFSERROR EUCLEAN 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define ANODE_ALLOC_FWD 512 3262306a36Sopenharmony_ci#define FNODE_ALLOC_FWD 0 3362306a36Sopenharmony_ci#define ALLOC_FWD_MIN 16 3462306a36Sopenharmony_ci#define ALLOC_FWD_MAX 128 3562306a36Sopenharmony_ci#define ALLOC_M 1 3662306a36Sopenharmony_ci#define FNODE_RD_AHEAD 16 3762306a36Sopenharmony_ci#define ANODE_RD_AHEAD 0 3862306a36Sopenharmony_ci#define DNODE_RD_AHEAD 72 3962306a36Sopenharmony_ci#define COUNT_RD_AHEAD 62 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define FREE_DNODES_ADD 58 4262306a36Sopenharmony_ci#define FREE_DNODES_DEL 29 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define CHKCOND(x,y) if (!(x)) printk y 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct hpfs_inode_info { 4762306a36Sopenharmony_ci loff_t mmu_private; 4862306a36Sopenharmony_ci ino_t i_parent_dir; /* (directories) gives fnode of parent dir */ 4962306a36Sopenharmony_ci unsigned i_dno; /* (directories) root dnode */ 5062306a36Sopenharmony_ci unsigned i_dpos; /* (directories) temp for readdir */ 5162306a36Sopenharmony_ci unsigned i_dsubdno; /* (directories) temp for readdir */ 5262306a36Sopenharmony_ci unsigned i_file_sec; /* (files) minimalist cache of alloc info */ 5362306a36Sopenharmony_ci unsigned i_disk_sec; /* (files) minimalist cache of alloc info */ 5462306a36Sopenharmony_ci unsigned i_n_secs; /* (files) minimalist cache of alloc info */ 5562306a36Sopenharmony_ci unsigned i_ea_size; /* size of extended attributes */ 5662306a36Sopenharmony_ci unsigned i_ea_mode : 1; /* file's permission is stored in ea */ 5762306a36Sopenharmony_ci unsigned i_ea_uid : 1; /* file's uid is stored in ea */ 5862306a36Sopenharmony_ci unsigned i_ea_gid : 1; /* file's gid is stored in ea */ 5962306a36Sopenharmony_ci unsigned i_dirty : 1; 6062306a36Sopenharmony_ci loff_t **i_rddir_off; 6162306a36Sopenharmony_ci struct inode vfs_inode; 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistruct hpfs_sb_info { 6562306a36Sopenharmony_ci struct mutex hpfs_mutex; /* global hpfs lock */ 6662306a36Sopenharmony_ci ino_t sb_root; /* inode number of root dir */ 6762306a36Sopenharmony_ci unsigned sb_fs_size; /* file system size, sectors */ 6862306a36Sopenharmony_ci unsigned sb_bitmaps; /* sector number of bitmap list */ 6962306a36Sopenharmony_ci unsigned sb_dirband_start; /* directory band start sector */ 7062306a36Sopenharmony_ci unsigned sb_dirband_size; /* directory band size, dnodes */ 7162306a36Sopenharmony_ci unsigned sb_dmap; /* sector number of dnode bit map */ 7262306a36Sopenharmony_ci unsigned sb_n_free; /* free blocks for statfs, or -1 */ 7362306a36Sopenharmony_ci unsigned sb_n_free_dnodes; /* free dnodes for statfs, or -1 */ 7462306a36Sopenharmony_ci kuid_t sb_uid; /* uid from mount options */ 7562306a36Sopenharmony_ci kgid_t sb_gid; /* gid from mount options */ 7662306a36Sopenharmony_ci umode_t sb_mode; /* mode from mount options */ 7762306a36Sopenharmony_ci unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */ 7862306a36Sopenharmony_ci unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */ 7962306a36Sopenharmony_ci unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */ 8062306a36Sopenharmony_ci unsigned sb_lowercase : 1; /* downcase filenames hackery */ 8162306a36Sopenharmony_ci unsigned sb_was_error : 1; /* there was an error, set dirty flag */ 8262306a36Sopenharmony_ci unsigned sb_chkdsk : 2; /* chkdsk: 0-no, 1-on errs, 2-allways */ 8362306a36Sopenharmony_ci unsigned char *sb_cp_table; /* code page tables: */ 8462306a36Sopenharmony_ci /* 128 bytes uppercasing table & */ 8562306a36Sopenharmony_ci /* 128 bytes lowercasing table */ 8662306a36Sopenharmony_ci __le32 *sb_bmp_dir; /* main bitmap directory */ 8762306a36Sopenharmony_ci unsigned sb_c_bitmap; /* current bitmap */ 8862306a36Sopenharmony_ci unsigned sb_max_fwd_alloc; /* max forwad allocation */ 8962306a36Sopenharmony_ci int sb_timeshift; 9062306a36Sopenharmony_ci struct rcu_head rcu; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci unsigned n_hotfixes; 9362306a36Sopenharmony_ci secno hotfix_from[256]; 9462306a36Sopenharmony_ci secno hotfix_to[256]; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* Four 512-byte buffers and the 2k block obtained by concatenating them */ 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistruct quad_buffer_head { 10062306a36Sopenharmony_ci struct buffer_head *bh[4]; 10162306a36Sopenharmony_ci void *data; 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/* The b-tree down pointer from a dir entry */ 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic inline dnode_secno de_down_pointer (struct hpfs_dirent *de) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n")); 10962306a36Sopenharmony_ci return le32_to_cpu(*(__le32 *) ((void *) de + le16_to_cpu(de->length) - 4)); 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* The first dir entry in a dnode */ 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci return (void *) dnode->dirent; 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* The end+1 of the dir entries */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci CHKCOND(le32_to_cpu(dnode->first_free)>=0x14 && le32_to_cpu(dnode->first_free)<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %x\n",(unsigned)le32_to_cpu(dnode->first_free))); 12462306a36Sopenharmony_ci return (void *) dnode + le32_to_cpu(dnode->first_free); 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* The dir entry after dir entry de */ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci CHKCOND(le16_to_cpu(de->length)>=0x20 && le16_to_cpu(de->length)<0x800,("HPFS: de_next_de: de->length = %x\n",(unsigned)le16_to_cpu(de->length))); 13262306a36Sopenharmony_ci return (void *) de + le16_to_cpu(de->length); 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic inline struct extended_attribute *fnode_ea(struct fnode *fnode) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s)); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic inline struct extended_attribute *fnode_end_ea(struct fnode *fnode) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s)); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic unsigned ea_valuelen(struct extended_attribute *ea) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci return ea->valuelen_lo + 256 * ea->valuelen_hi; 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic inline struct extended_attribute *next_ea(struct extended_attribute *ea) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea)); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic inline secno ea_sec(struct extended_attribute *ea) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 9 + ea->namelen))); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic inline secno ea_len(struct extended_attribute *ea) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 5 + ea->namelen))); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic inline char *ea_data(struct extended_attribute *ea) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci return (char *)((char *)ea + 5 + ea->namelen); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic inline unsigned de_size(int namelen, secno down_ptr) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci return ((0x1f + namelen + 3) & ~3) + (down_ptr ? 4 : 0); 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistatic inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci int a; 17862306a36Sopenharmony_ci int n; 17962306a36Sopenharmony_ci if (!dst || !src) return; 18062306a36Sopenharmony_ci a = dst->down; 18162306a36Sopenharmony_ci n = dst->not_8x3; 18262306a36Sopenharmony_ci memcpy((char *)dst + 2, (char *)src + 2, 28); 18362306a36Sopenharmony_ci dst->down = a; 18462306a36Sopenharmony_ci dst->not_8x3 = n; 18562306a36Sopenharmony_ci} 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistatic inline unsigned tstbits(__le32 *bmp, unsigned b, unsigned n) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci int i; 19062306a36Sopenharmony_ci if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n; 19162306a36Sopenharmony_ci if (!((le32_to_cpu(bmp[(b & 0x3fff) >> 5]) >> (b & 0x1f)) & 1)) return 1; 19262306a36Sopenharmony_ci for (i = 1; i < n; i++) 19362306a36Sopenharmony_ci if (!((le32_to_cpu(bmp[((b+i) & 0x3fff) >> 5]) >> ((b+i) & 0x1f)) & 1)) 19462306a36Sopenharmony_ci return i + 1; 19562306a36Sopenharmony_ci return 0; 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* alloc.c */ 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ciint hpfs_chk_sectors(struct super_block *, secno, int, char *); 20162306a36Sopenharmony_cisecno hpfs_alloc_sector(struct super_block *, secno, unsigned, int); 20262306a36Sopenharmony_ciint hpfs_alloc_if_possible(struct super_block *, secno); 20362306a36Sopenharmony_civoid hpfs_free_sectors(struct super_block *, secno, unsigned); 20462306a36Sopenharmony_ciint hpfs_check_free_dnodes(struct super_block *, int); 20562306a36Sopenharmony_civoid hpfs_free_dnode(struct super_block *, secno); 20662306a36Sopenharmony_cistruct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *); 20762306a36Sopenharmony_cistruct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **); 20862306a36Sopenharmony_cistruct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **); 20962306a36Sopenharmony_ciint hpfs_trim_fs(struct super_block *, u64, u64, u64, unsigned *); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci/* anode.c */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cisecno hpfs_bplus_lookup(struct super_block *, struct inode *, struct bplus_header *, unsigned, struct buffer_head *); 21462306a36Sopenharmony_cisecno hpfs_add_sector_to_btree(struct super_block *, secno, int, unsigned); 21562306a36Sopenharmony_civoid hpfs_remove_btree(struct super_block *, struct bplus_header *); 21662306a36Sopenharmony_ciint hpfs_ea_read(struct super_block *, secno, int, unsigned, unsigned, char *); 21762306a36Sopenharmony_ciint hpfs_ea_write(struct super_block *, secno, int, unsigned, unsigned, const char *); 21862306a36Sopenharmony_civoid hpfs_ea_remove(struct super_block *, secno, int, unsigned); 21962306a36Sopenharmony_civoid hpfs_truncate_btree(struct super_block *, secno, int, unsigned); 22062306a36Sopenharmony_civoid hpfs_remove_fnode(struct super_block *, fnode_secno fno); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci/* buffer.c */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cisecno hpfs_search_hotfix_map(struct super_block *s, secno sec); 22562306a36Sopenharmony_ciunsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n); 22662306a36Sopenharmony_civoid hpfs_prefetch_sectors(struct super_block *, unsigned, int); 22762306a36Sopenharmony_civoid *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int); 22862306a36Sopenharmony_civoid *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **); 22962306a36Sopenharmony_civoid *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int); 23062306a36Sopenharmony_civoid *hpfs_get_4sectors(struct super_block *, unsigned, struct quad_buffer_head *); 23162306a36Sopenharmony_civoid hpfs_brelse4(struct quad_buffer_head *); 23262306a36Sopenharmony_civoid hpfs_mark_4buffers_dirty(struct quad_buffer_head *); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/* dentry.c */ 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciextern const struct dentry_operations hpfs_dentry_operations; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/* dir.c */ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cistruct dentry *hpfs_lookup(struct inode *, struct dentry *, unsigned int); 24162306a36Sopenharmony_ciextern const struct file_operations hpfs_dir_ops; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci/* dnode.c */ 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ciint hpfs_add_pos(struct inode *, loff_t *); 24662306a36Sopenharmony_civoid hpfs_del_pos(struct inode *, loff_t *); 24762306a36Sopenharmony_cistruct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *, 24862306a36Sopenharmony_ci const unsigned char *, unsigned, secno); 24962306a36Sopenharmony_ciint hpfs_add_dirent(struct inode *, const unsigned char *, unsigned, 25062306a36Sopenharmony_ci struct hpfs_dirent *); 25162306a36Sopenharmony_ciint hpfs_remove_dirent(struct inode *, dnode_secno, struct hpfs_dirent *, struct quad_buffer_head *, int); 25262306a36Sopenharmony_civoid hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *); 25362306a36Sopenharmony_cidnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno); 25462306a36Sopenharmony_cistruct hpfs_dirent *map_pos_dirent(struct inode *, loff_t *, struct quad_buffer_head *); 25562306a36Sopenharmony_cistruct hpfs_dirent *map_dirent(struct inode *, dnode_secno, 25662306a36Sopenharmony_ci const unsigned char *, unsigned, dnode_secno *, 25762306a36Sopenharmony_ci struct quad_buffer_head *); 25862306a36Sopenharmony_civoid hpfs_remove_dtree(struct super_block *, dnode_secno); 25962306a36Sopenharmony_cistruct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct fnode *, struct quad_buffer_head *); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/* ea.c */ 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_civoid hpfs_ea_ext_remove(struct super_block *, secno, int, unsigned); 26462306a36Sopenharmony_ciint hpfs_read_ea(struct super_block *, struct fnode *, char *, char *, int); 26562306a36Sopenharmony_cichar *hpfs_get_ea(struct super_block *, struct fnode *, char *, int *); 26662306a36Sopenharmony_civoid hpfs_set_ea(struct inode *, struct fnode *, const char *, 26762306a36Sopenharmony_ci const char *, int); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci/* file.c */ 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ciint hpfs_file_fsync(struct file *, loff_t, loff_t, int); 27262306a36Sopenharmony_civoid hpfs_truncate(struct inode *); 27362306a36Sopenharmony_ciextern const struct file_operations hpfs_file_ops; 27462306a36Sopenharmony_ciextern const struct inode_operations hpfs_file_iops; 27562306a36Sopenharmony_ciextern const struct address_space_operations hpfs_aops; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci/* inode.c */ 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_civoid hpfs_init_inode(struct inode *); 28062306a36Sopenharmony_civoid hpfs_read_inode(struct inode *); 28162306a36Sopenharmony_civoid hpfs_write_inode(struct inode *); 28262306a36Sopenharmony_civoid hpfs_write_inode_nolock(struct inode *); 28362306a36Sopenharmony_ciint hpfs_setattr(struct mnt_idmap *, struct dentry *, struct iattr *); 28462306a36Sopenharmony_civoid hpfs_write_if_changed(struct inode *); 28562306a36Sopenharmony_civoid hpfs_evict_inode(struct inode *); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci/* map.c */ 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci__le32 *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *); 29062306a36Sopenharmony_ci__le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *); 29162306a36Sopenharmony_civoid hpfs_prefetch_bitmap(struct super_block *, unsigned); 29262306a36Sopenharmony_ciunsigned char *hpfs_load_code_page(struct super_block *, secno); 29362306a36Sopenharmony_ci__le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp); 29462306a36Sopenharmony_civoid hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock); 29562306a36Sopenharmony_cistruct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **); 29662306a36Sopenharmony_cistruct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **); 29762306a36Sopenharmony_cistruct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *); 29862306a36Sopenharmony_cidnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* name.c */ 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ciunsigned char hpfs_upcase(unsigned char *, unsigned char); 30362306a36Sopenharmony_ciint hpfs_chk_name(const unsigned char *, unsigned *); 30462306a36Sopenharmony_ciunsigned char *hpfs_translate_name(struct super_block *, unsigned char *, unsigned, int, int); 30562306a36Sopenharmony_ciint hpfs_compare_names(struct super_block *, const unsigned char *, unsigned, 30662306a36Sopenharmony_ci const unsigned char *, unsigned, int); 30762306a36Sopenharmony_ciint hpfs_is_name_long(const unsigned char *, unsigned); 30862306a36Sopenharmony_civoid hpfs_adjust_length(const unsigned char *, unsigned *); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci/* namei.c */ 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ciextern const struct inode_operations hpfs_dir_iops; 31362306a36Sopenharmony_ciextern const struct address_space_operations hpfs_symlink_aops; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic inline struct hpfs_inode_info *hpfs_i(struct inode *inode) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci return container_of(inode, struct hpfs_inode_info, vfs_inode); 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci return sb->s_fs_info; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/* super.c */ 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci__printf(2, 3) 32862306a36Sopenharmony_civoid hpfs_error(struct super_block *, const char *, ...); 32962306a36Sopenharmony_ciint hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); 33062306a36Sopenharmony_ciunsigned hpfs_get_free_dnodes(struct super_block *); 33162306a36Sopenharmony_cilong hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci/* 33462306a36Sopenharmony_ci * local time (HPFS) to GMT (Unix) 33562306a36Sopenharmony_ci */ 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistatic inline time64_t local_to_gmt(struct super_block *s, time64_t t) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci extern struct timezone sys_tz; 34062306a36Sopenharmony_ci return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift; 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic inline time32_t gmt_to_local(struct super_block *s, time64_t t) 34462306a36Sopenharmony_ci{ 34562306a36Sopenharmony_ci extern struct timezone sys_tz; 34662306a36Sopenharmony_ci return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic inline time32_t local_get_seconds(struct super_block *s) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci return gmt_to_local(s, ktime_get_real_seconds()); 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* 35562306a36Sopenharmony_ci * Locking: 35662306a36Sopenharmony_ci * 35762306a36Sopenharmony_ci * hpfs_lock() locks the whole filesystem. It must be taken 35862306a36Sopenharmony_ci * on any method called by the VFS. 35962306a36Sopenharmony_ci * 36062306a36Sopenharmony_ci * We don't do any per-file locking anymore, it is hard to 36162306a36Sopenharmony_ci * review and HPFS is not performance-sensitive anyway. 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_cistatic inline void hpfs_lock(struct super_block *s) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci struct hpfs_sb_info *sbi = hpfs_sb(s); 36662306a36Sopenharmony_ci mutex_lock(&sbi->hpfs_mutex); 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistatic inline void hpfs_unlock(struct super_block *s) 37062306a36Sopenharmony_ci{ 37162306a36Sopenharmony_ci struct hpfs_sb_info *sbi = hpfs_sb(s); 37262306a36Sopenharmony_ci mutex_unlock(&sbi->hpfs_mutex); 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic inline void hpfs_lock_assert(struct super_block *s) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci struct hpfs_sb_info *sbi = hpfs_sb(s); 37862306a36Sopenharmony_ci WARN_ON(!mutex_is_locked(&sbi->hpfs_mutex)); 37962306a36Sopenharmony_ci} 380