?? inode.c
字號:
UDF_I_UMTIME(inode) = 0; } if ( udf_stamp_to_time(&convtime, &convtime_usec, lets_to_cpu(fe->attrTime)) ) { inode->i_ctime = convtime; UDF_I_UCTIME(inode) = convtime_usec; } else { inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); UDF_I_UCTIME(inode) = 0; } UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID); UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr); UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs); offset = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode); alen = offset + UDF_I_LENALLOC(inode); } else { inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << (inode->i_sb->s_blocksize_bits - 9); if ( udf_stamp_to_time(&convtime, &convtime_usec, lets_to_cpu(efe->accessTime)) ) { inode->i_atime = convtime; } else { inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb); } if ( udf_stamp_to_time(&convtime, &convtime_usec, lets_to_cpu(efe->modificationTime)) ) { inode->i_mtime = convtime; UDF_I_UMTIME(inode) = convtime_usec; } else { inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb); UDF_I_UMTIME(inode) = 0; } if ( udf_stamp_to_time(&convtime, &convtime_usec, lets_to_cpu(efe->createTime)) ) { UDF_I_CRTIME(inode) = convtime; UDF_I_UCRTIME(inode) = convtime_usec; } else { UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb); UDF_I_UCRTIME(inode) = 0; } if ( udf_stamp_to_time(&convtime, &convtime_usec, lets_to_cpu(efe->attrTime)) ) { inode->i_ctime = convtime; UDF_I_UCTIME(inode) = convtime_usec; } else { inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); UDF_I_UCTIME(inode) = 0; } UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID); UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr); UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs); offset = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode); alen = offset + UDF_I_LENALLOC(inode); } switch (fe->icbTag.fileType) { case FILE_TYPE_DIRECTORY: { inode->i_op = &udf_dir_inode_operations; inode->i_fop = &udf_dir_operations; inode->i_mode |= S_IFDIR; inode->i_nlink ++; break; } case FILE_TYPE_REALTIME: case FILE_TYPE_REGULAR: case FILE_TYPE_NONE: { inode->i_data.a_ops = &udf_adinicb_aops; else inode->i_data.a_ops = &udf_aops; inode->i_op = &udf_file_inode_operations; inode->i_fop = &udf_file_operations; inode->i_mode |= S_IFREG; break; } case FILE_TYPE_BLOCK: { inode->i_mode |= S_IFBLK; break; } case FILE_TYPE_CHAR: { inode->i_mode |= S_IFCHR; break; } case FILE_TYPE_FIFO: { init_special_inode(inode, inode->i_mode | S_IFIFO, 0); break; } case FILE_TYPE_SYMLINK: { inode->i_data.a_ops = &udf_symlink_aops; inode->i_op = &page_symlink_inode_operations; inode->i_mode = S_IFLNK|S_IRWXUGO; break; } default: { printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n", inode->i_ino, fe->icbTag.fileType); make_bad_inode(inode); return; } } if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { struct buffer_head *tbh = NULL; struct DeviceSpecificationExtendedAttr *dsea = (struct DeviceSpecificationExtendedAttr *) udf_get_extendedattr(inode, 12, 1, &tbh); if (dsea) { init_special_inode(inode, inode->i_mode, ((le32_to_cpu(dsea->majorDeviceIdent)) << 8) | (le32_to_cpu(dsea->minorDeviceIdent) & 0xFF)); /* Developer ID ??? */ udf_release_data(tbh); } else { make_bad_inode(inode); } }}static mode_tudf_convert_permissions(struct FileEntry *fe){ mode_t mode; Uint32 permissions; Uint32 flags; permissions = le32_to_cpu(fe->permissions); flags = le16_to_cpu(fe->icbTag.flags); mode = (( permissions ) & S_IRWXO) | (( permissions >> 2 ) & S_IRWXG) | (( permissions >> 4 ) & S_IRWXU) | (( flags & ICB_FLAG_SETUID) ? S_ISUID : 0) | (( flags & ICB_FLAG_SETGID) ? S_ISGID : 0) | (( flags & ICB_FLAG_STICKY) ? S_ISVTX : 0); return mode;}/* * udf_write_inode * * PURPOSE * Write out the specified inode. * * DESCRIPTION * This routine is called whenever an inode is synced. * Currently this routine is just a placeholder. * * HISTORY * July 1, 1997 - Andrew E. Mileski * Written, tested, and released. */void udf_write_inode(struct inode * inode, int sync){ lock_kernel(); udf_update_inode(inode, sync); unlock_kernel();}int udf_sync_inode(struct inode * inode){ return udf_update_inode(inode, 1);}static intudf_update_inode(struct inode *inode, int do_sync){ struct buffer_head *bh = NULL; struct FileEntry *fe; struct ExtendedFileEntry *efe; Uint32 udfperms; Uint16 icbflags; Uint16 crclen; int i; timestamp cpu_time; int err = 0; bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); if (!bh) { udf_debug("bread failure\n"); return -EIO; } fe = (struct FileEntry *)bh->b_data; efe = (struct ExtendedFileEntry *)bh->b_data; if (UDF_I_NEW_INODE(inode) == 1) { if (UDF_I_EXTENDED_FE(inode) == 0) memset(bh->b_data, 0x00, sizeof(struct FileEntry)); else memset(bh->b_data, 0x00, sizeof(struct ExtendedFileEntry)); memset(bh->b_data + udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode), 0x0, inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) - UDF_I_LENALLOC(inode)); UDF_I_NEW_INODE(inode) = 0; } if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY) { struct UnallocatedSpaceEntry *use = (struct UnallocatedSpaceEntry *)bh->b_data; use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) - sizeof(tag); use->descTag.descCRCLength = cpu_to_le16(crclen); use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0)); use->descTag.tagChecksum = 0; for (i=0; i<16; i++) if (i != 4) use->descTag.tagChecksum += ((Uint8 *)&(use->descTag))[i]; mark_buffer_dirty(bh); udf_release_data(bh); return err; } if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) fe->uid = cpu_to_le32(inode->i_uid); if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) fe->gid = cpu_to_le32(inode->i_gid); udfperms = ((inode->i_mode & S_IRWXO) ) | ((inode->i_mode & S_IRWXG) << 2) | ((inode->i_mode & S_IRWXU) << 4); udfperms |= (le32_to_cpu(fe->permissions) & (PERM_O_DELETE | PERM_O_CHATTR | PERM_G_DELETE | PERM_G_CHATTR | PERM_U_DELETE | PERM_U_CHATTR)); fe->permissions = cpu_to_le32(udfperms); if (S_ISDIR(inode->i_mode)) fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); else fe->fileLinkCount = cpu_to_le16(inode->i_nlink); fe->informationLength = cpu_to_le64(inode->i_size); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { EntityID *eid; struct buffer_head *tbh = NULL; struct DeviceSpecificationExtendedAttr *dsea = (struct DeviceSpecificationExtendedAttr *) udf_get_extendedattr(inode, 12, 1, &tbh); if (!dsea) { dsea = (struct DeviceSpecificationExtendedAttr *) udf_add_extendedattr(inode, sizeof(struct DeviceSpecificationExtendedAttr) + sizeof(EntityID), 12, 0x3, &tbh); dsea->attrType = 12; dsea->attrSubtype = 1; dsea->attrLength = sizeof(struct DeviceSpecificationExtendedAttr) + sizeof(EntityID); dsea->impUseLength = sizeof(EntityID); } eid = (EntityID *)dsea->impUse; memset(eid, 0, sizeof(EntityID)); strcpy(eid->ident, UDF_ID_DEVELOPER); eid->identSuffix[0] = UDF_OS_CLASS_UNIX; eid->identSuffix[1] = UDF_OS_ID_LINUX; dsea->majorDeviceIdent = kdev_t_to_nr(inode->i_rdev) >> 8; dsea->minorDeviceIdent = kdev_t_to_nr(inode->i_rdev) & 0xFF; mark_buffer_dirty_inode(tbh, inode); udf_release_data(tbh); } if (UDF_I_EXTENDED_FE(inode) == 0) { fe->logicalBlocksRecorded = cpu_to_le64( (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> (inode->i_sb->s_blocksize_bits - 9)); if (udf_time_to_stamp(&cpu_time, inode->i_atime, 0)) fe->accessTime = cpu_to_lets(cpu_time); if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode))) fe->modificationTime = cpu_to_lets(cpu_time); if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode))) fe->attrTime = cpu_to_lets(cpu_time); memset(&(fe->impIdent), 0, sizeof(EntityID)); strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); fe->descTag.tagIdent = le16_to_cpu(TID_FILE_ENTRY); crclen = sizeof(struct FileEntry); } else { efe->objectSize = cpu_to_le64(inode->i_size); efe->logicalBlocksRecorded = cpu_to_le64( (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> (inode->i_sb->s_blocksize_bits - 9)); if (UDF_I_CRTIME(inode) >= inode->i_atime) { UDF_I_CRTIME(inode) = inode->i_atime; UDF_I_UCRTIME(inode) = 0; } if (UDF_I_CRTIME(inode) > inode->i_mtime || (UDF_I_CRTIME(inode) == inode->i_mtime && UDF_I_UCRTIME(inode) > UDF_I_UMTIME(inode))) { UDF_I_CRTIME(inode) = inode->i_mtime; UDF_I_UCRTIME(inode) = UDF_I_UMTIME(inode); } if (UDF_I_CRTIME(inode) > inode->i_ctime || (UDF_I_CRTIME(inode) == inode->i_ctime && UDF_I_UCRTIME(inode) > UDF_I_UCTIME(inode))) { UDF_I_CRTIME(inode) = inode->i_ctime; UDF_I_UCRTIME(inode) = UDF_I_UCTIME(inode); } if (udf_time_to_stamp(&cpu_time, inode->i_atime, 0)) efe->accessTime = cpu_to_lets(cpu_time); if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode))) efe->modificationTime = cpu_to_lets(cpu_time); if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode), UDF_I_UCRTIME(inode))) efe->createTime = cpu_to_lets(cpu_time); if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode))) efe->attrTime = cpu_to_lets(cpu_time); memset(&(efe->impIdent), 0, sizeof(EntityID)); strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode)); efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode)); efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); efe->descTag.tagIdent = le16_to_cpu(TID_EXTENDED_FILE_ENTRY); crclen = sizeof(struct ExtendedFileEntry); } if (UDF_I_STRAT4096(inode)) { fe->icbTag.strategyType = cpu_to_le16(4096); fe->icbTag.strategyParameter = cpu_to_le16(1); fe->icbTag.numEntries = cpu_to_le16(2); } else { fe->icbTag.strategyType = cpu_to_le16(4); fe->icbTag.numEntries = cpu_to_le16(1); } if (S_ISDIR(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_DIRECTORY; else if (S_ISREG(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_REGULAR; else if (S_ISLNK(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_SYMLINK; else if (S_ISBLK(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_BLOCK; else if (S_ISCHR(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_CHAR; else if (S_ISFIFO(inode->i_mode)) fe->icbTag.fileType = FILE_TYPE_FIFO; icbflags = UDF_I_ALLOCTYPE(inode) | ((inode->i_mode & S_ISUID) ? ICB_FLAG_SETUID : 0) | ((inode->i_mode & S_ISGID) ? ICB_FLAG_SETGID : 0) | ((inode->i_mode & S_ISVTX) ? ICB_FLAG_STICKY : 0) | (le16_to_cpu(fe->icbTag.flags) & ~(ICB_FLAG_ALLOC_MASK | ICB_FLAG_SETUID | ICB_FLAG_SETGID | ICB_FLAG_STICKY)); fe->icbTag.flags = cpu_to_le16(icbflags); fe->descTag.descVersion = cpu_to_le16(2); fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag); fe->descTag.descCRCLength = cpu_to_le16(crclen); fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0)); fe->descTag.tagChecksum = 0; for (i=0; i<16; i++) if (i != 4) fe->descTag.tagChecksum += ((Uint8 *)&(fe->descTag))[i]; /* write the data blocks */ mark_buffer_dirty(bh); if (do_sync) { ll_rw_block(WRITE, 1, &bh); wait_on_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk("IO error syncing udf inode [%s:%08lx]\n", bdevname(inode->i_dev), inode->i_ino); err = -EIO; } } udf_release_data(bh); return err;}/* * udf_iget * * PURPOSE * Get an inode. * * DESCRIPTION * This routine replaces iget() and read_inode(). * * HISTORY * October 3, 1997 - Andrew E. Mileski * Written, tested, and released. * * 12/19/98 dgb Added semaphore and changed to be a wrapper of iget */struct inode *udf_iget(struct super_block *sb, lb_addr ino){ struct inode *inode; unsigned long block; block = udf_get_lb_pblock(sb, ino, 0); /* Get the inode */ inode = iget(sb, block); /* calls udf_read_inode() ! */ if (!inode) { printk(KERN_ERR "udf: iget() failed\n"); return NULL; } else if (is_bad_inode(inode)) { iput(inode); return NULL; } else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF && UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF) { memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr)); __udf_read_inode(inode); if (is_bad_inode(inode)) { iput(inode); return NULL; } } if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) ) { udf_debug("block=%d, partition=%d out of range\n", ino.logicalBlockNum, ino.partitionReferenceNum); make_bad_inode(inode); iput(inode); return NULL; } return inode;}Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset, lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc){ int adsize; short_ad *sad = NULL; long_ad *lad = NULL; struct AllocExtDesc *aed; int ret; if (!(*bh)) { if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) { udf_debug("reading block %d failed!\n", udf_get_lb_pblock(inode->i_sb, *bloc, 0)); return -1; } } if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) adsize = sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) adsize = sizeof(long_ad); else return -1; if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) { char *sptr, *dptr; struct buffer_head *nbh; int err, loffset; lb_addr obloc = *bloc; if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, inode, obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) { return -1; } if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) { return -1; } lock_buffer(nbh); memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize); mark_buffer_uptodate(nbh, 1); unlock_buffer(nbh); mark_buffer_dirty_inode(nbh, inode);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -