Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>
Docbook 원문

statfs(2)

1장. statfs(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 에러
1.5절. 예제
1.6절. 참고문헌

파일 시스템 정보를 가져온다.


1.1절. 사용법

#include <sys/vfs.h>

int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
		


1.2절. 설명

statfs()는 마운트(:12)된 파일 시스템에 대한 정보를 반환한다. path는 마운트된 파일 시스템내 파일의 경로 이름이다. 파일 시스템의 정보는 buf가 가르키는 공간에 채워진다. statfs구조체는 다음과 같이 정의되어 있다.

struct statfs {
   long    f_type;     /* 파일 시스템 타입(아래에서 보여준다) */
   long    f_bsize;    /* 최적화된 전송 블럭 크기 */
   long    f_blocks;   /* 파일 시스템내 총 데이터 블럭들 */
   long    f_bfree;    /* 파일 시스템내 여유 블럭들 */
   long    f_bavail;   /* 비-슈퍼 유저를 위한 여유 블럭들 */
   long    f_files;    /* 파일 시스템내 총 파일 노드들 */
   long    f_ffree;    /* 파일 시스템내 여유 파일 노드들 */
   fsid_t  f_fsid;     /* 파일 시스템 ID */
   long    f_namelen;  /* 파일 이름의 최대 길이 */
   long    f_spare[6]; /* 나중을 위한 여유분 */
};
		
다음은 파일 시스템 타입이다.
linux/affs_fs.h:
   AFFS_SUPER_MAGIC      0xADFF
linux/ext_fs.h:
   EXT_SUPER_MAGIC       0x137D
linux/ext2_fs.h:
   EXT2_OLD_SUPER_MAGIC  0xEF51
   EXT2_SUPER_MAGIC      0xEF53
linux/hpfs_fs.h:
   HPFS_SUPER_MAGIC      0xF995E849
linux/iso_fs.h:
   ISOFS_SUPER_MAGIC     0x9660
linux/minix_fs.h:
   MINIX_SUPER_MAGIC     0x137F /* orig. minix */
   MINIX_SUPER_MAGIC2    0x138F /* 30 char minix */
   MINIX2_SUPER_MAGIC    0x2468 /* minix V2 */
   MINIX2_SUPER_MAGIC2   0x2478 /* minix V2, 30 char names */
linux/msdos_fs.h:
   MSDOS_SUPER_MAGIC     0x4d44
linux/ncp_fs.h:
   NCP_SUPER_MAGIC       0x564c
linux/nfs_fs.h:
   NFS_SUPER_MAGIC       0x6969
linux/proc_fs.h:
   PROC_SUPER_MAGIC      0x9fa0
linux/smb_fs.h:
   SMB_SUPER_MAGIC       0x517B
linux/sysv_fs.h:
   XENIX_SUPER_MAGIC     0x012FF7B4
   SYSV4_SUPER_MAGIC     0x012FF7B5
   SYSV2_SUPER_MAGIC     0x012FF7B6
   COH_SUPER_MAGIC       0x012FF7B7
linux/ufs_fs.h:
   UFS_MAGIC             0x00011954
linux/xia_fs.h:
   _XIAFS_SUPER_MAGIC    0x012FD16D
		
정의되지 않은 파일시스템이 검색되었을 경우 필드는 -1로 설정된다.

fstatfs()는 열린 파일지정자fd를 사용한다는 것을 제외하고는 statfs()와 동일하다.


1.3절. 반환값

성공시 0이 리턴되고, 에러가 발생하면 -1이 리턴된다.


1.4절. 에러

statfs():

ENOTDIR

path의 경로 요소가 디렉토리가 아니다.

ENAMETOOLONG

path가 너무 길다.

ENOENT

탐색 허가권이 path경로 요소에서 거부되었다.

ELOOP

너무 많은 상징 연결을path해석시에 만났다.

EFAULT

bufpath가 유효하지 않은 주소를 가리키고 있다.

EIO

파일 시스템을 읽거나 쓰는 동안 I/O 에러가 발생했다.

ENOMEM

이용할 수 있는 커널 메모리가 충분하지 않다.

ENOSYS

path파일 시스템이 statfs를 지원하지 않는다.

fstatfs():

EBADF

fd는 유효한 파일지정자가 아니다.

EFAULT

buf가 유효하지 않은 주소를 가리키고 있다.

ENOSYS

path파일 시스템이 statfs를 지원하지 않는다.

EIO

파일 시스템을 읽거나 쓰는 동안 I/O 에러가 발생했다.


1.5절. 예제

/*
 * 파일시스템 정보 얻어오기
 * /proc/mounts 정보와 statfs를 이용한다. 
 */
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <sys/vfs.h>
#include <sys/stat.h>
#include <sys/types.h>

const char *MMOUNT = "/proc/mounts";

struct f_size
{
    long blocks;
    long avail; 
};

typedef struct _mountinfo 
{
    FILE *fp;                // 파일 스트림 포인터    
    char devname[80];        // 장치 이름
    char mountdir[80];        // 마운트 디렉토리 이름
    char fstype[12];        // 파일 시스템 타입
    struct f_size size;        // 파일 시스템의 총크기/사용율 
} MOUNTP;

MOUNTP *dfopen()
{
    MOUNTP *MP;

    // /proc/mounts 파일을 연다.
    MP = (MOUNTP *)malloc(sizeof(MOUNTP));
    if(!(MP->fp = fopen(MMOUNT, "r")))
    {
        return NULL;
    }
    else
        return MP;
}

MOUNTP *dfget(MOUNTP *MP)
{
    char buf[256];
    char *bname;
    char null[16];
    struct statfs lstatfs;
    struct stat lstat; 
    int is_root = 0;

    // /proc/mounts로 부터 마운트된 파티션의 정보를 얻어온다.
    while(fgets(buf, 255, MP->fp))
    {
        is_root = 0;
        sscanf(buf, "%s%s%s",MP->devname, MP->mountdir, MP->fstype);
         if (strcmp(MP->mountdir,"/") == 0) is_root=1;
        if (stat(MP->devname, &lstat) == 0 || is_root)
        {
            if (strstr(buf, MP->mountdir) && S_ISBLK(lstat.st_mode) || is_root)
            {
                // 파일시스템의 총 할당된 크기와 사용량을 구한다.        
                statfs(MP->mountdir, &lstatfs);
                MP->size.blocks = lstatfs.f_blocks * (lstatfs.f_bsize/1024); 
                MP->size.avail  = lstatfs.f_bavail * (lstatfs.f_bsize/1024); 
                return MP;
            }
        }
    }
    rewind(MP->fp);
    return NULL;
}

int dfclose(MOUNTP *MP)
{
    fclose(MP->fp);
}

int main()
{
    MOUNTP *MP;
    if ((MP=dfopen()) == NULL)
    {
        perror("error");
        return 1;
    }

    while(1)
    {
        while(dfget(MP))
        {
            printf("%-14s%-20s%10lu%10lu\n", MP->mountdir, MP->devname, 
                                MP->size.blocks,
                                MP->size.avail);
        }
        printf("=========================\n\n");
        sleep(1);
    }
}