SW 개발

[Linux] busybox 에서 파일용량 확인 명령어의 내부 호출과정

. . . 2011. 11. 23. 11:19
반응형

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;
}
반응형