fs: ext4l: Add inode and bmap functions
Add inode allocation and block mapping functions: - iget_locked() - allocate inode by number - new_inode() - allocate new empty inode - ext4_uboot_bmap() - map logical to physical block - bmap() - VFS interface for block mapping Also add i_count reference counter to struct inode. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
@@ -377,8 +377,8 @@ struct buffer_head *sb_getblk(struct super_block *sb, sector_t block);
|
||||
#define ktime_get_real_seconds() (0)
|
||||
#define time_before32(a, b) (0)
|
||||
|
||||
/* Inode operations - stubs */
|
||||
#define new_inode(sb) ((struct inode *)NULL)
|
||||
/* Inode operations - iget_locked and new_inode are in interface.c */
|
||||
extern struct inode *new_inode(struct super_block *sb);
|
||||
#define i_uid_write(inode, uid) do { } while (0)
|
||||
#define i_gid_write(inode, gid) do { } while (0)
|
||||
#define inode_fsuid_set(inode, idmap) do { } while (0)
|
||||
@@ -820,6 +820,7 @@ struct inode {
|
||||
const struct inode_operations *i_op;
|
||||
const struct file_operations *i_fop;
|
||||
atomic_t i_writecount; /* Count of writers */
|
||||
atomic_t i_count; /* Reference count */
|
||||
struct rw_semaphore i_rwsem; /* inode lock */
|
||||
const char *i_link; /* Symlink target for fast symlinks */
|
||||
unsigned short i_write_hint; /* Write life time hint */
|
||||
@@ -1615,7 +1616,7 @@ static inline unsigned int i_gid_read(const struct inode *inode)
|
||||
#define fs_high2lowgid(gid) ((gid) & 0xFFFF)
|
||||
|
||||
/* Inode allocation/state operations */
|
||||
#define iget_locked(sb, ino) ((struct inode *)NULL)
|
||||
extern struct inode *iget_locked(struct super_block *sb, unsigned long ino);
|
||||
#define set_nlink(i, n) do { (i)->i_nlink = (n); } while (0)
|
||||
#define inc_nlink(i) do { (i)->i_nlink++; } while (0)
|
||||
#define drop_nlink(i) do { (i)->i_nlink--; } while (0)
|
||||
@@ -2855,7 +2856,7 @@ struct disk_partition *ext4l_get_partition(void);
|
||||
/* JBD2 journal.c stubs */
|
||||
struct buffer_head *alloc_buffer_head(gfp_t gfp_mask);
|
||||
#define __getblk(bdev, block, size) ({ (void)(bdev); (void)(block); (void)(size); (struct buffer_head *)NULL; })
|
||||
#define bmap(inode, block) ({ (void)(inode); (void)(block); 0; })
|
||||
int bmap(struct inode *inode, sector_t *block);
|
||||
#define trace_jbd2_update_log_tail(j, t, b, f) \
|
||||
do { (void)(j); (void)(t); (void)(b); (void)(f); } while (0)
|
||||
|
||||
|
||||
@@ -39,6 +39,105 @@ u32 ext4l_crc32c(u32 crc, const void *address, unsigned int length)
|
||||
return crc32c_cal(crc, address, length, ext4l_crc32c_table);
|
||||
}
|
||||
|
||||
/*
|
||||
* iget_locked - allocate a new inode
|
||||
* @sb: super block of filesystem
|
||||
* @ino: inode number to allocate
|
||||
*
|
||||
* U-Boot implementation: allocates ext4_inode_info and returns the embedded
|
||||
* vfs_inode. In Linux, this would look up the inode in a hash table first.
|
||||
* Since U-Boot is single-threaded and doesn't cache inodes, we always allocate.
|
||||
*/
|
||||
struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
struct ext4_inode_info *ei;
|
||||
struct inode *inode;
|
||||
|
||||
ei = kzalloc(sizeof(struct ext4_inode_info), GFP_KERNEL);
|
||||
if (!ei)
|
||||
return NULL;
|
||||
|
||||
/* Get pointer to the embedded vfs_inode using offsetof */
|
||||
inode = (struct inode *)((char *)ei +
|
||||
offsetof(struct ext4_inode_info, vfs_inode));
|
||||
inode->i_sb = sb;
|
||||
inode->i_blkbits = sb->s_blocksize_bits;
|
||||
inode->i_ino = ino;
|
||||
inode->i_state = I_NEW;
|
||||
inode->i_count.counter = 1;
|
||||
inode->i_mapping = &inode->i_data;
|
||||
inode->i_data.host = inode;
|
||||
INIT_LIST_HEAD(&ei->i_es_list);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* new_inode - allocate a new empty inode
|
||||
* @sb: super block of filesystem
|
||||
*
|
||||
* U-Boot implementation: allocates ext4_inode_info for a new inode that
|
||||
* will be initialised by the caller (e.g., for creating new files).
|
||||
*/
|
||||
struct inode *new_inode(struct super_block *sb)
|
||||
{
|
||||
struct ext4_inode_info *ei;
|
||||
struct inode *inode;
|
||||
|
||||
ei = kzalloc(sizeof(struct ext4_inode_info), GFP_KERNEL);
|
||||
if (!ei)
|
||||
return NULL;
|
||||
|
||||
inode = &ei->vfs_inode;
|
||||
inode->i_sb = sb;
|
||||
inode->i_blkbits = sb->s_blocksize_bits;
|
||||
inode->i_nlink = 1;
|
||||
inode->i_count.counter = 1;
|
||||
inode->i_mapping = &inode->i_data;
|
||||
inode->i_data.host = inode;
|
||||
INIT_LIST_HEAD(&ei->i_es_list);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* ext4_uboot_bmap - map a logical block to a physical block
|
||||
* @inode: inode to map
|
||||
* @block: on entry, logical block number; on exit, physical block number
|
||||
*
|
||||
* U-Boot implementation of bmap for ext4. Maps a logical block number
|
||||
* to the corresponding physical block on disk.
|
||||
*/
|
||||
int ext4_uboot_bmap(struct inode *inode, sector_t *block)
|
||||
{
|
||||
struct ext4_map_blocks map;
|
||||
int ret;
|
||||
|
||||
map.m_lblk = *block;
|
||||
map.m_len = 1;
|
||||
map.m_flags = 0;
|
||||
|
||||
ret = ext4_map_blocks(NULL, inode, &map, 0);
|
||||
if (ret > 0) {
|
||||
*block = map.m_pblk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret < 0 ? ret : -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* bmap - map a logical block to a physical block (VFS interface)
|
||||
* @inode: inode to map
|
||||
* @blockp: pointer to logical block number; updated to physical block number
|
||||
*
|
||||
* This is the VFS bmap interface used by jbd2.
|
||||
*/
|
||||
int bmap(struct inode *inode, sector_t *blockp)
|
||||
{
|
||||
return ext4_uboot_bmap(inode, blockp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Buffer cache implementation
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user