반응형
busybox 에서의 df
명령어
busybox 에서 df -h
라는 명령어를 치게 되면.. 아래의 소스코드를 실행하게 된다.
busybox_src/coreutils/df.c
//.. 중략
device = mount_entry->mnt_fsname;
mount_point = mount_entry->mnt_dir;
if (statfs(mount_point, &s) != 0) {
bb_simple_perror_msg(mount_point);
goto set_error;
}
if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) {
if (opt & OPT_INODE) {
s.f_blocks = s.f_files;
s.f_bavail = s.f_bfree = s.f_ffree;
s.f_bsize = 1;
if (df_disp_hr)
df_disp_hr = 1;
}
blocks_used = s.f_blocks - s.f_bfree;
blocks_percent_used = 0;
if (blocks_used + s.f_bavail) {
blocks_percent_used = (blocks_used * 100ULL
+ (blocks_used + s.f_bavail)/2
) / (blocks_used + s.f_bavail);
}
//... 중략
```
`statfs()` 의 함수는 파일시스템에서 함수포인터가 연결되어있고... `include/linux/fs.h` 에서 각 파일시스템마다 별도의 함수를 호출 하게 된다.
```cpp
struct super_operations {
struct inode \*(\*alloc_inode)(struct super_block \*sb);
void (\*destroy_inode)(struct inode \*);
void (\*dirty_inode) (struct inode \*);
int (\*write_inode) (struct inode \*, int);
void (\*drop_inode) (struct inode \*);
void (\*delete_inode) (struct inode \*);
void (\*put_super) (struct super_block \*);
void (\*write_super) (struct super_block \*);
int (\*sync_fs)(struct super_block \*sb, int wait);
int (\*freeze_fs) (struct super_block \*);
int (\*unfreeze_fs) (struct super_block \*);
int (\*statfs) (struct dentry \*, struct kstatfs \*);
int (\*remount_fs) (struct super_block \*, int \*, char \*);
void (\*clear_inode) (struct inode \*);
void (\*umount_begin) (struct super_block \*);
int (\*show_options)(struct seq_file \*, struct vfsmount \*);
int (\*show_stats)(struct seq_file \*, struct vfsmount \*);
#ifdef CONFIG_QUOTA
ssize_t (\*quota_read)(struct super_block \*, int, char \*, size_t, loff_t);
ssize_t (\*quota_write)(struct super_block \*, int, const char \*, size_t, loff_t);
#endif
int (\*bdev_try_to_free_page)(struct super_block\*, struct page\*, gfp_t);
};
- 즉.. 각 fs 종류마다 call back 형태로 연결되어 호출한다.**
jffs2 의 함수호출
int jffs2_statfs(struct dentry \*dentry, struct kstatfs \*buf)
{
struct jffs2_sb_info \*c = JFFS2_SB_INFO(dentry->d_sb);
unsigned long avail;
buf->f_type = JFFS2_SUPER_MAGIC;
buf->f_bsize = 1 << PAGE_SHIFT;
buf->f_blocks = c->flash_size >> PAGE_SHIFT;
buf->f_files = 0;
buf->f_ffree = 0;
buf->f_namelen = JFFS2_MAX_NAME_LEN;
buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC;
buf->f_fsid.val[1] = c->mtd->index;
spin_lock(&c->erase_completion_lock);
avail = c->dirty_size + c->free_size;
if (avail > c->sector_size \* c->resv_blocks_write)
avail -= c->sector_size \* c->resv_blocks_write;
else
avail = 0;
spin_unlock(&c->erase_completion_lock);
buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
return 0;
}
반응형