본문 바로가기

Linux/Device Driver

struct file *filp

읽기와 쓰기에 전달되는 file 구조체 변수의 선두 주소를 담은 filp는 디바이스 파일이 어떤 형식으로 열렸는가에 대한 정보를 담고 있다.

이 struct file의 형태는 다음과 같다.

//
// struct file *filp
//
struct file
{
    struct list_head        f_list;
    struct dentry            *f_dentry;
    struct vfsmount            *f_vfsmnt;
    struct file_operations    *f_op;
    atomic_t                f_count;
    unsigned int            f_flags;
    mode_t                    f_mode;
    loff_t                    f_pos;
    struct fown_struct        f_owner;
    unsigned int            f_uid, f_gid;
    int                        f_error;
    struct file_ra_state    f_ra;
    unsigned long            f_version;
    void                    *f_security;

    // needed for tty driver, and maybe others
    void                    *private_data;

    // Used by fs/eventpoll.c to link all the hooks to this file
    struct list_head        f_ep_links;
    spinlock_t                f_ep_lock;
}


unsigned int f_flags;
이 변수는 응용 프로그램에서 디바이스 파일을 int open(const char *pathname, int flags) 함수로 열였을 때 flags에 설정된 값이다.
이 필드값을 살펴봄으로써 디바이스 파일을 열였을 때의 옵션에 따라 처리하는 방식을 결정할 수 있다. 가장 많이 참조되는 것으론

// ----------------------------------------------------------------------------------------------
O_RDONLY, O_NONBLOCK, O_NDELAY, O_SYNC
// ----------------------------------------------------------------------------------------------

loff_t f_pos;
f_pos 필드 변수에는 현재의 읽기/쓰기의 위치를 담는데 read(), write(), llseek()과 같이 읽기/쓰기의 위치를
변경할 수 있는 함수에 의해 변경된다. 파일 포인터를 관리하는 디바이스 드라이버에 사용된다.

void *private_data;
디바이스 드라이버를 제작할 때 가급적 전역 변수 사용을 자제해야 한다. 디바이스 드라이버에서 프로세스가 함수간에 메모리를 공유할 목적이라면
이 필드 변수를 적극 활용하는게 좋다.

struct file_operations *f_op;
부 번호에 따라 다른 응답을 처리해야 할 때는 open() 함수 처리 시에 이 필드를 직접 변경 함으로써 디바이스 파일의
부 번호에 따라 다르게 동작하는 디바이스 드라이버를 작성할 수 있다.