본문 바로가기

Programming/Linux_Kernel

use fallocate in Android system

Android 4.4 기준으로 

/system/lib/libc.so

에는 fallocate funcation 을 지원하지 않는다.


여타 다른 gcc build 환경을 사용했을때는 모르지만,

(arm-2009q1  build 환경을 사용한 app 은 fallocate 함수를 사용하는데 문제가 없었다.)

Android 자체 build system 을 사용할때는 fallocate 함수를 사용할 수 없다.


이 문제를 해결하기 위해

/proc/kallsyms 를 확인한 결과

kernel 은 sys_fallocate 를 지원하는 것으로 보인다.


따라서 아래와 같이 direct 로 system call 을 호출하였다.


#define FALLOC_FL_KEEP_SIZE     0x01

return syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, offset, alloc_size);


하지만 100%의 error 가 발생하였다.


이를 64 bit format 으로 호출하였더니 호출 성공 !!

return syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, offset, 0, alloc_size, 0);


원인은 확실하지 않지만,

Nexus5 에서 사용하는 Coretex-A15 부터 hypervisor 를 사용하는데, 이 기능은 virtualazationd을 구현해서 old한 mmu를 사용하지 않고 LPEA 주소를 사용 한다고 한다.

이 기능은 address 를 40bit로 표현해서 1TB까지 사용하는데 따라서 함수버전을 32 bit 버전이 아닌 40bit mmu 사용하니 64bit 버전으로 사용하는 것이 아닌지 추측하고 있다.


주의!! : FALLOC_FL_KEEP_SIZE flag 를 사용하는것이 문제를 발생시킬 수 있는것 같다. return 값을 꼭 확인하자. !!!




fallocate 를 지원하지 않을때 ftruncate 를 사용하는 코드

    if (fallocate(fd, 0, 0, numSectors * 512)) {

        if (errno == ENOSYS || errno == ENOTSUP) {

            SLOGW("fallocate not found. Falling back to ftruncate.");

            if (ftruncate(fd, numSectors * 512) < 0) {

                SLOGE("Error truncating imagefile (%s)", strerror(errno));

                close(fd);

                return -1;

            }