
Linux isofs rock ridge扩展与CE签名处理ISO 9660是光盘文件系统的基础标准但它不支持Unix风格的长文件名、符号链接、权限和所有权信息。Rock Ridge扩展通过System Use Sharing ProtocolSUSP在ISO 9660目录记录的System Use字段中嵌入额外的属性记录使光盘文件系统能够表达完整的Unix语义。ISO 9660的每个目录记录有一个固定长度的系统使用区域System Use Area起始于目录记录偏移量X由Directory Record Length字段决定。Rock Ridge扩展的System Use字段在isofs中通过以下结构解析struct iso_directory_record {char length;char ext_attr_length;char extent[8];char size[8];char date[7];char flags;char file_unit_size;char interleave;char volume_sequence_number[4];unsigned char name_len;char name[0];} __attribute__((packed));在name之后紧跟着System Use字段。Rock Ridge核心的入口解析函数是parse_rock_ridge_inode_internal()它遍历系统使用区域并处理每个SUSP条目static int parse_rock_ridge_inode_internal(struct iso_inode_info *inode,struct inode *iget_inode,int regard_as_data){int sig;unsigned int len;unsigned char *rr inode-i_sb-s_rock_ridge;unsigned char *ptr, *end;struct rock_ridge *ri;struct ce_handle ce;int ret 0;ptr inode-i_sb-s_rock_ridge;end ptr inode-i_sb-s_rock_ridge_size;while (ptr end) {struct rock_ridge *rr (struct rock_ridge *)ptr;sig (rr-signature[0] 8) | rr-signature[1];len rr-len;if (len 4 || ptr len end)break;根据SPSystem Use Sharing Protocol规范每个SUSP条目的格式为2字节签名、1字节长度、1字节版本。不同的签名对应的处理分支如下switch (sig) {case SIG_RR:inode-i_rock_ridge rr-u.RR.flags;break;case SIG_PX:inode-i_mode isonum_733(rr-u.PX.mode);inode-i_uid isonum_733(rr-u.PX.uid);inode-i_gid isonum_733(rr-u.PX.gid);break;case SIG_PN:inode-i_rdev old_decode_dev(isonum_733(rr-u.PN.dev));break;case SIG_SL:parse_rock_ridge_symlink(rr, inode);break;case SIG_NM:parse_rock_ridge_filename(rr, inode);break;case SIG_CL:inode-i_ino isonum_733(rr-u.CL.location);break;case SIG_PL:inode-i_ino isonum_733(rr-u.PL.location);break;case SIG_CE:ce.extent isonum_733(rr-u.CE.extent);ce.offset isonum_733(rr-u.CE.offset);ce.size isonum_733(rr-u.CE.size);ret rock_ridge_continue(inode, ce);if (ret)return ret;break;}ptr len;}return ret;}CE签名SIG_CE, 0x4345的处理最为特殊。CE条目的作用是提供Continuation Area延续区域当系统使用区域不足以容纳所有Rock Ridge条目时CE通过一个独立的extent扩展存储空间。CE条目包含三个32位字段extent逻辑块号、offset块内偏移、size数据大小。rock_ridge_continue()处理CE扩展区的读取static int rock_ridge_continue(struct iso_inode_info *inode,struct ce_handle *ce){int blocksize inode-i_sb-s_blocksize;struct buffer_head *bh;unsigned char *ptr;int ret;bh sb_bread(inode-i_sb, ce-extent);if (!bh)return -EIO;ptr bh-b_data ce-offset;inode-i_sb-s_rock_ridge kmalloc(ce-size, GFP_KERNEL);if (!inode-i_sb-s_rock_ridge) {brelse(bh);return -ENOMEM;}memcpy(inode-i_sb-s_rock_ridge, ptr, ce-size);inode-i_sb-s_rock_ridge_size ce-size;brelse(bh);return 0;}该函数通过sb_bread()读取CE扩展区的数据块将其中offset偏移处开始、长度为size的数据复制到s_rock_ridge缓冲区中。之后主解析循环继续从这个新缓冲区读取剩余的Rock Ridge条目。Rock Ridge条目的验证涉及checksum校验。每个条目的第4字节起如果version字段匹配则使用SP签名中的checksum字段验证数据完整性。SP条目是SUSP协议中的第一个条目位于系统使用区域的起始处case SIG_SP:if (rr-u.SP.len_skp 4)break;inode-i_sb-s_rock_offset rr-u.SP.len_skp;break;SP条目的len_skp字段指定了系统使用区域的起始偏移通常为4所有后续条目从该偏移开始解析。ERExtensions Reference条目声明了使用的扩展协议ID包括Rock Ridge的版本信息和POSIX属性声明。当isofs检测到Rock Ridge的ER签名时会设置inode-i_rock_ridge标志位启用Unix语义的完整处理。RRRock Ridge条目本身是一个位掩码其中RR_PX位表示存在POSIX属性RR_PN表示存在设备号RR_SL表示符号链接RR_NM表示备用文件名RR_CL/RR_PL表示子目录/父目录链接用于处理深度超过8层的目录层次结构。Rock Ridge通过CLChild Link和PLParent Link机制解决ISO 9660目录深度限制问题。CL条目将一个目录记录标记为指向另一个位置的符号链接而PL条目提供父目录的逆向链接。这种机制使得ISO 9660原本受限的8层目录可以扩展到任意深度。