• Alexey Dobriyan's avatar
    proc: give /proc/cmdline size · 941baf6f
    Alexey Dobriyan authored
    Most /proc files don't have length (in fstat sense).  This leads to
    inefficiencies when reading such files with APIs commonly found in modern
    programming languages.  They open file, then fstat descriptor, get st_size
    == 0 and either assume file is empty or start reading without knowing
    target size.
    
    cat(1) does OK because it uses large enough buffer by default.  But naive
    programs copy-pasted from SO aren't:
    
    	let mut f = std::fs::File::open("/proc/cmdline").unwrap();
    	let mut buf: Vec<u8> = Vec::new();
    	f.read_to_end(&mut buf).unwrap();
    
    will result in
    
    	openat(AT_FDCWD, "/proc/cmdline", O_RDONLY|O_CLOEXEC) = 3
    	statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Bad address)
    	statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=0, ...}) = 0
    	lseek(3, 0, SEEK_CUR)                   = 0
    	read(3, "BOOT_IMAGE=(hd3,gpt2)/vmlinuz-5.", 32) = 32
    	read(3, "19.6-100.fc35.x86_64 root=/dev/m", 32) = 32
    	read(3, "apper/fedora_localhost--live-roo"..., 64) = 64
    	read(3, "ocalhost--live-swap rd.lvm.lv=fe"..., 128) = 116
    	read(3, "", 12)
    
    open/stat is OK, lseek looks silly but there are 3 unnecessary reads
    because Rust starts with 32 bytes per Vec<u8> and grows from there.
    
    In case of /proc/cmdline, the length is known precisely.
    
    Make variables readonly while I'm at it.
    
    P.S.: I tried to scp /proc/cpuinfo today and got empty file
    	but this is separate story.
    
    Link: https://lkml.kernel.org/r/YxoywlbM73JJN3r+@localhost.localdomainSigned-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    941baf6f
main.c 40.1 KB