18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/fs/ufs/util.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1998 68c2ecf20Sopenharmony_ci * Daniel Pirkl <daniel.pirkl@email.cz> 78c2ecf20Sopenharmony_ci * Charles University, Faculty of Mathematics and Physics 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 118c2ecf20Sopenharmony_ci#include <linux/fs.h> 128c2ecf20Sopenharmony_ci#include "swab.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * some useful macros 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci#define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * functions used for retyping 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cistatic inline struct ufs_buffer_head *UCPI_UBH(struct ufs_cg_private_info *cpi) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci return &cpi->c_ubh; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_cistatic inline struct ufs_buffer_head *USPI_UBH(struct ufs_sb_private_info *spi) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci return &spi->s_ubh; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/* 358c2ecf20Sopenharmony_ci * macros used for accessing structures 368c2ecf20Sopenharmony_ci */ 378c2ecf20Sopenharmony_cistatic inline s32 388c2ecf20Sopenharmony_ciufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, 398c2ecf20Sopenharmony_ci struct ufs_super_block_third *usb3) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 428c2ecf20Sopenharmony_ci case UFS_ST_SUNOS: 438c2ecf20Sopenharmony_ci if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) 448c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb1->fs_u0.fs_sun.fs_state); 458c2ecf20Sopenharmony_ci fallthrough; /* to UFS_ST_SUN */ 468c2ecf20Sopenharmony_ci case UFS_ST_SUN: 478c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state); 488c2ecf20Sopenharmony_ci case UFS_ST_SUNx86: 498c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state); 508c2ecf20Sopenharmony_ci case UFS_ST_44BSD: 518c2ecf20Sopenharmony_ci default: 528c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_state); 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic inline void 578c2ecf20Sopenharmony_ciufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, 588c2ecf20Sopenharmony_ci struct ufs_super_block_third *usb3, s32 value) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 618c2ecf20Sopenharmony_ci case UFS_ST_SUNOS: 628c2ecf20Sopenharmony_ci if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { 638c2ecf20Sopenharmony_ci usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); 648c2ecf20Sopenharmony_ci break; 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci fallthrough; /* to UFS_ST_SUN */ 678c2ecf20Sopenharmony_ci case UFS_ST_SUN: 688c2ecf20Sopenharmony_ci usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value); 698c2ecf20Sopenharmony_ci break; 708c2ecf20Sopenharmony_ci case UFS_ST_SUNx86: 718c2ecf20Sopenharmony_ci usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value); 728c2ecf20Sopenharmony_ci break; 738c2ecf20Sopenharmony_ci case UFS_ST_44BSD: 748c2ecf20Sopenharmony_ci usb3->fs_un2.fs_44.fs_state = cpu_to_fs32(sb, value); 758c2ecf20Sopenharmony_ci break; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic inline u32 808c2ecf20Sopenharmony_ciufs_get_fs_npsect(struct super_block *sb, struct ufs_super_block_first *usb1, 818c2ecf20Sopenharmony_ci struct ufs_super_block_third *usb3) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) 848c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb3->fs_un2.fs_sunx86.fs_npsect); 858c2ecf20Sopenharmony_ci else 868c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect); 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic inline u64 908c2ecf20Sopenharmony_ciufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci __fs64 tmp; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 958c2ecf20Sopenharmony_ci case UFS_ST_SUNOS: 968c2ecf20Sopenharmony_ci case UFS_ST_SUN: 978c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0]; 988c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1]; 998c2ecf20Sopenharmony_ci break; 1008c2ecf20Sopenharmony_ci case UFS_ST_SUNx86: 1018c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qbmask[0]; 1028c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qbmask[1]; 1038c2ecf20Sopenharmony_ci break; 1048c2ecf20Sopenharmony_ci case UFS_ST_44BSD: 1058c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qbmask[0]; 1068c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qbmask[1]; 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci return fs64_to_cpu(sb, tmp); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic inline u64 1148c2ecf20Sopenharmony_ciufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci __fs64 tmp; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 1198c2ecf20Sopenharmony_ci case UFS_ST_SUNOS: 1208c2ecf20Sopenharmony_ci case UFS_ST_SUN: 1218c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0]; 1228c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1]; 1238c2ecf20Sopenharmony_ci break; 1248c2ecf20Sopenharmony_ci case UFS_ST_SUNx86: 1258c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qfmask[0]; 1268c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qfmask[1]; 1278c2ecf20Sopenharmony_ci break; 1288c2ecf20Sopenharmony_ci case UFS_ST_44BSD: 1298c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qfmask[0]; 1308c2ecf20Sopenharmony_ci ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qfmask[1]; 1318c2ecf20Sopenharmony_ci break; 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci return fs64_to_cpu(sb, tmp); 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistatic inline u16 1388c2ecf20Sopenharmony_ciufs_get_de_namlen(struct super_block *sb, struct ufs_dir_entry *de) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) == UFS_DE_OLD) 1418c2ecf20Sopenharmony_ci return fs16_to_cpu(sb, de->d_u.d_namlen); 1428c2ecf20Sopenharmony_ci else 1438c2ecf20Sopenharmony_ci return de->d_u.d_44.d_namlen; /* XXX this seems wrong */ 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic inline void 1478c2ecf20Sopenharmony_ciufs_set_de_namlen(struct super_block *sb, struct ufs_dir_entry *de, u16 value) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) == UFS_DE_OLD) 1508c2ecf20Sopenharmony_ci de->d_u.d_namlen = cpu_to_fs16(sb, value); 1518c2ecf20Sopenharmony_ci else 1528c2ecf20Sopenharmony_ci de->d_u.d_44.d_namlen = value; /* XXX this seems wrong */ 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic inline void 1568c2ecf20Sopenharmony_ciufs_set_de_type(struct super_block *sb, struct ufs_dir_entry *de, int mode) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) != UFS_DE_44BSD) 1598c2ecf20Sopenharmony_ci return; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci /* 1628c2ecf20Sopenharmony_ci * TODO turn this into a table lookup 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_ci switch (mode & S_IFMT) { 1658c2ecf20Sopenharmony_ci case S_IFSOCK: 1668c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_SOCK; 1678c2ecf20Sopenharmony_ci break; 1688c2ecf20Sopenharmony_ci case S_IFLNK: 1698c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_LNK; 1708c2ecf20Sopenharmony_ci break; 1718c2ecf20Sopenharmony_ci case S_IFREG: 1728c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_REG; 1738c2ecf20Sopenharmony_ci break; 1748c2ecf20Sopenharmony_ci case S_IFBLK: 1758c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_BLK; 1768c2ecf20Sopenharmony_ci break; 1778c2ecf20Sopenharmony_ci case S_IFDIR: 1788c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_DIR; 1798c2ecf20Sopenharmony_ci break; 1808c2ecf20Sopenharmony_ci case S_IFCHR: 1818c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_CHR; 1828c2ecf20Sopenharmony_ci break; 1838c2ecf20Sopenharmony_ci case S_IFIFO: 1848c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_FIFO; 1858c2ecf20Sopenharmony_ci break; 1868c2ecf20Sopenharmony_ci default: 1878c2ecf20Sopenharmony_ci de->d_u.d_44.d_type = DT_UNKNOWN; 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci} 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic inline u32 1928c2ecf20Sopenharmony_ciufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { 1958c2ecf20Sopenharmony_ci case UFS_UID_44BSD: 1968c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid); 1978c2ecf20Sopenharmony_ci case UFS_UID_EFT: 1988c2ecf20Sopenharmony_ci if (inode->ui_u1.oldids.ui_suid == 0xFFFF) 1998c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid); 2008c2ecf20Sopenharmony_ci fallthrough; 2018c2ecf20Sopenharmony_ci default: 2028c2ecf20Sopenharmony_ci return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid); 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic inline void 2078c2ecf20Sopenharmony_ciufs_set_inode_uid(struct super_block *sb, struct ufs_inode *inode, u32 value) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { 2108c2ecf20Sopenharmony_ci case UFS_UID_44BSD: 2118c2ecf20Sopenharmony_ci inode->ui_u3.ui_44.ui_uid = cpu_to_fs32(sb, value); 2128c2ecf20Sopenharmony_ci inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value); 2138c2ecf20Sopenharmony_ci break; 2148c2ecf20Sopenharmony_ci case UFS_UID_EFT: 2158c2ecf20Sopenharmony_ci inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value); 2168c2ecf20Sopenharmony_ci if (value > 0xFFFF) 2178c2ecf20Sopenharmony_ci value = 0xFFFF; 2188c2ecf20Sopenharmony_ci fallthrough; 2198c2ecf20Sopenharmony_ci default: 2208c2ecf20Sopenharmony_ci inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value); 2218c2ecf20Sopenharmony_ci break; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic inline u32 2268c2ecf20Sopenharmony_ciufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { 2298c2ecf20Sopenharmony_ci case UFS_UID_44BSD: 2308c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid); 2318c2ecf20Sopenharmony_ci case UFS_UID_EFT: 2328c2ecf20Sopenharmony_ci if (inode->ui_u1.oldids.ui_sgid == 0xFFFF) 2338c2ecf20Sopenharmony_ci return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); 2348c2ecf20Sopenharmony_ci fallthrough; 2358c2ecf20Sopenharmony_ci default: 2368c2ecf20Sopenharmony_ci return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid); 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic inline void 2418c2ecf20Sopenharmony_ciufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value) 2428c2ecf20Sopenharmony_ci{ 2438c2ecf20Sopenharmony_ci switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { 2448c2ecf20Sopenharmony_ci case UFS_UID_44BSD: 2458c2ecf20Sopenharmony_ci inode->ui_u3.ui_44.ui_gid = cpu_to_fs32(sb, value); 2468c2ecf20Sopenharmony_ci inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value); 2478c2ecf20Sopenharmony_ci break; 2488c2ecf20Sopenharmony_ci case UFS_UID_EFT: 2498c2ecf20Sopenharmony_ci inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value); 2508c2ecf20Sopenharmony_ci if (value > 0xFFFF) 2518c2ecf20Sopenharmony_ci value = 0xFFFF; 2528c2ecf20Sopenharmony_ci fallthrough; 2538c2ecf20Sopenharmony_ci default: 2548c2ecf20Sopenharmony_ci inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value); 2558c2ecf20Sopenharmony_ci break; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ciextern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); 2608c2ecf20Sopenharmony_ciextern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); 2618c2ecf20Sopenharmony_ciextern int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci/* 2648c2ecf20Sopenharmony_ci * These functions manipulate ufs buffers 2658c2ecf20Sopenharmony_ci */ 2668c2ecf20Sopenharmony_ci#define ubh_bread(sb,fragment,size) _ubh_bread_(uspi,sb,fragment,size) 2678c2ecf20Sopenharmony_ciextern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, struct super_block *, u64 , u64); 2688c2ecf20Sopenharmony_ciextern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, struct super_block *, u64, u64); 2698c2ecf20Sopenharmony_ciextern void ubh_brelse (struct ufs_buffer_head *); 2708c2ecf20Sopenharmony_ciextern void ubh_brelse_uspi (struct ufs_sb_private_info *); 2718c2ecf20Sopenharmony_ciextern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); 2728c2ecf20Sopenharmony_ciextern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); 2738c2ecf20Sopenharmony_ciextern void ubh_sync_block(struct ufs_buffer_head *); 2748c2ecf20Sopenharmony_ciextern void ubh_bforget (struct ufs_buffer_head *); 2758c2ecf20Sopenharmony_ciextern int ubh_buffer_dirty (struct ufs_buffer_head *); 2768c2ecf20Sopenharmony_ci#define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) 2778c2ecf20Sopenharmony_ciextern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struct ufs_buffer_head *, unsigned); 2788c2ecf20Sopenharmony_ci#define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size) 2798c2ecf20Sopenharmony_ciextern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci/* This functions works with cache pages*/ 2828c2ecf20Sopenharmony_ciextern struct page *ufs_get_locked_page(struct address_space *mapping, 2838c2ecf20Sopenharmony_ci pgoff_t index); 2848c2ecf20Sopenharmony_cistatic inline void ufs_put_locked_page(struct page *page) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci unlock_page(page); 2878c2ecf20Sopenharmony_ci put_page(page); 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/* 2928c2ecf20Sopenharmony_ci * macros and inline function to get important structures from ufs_sb_private_info 2938c2ecf20Sopenharmony_ci */ 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic inline void *get_usb_offset(struct ufs_sb_private_info *uspi, 2968c2ecf20Sopenharmony_ci unsigned int offset) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci unsigned int index; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci index = offset >> uspi->s_fshift; 3018c2ecf20Sopenharmony_ci offset &= ~uspi->s_fmask; 3028c2ecf20Sopenharmony_ci return uspi->s_ubh.bh[index]->b_data + offset; 3038c2ecf20Sopenharmony_ci} 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci#define ubh_get_usb_first(uspi) \ 3068c2ecf20Sopenharmony_ci ((struct ufs_super_block_first *)get_usb_offset((uspi), 0)) 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci#define ubh_get_usb_second(uspi) \ 3098c2ecf20Sopenharmony_ci ((struct ufs_super_block_second *)get_usb_offset((uspi), UFS_SECTOR_SIZE)) 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci#define ubh_get_usb_third(uspi) \ 3128c2ecf20Sopenharmony_ci ((struct ufs_super_block_third *)get_usb_offset((uspi), 2*UFS_SECTOR_SIZE)) 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci#define ubh_get_ucg(ubh) \ 3168c2ecf20Sopenharmony_ci ((struct ufs_cylinder_group *)((ubh)->bh[0]->b_data)) 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci/* 3208c2ecf20Sopenharmony_ci * Extract byte from ufs_buffer_head 3218c2ecf20Sopenharmony_ci * Extract the bits for a block from a map inside ufs_buffer_head 3228c2ecf20Sopenharmony_ci */ 3238c2ecf20Sopenharmony_ci#define ubh_get_addr8(ubh,begin) \ 3248c2ecf20Sopenharmony_ci ((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + \ 3258c2ecf20Sopenharmony_ci ((begin) & ~uspi->s_fmask)) 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci#define ubh_get_addr16(ubh,begin) \ 3288c2ecf20Sopenharmony_ci (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ 3298c2ecf20Sopenharmony_ci ((begin) & ((uspi->fsize>>1) - 1))) 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci#define ubh_get_addr32(ubh,begin) \ 3328c2ecf20Sopenharmony_ci (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ 3338c2ecf20Sopenharmony_ci ((begin) & ((uspi->s_fsize>>2) - 1))) 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci#define ubh_get_addr64(ubh,begin) \ 3368c2ecf20Sopenharmony_ci (((__fs64*)((ubh)->bh[(begin) >> (uspi->s_fshift-3)]->b_data)) + \ 3378c2ecf20Sopenharmony_ci ((begin) & ((uspi->s_fsize>>3) - 1))) 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci#define ubh_get_addr ubh_get_addr8 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_cistatic inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi, 3428c2ecf20Sopenharmony_ci struct ufs_buffer_head *ubh, 3438c2ecf20Sopenharmony_ci u64 blk) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci if (uspi->fs_magic == UFS2_MAGIC) 3468c2ecf20Sopenharmony_ci return ubh_get_addr64(ubh, blk); 3478c2ecf20Sopenharmony_ci else 3488c2ecf20Sopenharmony_ci return ubh_get_addr32(ubh, blk); 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci#define ubh_blkmap(ubh,begin,bit) \ 3528c2ecf20Sopenharmony_ci ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_cistatic inline u64 3558c2ecf20Sopenharmony_ciufs_freefrags(struct ufs_sb_private_info *uspi) 3568c2ecf20Sopenharmony_ci{ 3578c2ecf20Sopenharmony_ci return ufs_blkstofrags(uspi->cs_total.cs_nbfree) + 3588c2ecf20Sopenharmony_ci uspi->cs_total.cs_nffree; 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci/* 3628c2ecf20Sopenharmony_ci * Macros to access cylinder group array structures 3638c2ecf20Sopenharmony_ci */ 3648c2ecf20Sopenharmony_ci#define ubh_cg_blktot(ucpi,cylno) \ 3658c2ecf20Sopenharmony_ci (*((__fs32*)ubh_get_addr(UCPI_UBH(ucpi), (ucpi)->c_btotoff + ((cylno) << 2)))) 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci#define ubh_cg_blks(ucpi,cylno,rpos) \ 3688c2ecf20Sopenharmony_ci (*((__fs16*)ubh_get_addr(UCPI_UBH(ucpi), \ 3698c2ecf20Sopenharmony_ci (ucpi)->c_boff + (((cylno) * uspi->s_nrpos + (rpos)) << 1 )))) 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci/* 3728c2ecf20Sopenharmony_ci * Bitmap operations 3738c2ecf20Sopenharmony_ci * These functions work like classical bitmap operations. 3748c2ecf20Sopenharmony_ci * The difference is that we don't have the whole bitmap 3758c2ecf20Sopenharmony_ci * in one contiguous chunk of memory, but in several buffers. 3768c2ecf20Sopenharmony_ci * The parameters of each function are super_block, ufs_buffer_head and 3778c2ecf20Sopenharmony_ci * position of the beginning of the bitmap. 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_ci#define ubh_setbit(ubh,begin,bit) \ 3808c2ecf20Sopenharmony_ci (*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) |= (1 << ((bit) & 7))) 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci#define ubh_clrbit(ubh,begin,bit) \ 3838c2ecf20Sopenharmony_ci (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) &= ~(1 << ((bit) & 7))) 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci#define ubh_isset(ubh,begin,bit) \ 3868c2ecf20Sopenharmony_ci (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) & (1 << ((bit) & 7))) 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci#define ubh_isclr(ubh,begin,bit) (!ubh_isset(ubh,begin,bit)) 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci#define ubh_find_first_zero_bit(ubh,begin,size) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0) 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci#define ubh_find_next_zero_bit(ubh,begin,size,offset) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset) 3938c2ecf20Sopenharmony_cistatic inline unsigned _ubh_find_next_zero_bit_( 3948c2ecf20Sopenharmony_ci struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, 3958c2ecf20Sopenharmony_ci unsigned begin, unsigned size, unsigned offset) 3968c2ecf20Sopenharmony_ci{ 3978c2ecf20Sopenharmony_ci unsigned base, count, pos; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci size -= offset; 4008c2ecf20Sopenharmony_ci begin <<= 3; 4018c2ecf20Sopenharmony_ci offset += begin; 4028c2ecf20Sopenharmony_ci base = offset >> uspi->s_bpfshift; 4038c2ecf20Sopenharmony_ci offset &= uspi->s_bpfmask; 4048c2ecf20Sopenharmony_ci for (;;) { 4058c2ecf20Sopenharmony_ci count = min_t(unsigned int, size + offset, uspi->s_bpf); 4068c2ecf20Sopenharmony_ci size -= count - offset; 4078c2ecf20Sopenharmony_ci pos = find_next_zero_bit_le(ubh->bh[base]->b_data, count, offset); 4088c2ecf20Sopenharmony_ci if (pos < count || !size) 4098c2ecf20Sopenharmony_ci break; 4108c2ecf20Sopenharmony_ci base++; 4118c2ecf20Sopenharmony_ci offset = 0; 4128c2ecf20Sopenharmony_ci } 4138c2ecf20Sopenharmony_ci return (base << uspi->s_bpfshift) + pos - begin; 4148c2ecf20Sopenharmony_ci} 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_cistatic inline unsigned find_last_zero_bit (unsigned char * bitmap, 4178c2ecf20Sopenharmony_ci unsigned size, unsigned offset) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci unsigned bit, i; 4208c2ecf20Sopenharmony_ci unsigned char * mapp; 4218c2ecf20Sopenharmony_ci unsigned char map; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci mapp = bitmap + (size >> 3); 4248c2ecf20Sopenharmony_ci map = *mapp--; 4258c2ecf20Sopenharmony_ci bit = 1 << (size & 7); 4268c2ecf20Sopenharmony_ci for (i = size; i > offset; i--) { 4278c2ecf20Sopenharmony_ci if ((map & bit) == 0) 4288c2ecf20Sopenharmony_ci break; 4298c2ecf20Sopenharmony_ci if ((i & 7) != 0) { 4308c2ecf20Sopenharmony_ci bit >>= 1; 4318c2ecf20Sopenharmony_ci } else { 4328c2ecf20Sopenharmony_ci map = *mapp--; 4338c2ecf20Sopenharmony_ci bit = 1 << 7; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci } 4368c2ecf20Sopenharmony_ci return i; 4378c2ecf20Sopenharmony_ci} 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci#define ubh_find_last_zero_bit(ubh,begin,size,offset) _ubh_find_last_zero_bit_(uspi,ubh,begin,size,offset) 4408c2ecf20Sopenharmony_cistatic inline unsigned _ubh_find_last_zero_bit_( 4418c2ecf20Sopenharmony_ci struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, 4428c2ecf20Sopenharmony_ci unsigned begin, unsigned start, unsigned end) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci unsigned base, count, pos, size; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci size = start - end; 4478c2ecf20Sopenharmony_ci begin <<= 3; 4488c2ecf20Sopenharmony_ci start += begin; 4498c2ecf20Sopenharmony_ci base = start >> uspi->s_bpfshift; 4508c2ecf20Sopenharmony_ci start &= uspi->s_bpfmask; 4518c2ecf20Sopenharmony_ci for (;;) { 4528c2ecf20Sopenharmony_ci count = min_t(unsigned int, 4538c2ecf20Sopenharmony_ci size + (uspi->s_bpf - start), uspi->s_bpf) 4548c2ecf20Sopenharmony_ci - (uspi->s_bpf - start); 4558c2ecf20Sopenharmony_ci size -= count; 4568c2ecf20Sopenharmony_ci pos = find_last_zero_bit (ubh->bh[base]->b_data, 4578c2ecf20Sopenharmony_ci start, start - count); 4588c2ecf20Sopenharmony_ci if (pos > start - count || !size) 4598c2ecf20Sopenharmony_ci break; 4608c2ecf20Sopenharmony_ci base--; 4618c2ecf20Sopenharmony_ci start = uspi->s_bpf; 4628c2ecf20Sopenharmony_ci } 4638c2ecf20Sopenharmony_ci return (base << uspi->s_bpfshift) + pos - begin; 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci#define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block)) 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci#define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block) 4698c2ecf20Sopenharmony_cistatic inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi, 4708c2ecf20Sopenharmony_ci struct ufs_buffer_head * ubh, unsigned begin, unsigned block) 4718c2ecf20Sopenharmony_ci{ 4728c2ecf20Sopenharmony_ci u8 mask; 4738c2ecf20Sopenharmony_ci switch (uspi->s_fpb) { 4748c2ecf20Sopenharmony_ci case 8: 4758c2ecf20Sopenharmony_ci return (*ubh_get_addr (ubh, begin + block) == 0xff); 4768c2ecf20Sopenharmony_ci case 4: 4778c2ecf20Sopenharmony_ci mask = 0x0f << ((block & 0x01) << 2); 4788c2ecf20Sopenharmony_ci return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask; 4798c2ecf20Sopenharmony_ci case 2: 4808c2ecf20Sopenharmony_ci mask = 0x03 << ((block & 0x03) << 1); 4818c2ecf20Sopenharmony_ci return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask; 4828c2ecf20Sopenharmony_ci case 1: 4838c2ecf20Sopenharmony_ci mask = 0x01 << (block & 0x07); 4848c2ecf20Sopenharmony_ci return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci return 0; 4878c2ecf20Sopenharmony_ci} 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci#define ubh_clrblock(ubh,begin,block) _ubh_clrblock_(uspi,ubh,begin,block) 4908c2ecf20Sopenharmony_cistatic inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi, 4918c2ecf20Sopenharmony_ci struct ufs_buffer_head * ubh, unsigned begin, unsigned block) 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci switch (uspi->s_fpb) { 4948c2ecf20Sopenharmony_ci case 8: 4958c2ecf20Sopenharmony_ci *ubh_get_addr (ubh, begin + block) = 0x00; 4968c2ecf20Sopenharmony_ci return; 4978c2ecf20Sopenharmony_ci case 4: 4988c2ecf20Sopenharmony_ci *ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2)); 4998c2ecf20Sopenharmony_ci return; 5008c2ecf20Sopenharmony_ci case 2: 5018c2ecf20Sopenharmony_ci *ubh_get_addr (ubh, begin + (block >> 2)) &= ~(0x03 << ((block & 0x03) << 1)); 5028c2ecf20Sopenharmony_ci return; 5038c2ecf20Sopenharmony_ci case 1: 5048c2ecf20Sopenharmony_ci *ubh_get_addr (ubh, begin + (block >> 3)) &= ~(0x01 << ((block & 0x07))); 5058c2ecf20Sopenharmony_ci return; 5068c2ecf20Sopenharmony_ci } 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#define ubh_setblock(ubh,begin,block) _ubh_setblock_(uspi,ubh,begin,block) 5108c2ecf20Sopenharmony_cistatic inline void _ubh_setblock_(struct ufs_sb_private_info * uspi, 5118c2ecf20Sopenharmony_ci struct ufs_buffer_head * ubh, unsigned begin, unsigned block) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci switch (uspi->s_fpb) { 5148c2ecf20Sopenharmony_ci case 8: 5158c2ecf20Sopenharmony_ci *ubh_get_addr(ubh, begin + block) = 0xff; 5168c2ecf20Sopenharmony_ci return; 5178c2ecf20Sopenharmony_ci case 4: 5188c2ecf20Sopenharmony_ci *ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2)); 5198c2ecf20Sopenharmony_ci return; 5208c2ecf20Sopenharmony_ci case 2: 5218c2ecf20Sopenharmony_ci *ubh_get_addr(ubh, begin + (block >> 2)) |= (0x03 << ((block & 0x03) << 1)); 5228c2ecf20Sopenharmony_ci return; 5238c2ecf20Sopenharmony_ci case 1: 5248c2ecf20Sopenharmony_ci *ubh_get_addr(ubh, begin + (block >> 3)) |= (0x01 << ((block & 0x07))); 5258c2ecf20Sopenharmony_ci return; 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic inline void ufs_fragacct (struct super_block * sb, unsigned blockmap, 5308c2ecf20Sopenharmony_ci __fs32 * fraglist, int cnt) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci struct ufs_sb_private_info * uspi; 5338c2ecf20Sopenharmony_ci unsigned fragsize, pos; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci uspi = UFS_SB(sb)->s_uspi; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci fragsize = 0; 5388c2ecf20Sopenharmony_ci for (pos = 0; pos < uspi->s_fpb; pos++) { 5398c2ecf20Sopenharmony_ci if (blockmap & (1 << pos)) { 5408c2ecf20Sopenharmony_ci fragsize++; 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_ci else if (fragsize > 0) { 5438c2ecf20Sopenharmony_ci fs32_add(sb, &fraglist[fragsize], cnt); 5448c2ecf20Sopenharmony_ci fragsize = 0; 5458c2ecf20Sopenharmony_ci } 5468c2ecf20Sopenharmony_ci } 5478c2ecf20Sopenharmony_ci if (fragsize > 0 && fragsize < uspi->s_fpb) 5488c2ecf20Sopenharmony_ci fs32_add(sb, &fraglist[fragsize], cnt); 5498c2ecf20Sopenharmony_ci} 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_cistatic inline void *ufs_get_direct_data_ptr(struct ufs_sb_private_info *uspi, 5528c2ecf20Sopenharmony_ci struct ufs_inode_info *ufsi, 5538c2ecf20Sopenharmony_ci unsigned blk) 5548c2ecf20Sopenharmony_ci{ 5558c2ecf20Sopenharmony_ci BUG_ON(blk > UFS_TIND_BLOCK); 5568c2ecf20Sopenharmony_ci return uspi->fs_magic == UFS2_MAGIC ? 5578c2ecf20Sopenharmony_ci (void *)&ufsi->i_u1.u2_i_data[blk] : 5588c2ecf20Sopenharmony_ci (void *)&ufsi->i_u1.i_data[blk]; 5598c2ecf20Sopenharmony_ci} 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_cistatic inline u64 ufs_data_ptr_to_cpu(struct super_block *sb, void *p) 5628c2ecf20Sopenharmony_ci{ 5638c2ecf20Sopenharmony_ci return UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC ? 5648c2ecf20Sopenharmony_ci fs64_to_cpu(sb, *(__fs64 *)p) : 5658c2ecf20Sopenharmony_ci fs32_to_cpu(sb, *(__fs32 *)p); 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistatic inline void ufs_cpu_to_data_ptr(struct super_block *sb, void *p, u64 val) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci if (UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC) 5718c2ecf20Sopenharmony_ci *(__fs64 *)p = cpu_to_fs64(sb, val); 5728c2ecf20Sopenharmony_ci else 5738c2ecf20Sopenharmony_ci *(__fs32 *)p = cpu_to_fs32(sb, val); 5748c2ecf20Sopenharmony_ci} 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_cistatic inline void ufs_data_ptr_clear(struct ufs_sb_private_info *uspi, 5778c2ecf20Sopenharmony_ci void *p) 5788c2ecf20Sopenharmony_ci{ 5798c2ecf20Sopenharmony_ci if (uspi->fs_magic == UFS2_MAGIC) 5808c2ecf20Sopenharmony_ci *(__fs64 *)p = 0; 5818c2ecf20Sopenharmony_ci else 5828c2ecf20Sopenharmony_ci *(__fs32 *)p = 0; 5838c2ecf20Sopenharmony_ci} 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_cistatic inline int ufs_is_data_ptr_zero(struct ufs_sb_private_info *uspi, 5868c2ecf20Sopenharmony_ci void *p) 5878c2ecf20Sopenharmony_ci{ 5888c2ecf20Sopenharmony_ci if (uspi->fs_magic == UFS2_MAGIC) 5898c2ecf20Sopenharmony_ci return *(__fs64 *)p == 0; 5908c2ecf20Sopenharmony_ci else 5918c2ecf20Sopenharmony_ci return *(__fs32 *)p == 0; 5928c2ecf20Sopenharmony_ci} 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_cistatic inline __fs32 ufs_get_seconds(struct super_block *sbp) 5958c2ecf20Sopenharmony_ci{ 5968c2ecf20Sopenharmony_ci time64_t now = ktime_get_real_seconds(); 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci /* Signed 32-bit interpretation wraps around in 2038, which 5998c2ecf20Sopenharmony_ci * happens in ufs1 inode stamps but not ufs2 using 64-bits 6008c2ecf20Sopenharmony_ci * stamps. For superblock and blockgroup, let's assume 6018c2ecf20Sopenharmony_ci * unsigned 32-bit stamps, which are good until y2106. 6028c2ecf20Sopenharmony_ci * Wrap around rather than clamp here to make the dirty 6038c2ecf20Sopenharmony_ci * file system detection work in the superblock stamp. 6048c2ecf20Sopenharmony_ci */ 6058c2ecf20Sopenharmony_ci return cpu_to_fs32(sbp, lower_32_bits(now)); 6068c2ecf20Sopenharmony_ci} 607