您的位置:首页 > 移动开发 > Android开发

文件系统中的保留空间

2015-11-16 17:26 549 查看
Android中我们经常会使用android.os.StatFs来获取关于文件系统空间的状态信息。

File sdcardDir = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(sdcardDir.getPath());
long blockSize = sf.getBlockSize();
long blockCount = sf.getBlockCountLong();
long availCount = sf.getAvailableBlocksLong();
Log.d("", "block大小:"+ blockSize+",block数目:"+ blockCount+",总大小:"+blockSize*blockCount/1024+"KB");
Log.d("", "可用的block数目::"+ availCount+",剩余空间:"+ availCount*blockSize/1024+"KB");


但上面的方法我们会发现剩余空间和df命令显示的Free大小不一样,这是怎么回事呢?

看看df的代码(system/core/toolbox/df.c)

39        printf("%-20s  ", s);
40        printsize((long long)st.f_blocks * (long long)st.f_bsize);
41        printf("  ");
42        printsize((long long)(st.f_blocks - (long long)st.f_bfree) * st.f_bsize);
43        printf("  ");
44        printsize((long long)st.f_bfree * (long long)st.f_bsize);
45        printf("   %d\n", (int) st.f_bsize);


发现df使用的是f_bfree,查看下statfs的定义

/*
* file system statistics
*/
struct statfs {
int f_version; /* version/type of statfs, 0 for now*/
int f_type; /* type of info, zero for now */
ulong_t f_bsize; /* optimal file system block size */
fsblkcnt_t f_blocks; /* total data blocks in file system */
fsblkcnt_t f_bfree; /* free block in fs */
fsblkcnt_t f_bavail; /* free blocks avail to non-superuser*/
fsfilcnt_t f_files; /* total file nodes in file system */
fsfilcnt_t f_ffree; /* free file nodes in fs */
#if !defined(_KERNEL) && defined(__64BIT__)
fsid64_t f_fsid; /* file system id */
#else
fsid_t f_fsid; /* file system id */
#endif
int f_vfstype; /* what type of vfs this is */
ulong_t f_fsize; /* fundamental file system block size*/
int f_vfsnumber; /* vfs indentifier number */
int f_vfsoff; /* reserved, for vfs specific data offset */
int f_vfslen; /* reserved, for len of vfs specific data */
int f_vfsvers; /* reserved, for vers of vfs specific data */
char f_fname[32]; /* file system name (usually mount pt.) */
char f_fpack[32]; /* file system pack name */
int f_name_max; /* maximum component name length for posix */
};


可以看到

fsblkcnt_t f_bfree; /* free block in fs */
fsblkcnt_t f_bavail; /* free blocks avail to non-superuser*/


查看SDK

public long getAvailableBlocksLong ()

The number of blocks that are free on the file system and available to applications. This corresponds to the Unix statvfs.f_bavail field.

也就是说getAvailableBlocksLong()返回的是f_bavail,这块是不包含超级用户的预留空间的。如果要得到和df一样的大小请使用getFreeBlocksLong()。

public long getFreeBlocksLong ()

The total number of blocks that are free on the file system, including reserved blocks (that are not available to normal applications). This corresponds to the Unix statvfs.f_bfree field. Most applications will want to use getAvailableBlocks() instead.

那什么是“超级用户预留空间”呢?请看ext4文件系统的说明 https://lwn.net/Articles/546473/

Currently in ENOSPC condition when writing into unwritten space, or punching a hole, we might need to split the extent and grow extent tree. However since we can not allocate any new metadata blocks we’ll have to zero out unwritten part of extent or punched out part of extent, or in the worst case return ENOSPC even though use actually does not allocate any space.

Also in delalloc path we do reserve metadata and data blocks for the time we’re going to write out, however metadata block reservation is very tricky especially since we expect that logical connectivity implies physical connectivity, however that might not be the case and hence we might end up allocating more metadata blocks than previously reserved. So in future, metadata reservation checks should be removed since we can not assure that we do not under reserve.

And this is where reserved space comes into the picture. When mounting the file system we slice off a little bit of the file system space (2% or 4096 clusters, whichever is smaller) which can be then used for the cases mentioned above to prevent costly zeroout, or unexpected ENOSPC.

The number of reserved clusters can be set via sysfs, however it can never be bigger than number of free clusters in the file system.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息