ユーザ用ツール

サイト用ツール


サイドバー

最新の10件
一覧
linux:filesystem

filesystem

tips

FAT32のディレクトリ内ファイル数制限によりrsyncコマンドがストールする

NTFSからFAT32にrsyncでデータをコピーしていると途中で停止していた. エラーは出ておらずlogを見ると処理が止まってから7時間以上経過していた CTRL+Cで止めると No space left on device というエラー.

このとき対象のコピー先ディレクトリにtouchすると No space left on device になった.

$ touch hogehoge
touch: cannot touch 'hogehoge': No space left on device

ファイル数は 32632

$ ls -A1 .|wc -l
32632

恐らく同一ディレクトリ内へのファイル数制限 この後同じ状態になったときは 10926, 13107, 13105 ファイル名長により変わるよう.

rsyncが何も言わずに止まってしまうのは困る. --timeout=30 を指定してみたところ該当ディレクトリでエラーになるようになった.No space left on device (28)

            --timeout=SECONDS       set I/O timeout in seconds

このエラーが出たディレクトリを --exclude に指定して除外し,個別対応とした.( $ cd exclude_path && zip -9 /backupdir/archive.zip ./* )

てことでこんな感じに

$ rsync -avvc --modify-window=1 --timeout=30 --log-file=rsync.log --exclude '除外1' --exclude '除外2' コピー元 コピー先

--modify-window=1 はFAT32のタイムスタンプ制限(2秒単位)のため.

FAT32のディレクトリ内ファイル数制限を確認する

最大65535 個でファイル名長が長くなると少なくなるのを確認した.

まずは適当なFAT32領域を用意する

$ dd if=/dev/zero of=./FAT32_1GB.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 0.556993 s, 1.9 GB/s
$ fdisk ./FAT32_1GB.img

Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xa1d801ca.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p):

Using default response p.
Partition number (1-4, default 1):
First sector (2048-2047999, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-2047999, default 2047999):

Created a new partition 1 of type 'Linux' and of size 999 MiB.

Command (m for help): t

Selected partition 1
Hex code (type L to list all codes): L

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden or  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi ea  Rufus alignment
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         eb  BeOS fs
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ee  GPT
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        ef  EFI (FAT-12/16/
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f0  Linux/PA-RISC b
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f1  SpeedStor
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f4  SpeedStor
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      f2  DOS secondary
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fb  VMware VMFS
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fc  VMware VMKCORE
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fd  Linux raid auto
1c  Hidden W95 FAT3 75  PC/IX           bc  Acronis FAT32 L fe  LANstep
1e  Hidden W95 FAT1 80  Old Minix       be  Solaris boot    ff  BBT
Hex code (type L to list all codes): b
Changed type of partition 'Linux' to 'W95 FAT32'.

Command (m for help): p
Disk ./FAT32_1GB.img: 1000 MiB, 1048576000 bytes, 2048000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos  
Disk identifier: 0xa1d801ca

Device           Boot Start     End Sectors  Size Id Type
./FAT32_1GB.img1       2048 2047999 2045952  999M  b W95 FAT32

Command (m for help): w
The partition table has been altered.
Syncing disks.

$ mkfs.vfat ./FAT32_1GB.img 
mkfs.fat 4.1 (2017-01-24)
$ mkdir fat32
$ sudo mount -o loop,uid=`id -u` ./FAT32_1GB.img ./fat32
$ mount |grep fat32
/home/matoken/tmp/FAT32_1GB.img on /home/matoken/tmp/fat32 type vfat (rw,relatime,uid=1000,fmask=0022,dmask=0022,codepage=437,iochars
et=ascii,shortname=mixed,utf8,errors=remount-ro)
$ cd fat32

サブディレクトリを掘ってファイルを沢山作ってみる 1~5文字のファイル名長だと ./.. を合わせて 65535 迄作れる

$ mkdir dir1
$ cd dir1
$ n=1;while :;do if ! touch ${n};then echo ${n} ;break;fi ;n=$(( n + 1 ));done
touch: cannot touch '65534': No space left on device
65534
$ ls -1A|wc -l
65533
$ ls -1a|wc -l
65535

別のディレクトリで長いファイル名長で試す. 255文字のファイル名長だと ./.. を合わせて3123個までだった

$ n=1;while :;do if ! touch `printf %0255d ${n}`;then echo ${n} ;break;fi ;n=$(( n + 1 ));done
touch: cannot touch '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003121': No space left on device
3121
$ ls -lA|wc -l
3121
$ ls -la|wc -l
3123

日本語ファイル名が長すぎて処理に失敗する

UnavailableVideoError: [Errno 36] File name too long: '/home/matoken/Videos/\xe7\x95\xb0\xe7\xa8\xae\xe6\x97\x8f\xe3\x83\xac\xe3\x83\x93\xe3\x83\xa5\xe3\x82\xa2\xe3\x83\xbc\xe3\x82\xba\xe3\x80\x80\xe7\xac\xac1\xe8\xa9\xb1\xe3\x80\x80\xe3\x82\xa8\xe3\x83\xab\xe3\x83\x95\xe3\x81\xae\xe7\x86\x9f\xe5\xa5\xb3\xe3\x81\xa8\xe4\xba\xba\xe9\x96\x93\xe3\x81\xae\xe7\x86\x9f\xe5\xa5\xb3\xe3\x81\xab\xe3\x81\xa4\xe3\x81\x84\xe3\x81\xa6\xe3\x81\xae\xe8\xad\xb0\xe8\xab\x96\xe3\x81\x8c\xe6\xb2\xb8\xe9\xa8\xb0\xe3\x81\x97\xe3\x80\x81\xe5\xa4\xa9\xe4\xbd\xbf\xe3\x81\xaf\xe3\x83\x8b\xe3\x83\xa3\xe3\x83\xb3\xe3\x83\x8b\xe3\x83\xa3\xe3\x83\xb3\xe5\xa4\xa9\xe5\x9b\xbd\xe3\x81\xa7\xe6\x98\x87\xe5\xa4\xa9\xe3\x81\x97\xe3\x80\x81\xe6\x9c\x89\xe7\xbf\xbc\xe4\xba\xba\xe3\x81\xaf\xe7\xb7\x8f\xe6\x8e\x92\xe6\xb3\x84\xe5\xad\x94\xe3\x81\xa7\xe6\x84\x9f\xe5\xba\xa6\xe3\x82\x82\xe6\x8a\x9c\xe7\xbe\xa4\xef\xbc\x81.fdash-b4723d03-31f0-456c-9a49-70aa8ce6134c-1.m4a.ytdl'

ファイルシステムは ext4。 ファイル名長はバイト単位なので、asciiだと255文字まで。

$ getconf NAME_MAX .
255
$ while [ true ]; do     if ! touch $(printf "%${num}s"  | tr ' ' 'a');    then        echo $num;        break;    fi;    ((num++)); done
touch: cannot touch 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': File name too long
256

UTF-8の日本語などは1文字当たりのバイト数が多くなる(1〜4byte)ので文字数は短くなる

は1文字当たり3byte

$ echo -n 'a' | wc -c
1
$ echo -n 'あ' | wc -c
3

だと85文字まで

$ num=1;str="あ";while :; do if ! touch $str;    then        echo $num;        break;    fi;    ((num++)); str="$strあ"; done
touch: cannot touch ''$'\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202': File name too long
86

今回の処理はほんの少し足りない程度なので惜しい……。そういえばNTFSやexFATはUnicodeで文字数を数えていた気がするので試してみる。

まずは一時的なexFAT領域を作る

$ dd if=/dev/zero of=./700M.img bs=1M count=700
$ fdisk ./700M.img
$ kpartx -av ./700M.img
$ sudo mkfs.exfat /dev/mapper/loop0p1
$ sudo mount /dev/mapper/loop0p1 /mnt

exfat領域で確認

NAME_MAXはext4と同じ255だけど、

$ getconf NAME_MAX /mnt
255

ext4環境では85文字までしか使えなかった1文字当たり3byteの を255文字使ったファイルが作成できる。

$ num=1;str="あ";while :; do if ! touch $str;    then        echo $num;        break;    fi;    ((num++)); str="$strあ"; done
touch: cannot touch ''$'\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202\343\201\202': File name too long
256

しかし、4byte文字の「😺」だと127文字になる??

$ echo -n '😺' | wc -c
4
$ num=1;str="😺";while :; do if ! touch $str;    then        echo $num;        break;    fi;    ((num++)); str="$str😺"; done
touch: cannot touch ''$'\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272\360\237\230\272': File name too long
128

利用したexFAT driverはexfat-fuse

$ ps ax|grep -i exfat
 1729 ?        Ss     0:12 /sbin/mount.exfat /dev/mapper/loop0p1 /mnt -o rw
$ dpkg-query -W exfat-fuse
exfat-fuse      1.3.0-1
$ /sbin/mount.exfat-fuse -V
FUSE exfat 1.3.0
Copyright (C) 2010-2018  Andrew Nayenko

とりあえず今回はこれで回避した。

linux 5.14.0exfat.koNAME_MAX=1530 だった.「」はfuse版と同じ255文字,「🐈」も同様に127文字になった.恐らく NAME_MAX などの変更が必要.

$ getconf NAME_MAX /mnt
1530
$ grep -E 'NAME_MAX|PATH_MAX' /usr/src/linux-headers-$(uname -r)/include/uapi/linux/limits.h
#define NAME_MAX         255    /* # chars in a file name */
#define PATH_MAX        4096    /* # chars in a path name including nul */
#define XATTR_NAME_MAX   255    /* # chars in an extended attribute name */

Btrfsのbtrfs\-transactionでioが100%になって困る

Btrfsでdfで空き容量があるように見えるのに容量が無いと言われてreadonlyにされてしまう

Btrfsでswap fileが作れないことを知らずに嵌まる

コメント

コメントを入力. Wiki文法が有効です:
   ___   ____    __ __     __   _  __
  / _ ) / __ \  / //_/ __ / /  / |/ /
 / _  |/ /_/ / / ,<   / // /  /    / 
/____/ \____/ /_/|_|  \___/  /_/|_/
 
linux/filesystem.txt · 最終更新: 2021/09/09 05:46 by matoken