struct fileIdentDesc * udf_fileident_read(struct inode *dir, loff_t *nf_pos, struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi, struct extent_position *epos, kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) { struct fileIdentDesc *fi; int i, num, block; struct buffer_head * tmp, * bha[16]; fibh->soffset = fibh->eoffset; if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) { fi = udf_get_fileident(UDF_I_DATA(dir) - (UDF_I_EFE(dir) ? sizeof(struct extendedFileEntry) : sizeof(struct fileEntry)), dir->i_sb->s_blocksize, &(fibh->eoffset)); if (!fi) return NULL; *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc)); return fi; }
static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t ppos) { ssize_t retval; struct file *file = iocb->ki_filp; struct inode *inode = file->f_path.dentry->d_inode; int err, pos; size_t count = iocb->ki_left; if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { if (file->f_flags & O_APPEND) pos = inode->i_size; else pos = ppos; if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + pos + count)) { udf_expand_file_adinicb(inode, pos + count, &err); if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { udf_debug("udf_expand_adinicb: err=%d\n", err); return err; } } else { if (pos + count > inode->i_size) UDF_I_LENALLOC(inode) = pos + count; else UDF_I_LENALLOC(inode) = inode->i_size; } } retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); if (retval > 0) mark_inode_dirty(inode); return retval; }
static int udf_symlink_filler(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; struct buffer_head *bh = NULL; char *symlink; int err = -EIO; char *p = kmap(page); lock_kernel(); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) { bh = udf_tread(inode->i_sb, inode->i_ino); if (!bh) goto out; symlink = bh->b_data + udf_file_entry_alloc_offset(inode); } else { bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); if (!bh) goto out; symlink = bh->b_data; } udf_pc_to_char(symlink, inode->i_size, p); udf_release_data(bh); unlock_kernel(); SetPageUptodate(page); kunmap(page); UnlockPage(page); return 0; out: unlock_kernel(); SetPageError(page); kunmap(page); UnlockPage(page); return err; }
struct inode * udf_new_inode (struct inode *dir, int mode, int * err) { struct super_block *sb; struct inode * inode; int block; Uint32 start = UDF_I_LOCATION(dir).logicalBlockNum; sb = dir->i_sb; inode = new_inode(sb); if (!inode) { *err = -ENOMEM; return NULL; } *err = -ENOSPC; block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, start, err); if (*err) { iput(inode); return NULL; } lock_super(sb); if (UDF_SB_LVIDBH(sb)) { struct LogicalVolHeaderDesc *lvhd; Uint64 uniqueID; lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse); if (S_ISDIR(mode)) UDF_SB_LVIDIU(sb)->numDirs = cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1); else UDF_SB_LVIDIU(sb)->numFiles = cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1); UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID); if (!(++uniqueID & 0x00000000FFFFFFFFUL)) uniqueID += 16; lvhd->uniqueID = cpu_to_le64(uniqueID); mark_buffer_dirty(UDF_SB_LVIDBH(sb)); } inode->i_mode = mode; inode->i_uid = current->fsuid; if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) mode |= S_ISGID; } else inode->i_gid = current->fsgid; UDF_I_LOCATION(inode).logicalBlockNum = block; UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0); inode->i_blksize = PAGE_SIZE; inode->i_blocks = 0; UDF_I_LENEATTR(inode) = 0; UDF_I_LENALLOC(inode) = 0; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) { UDF_I_EXTENDED_FE(inode) = 1; UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE); } else UDF_I_EXTENDED_FE(inode) = 0; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB; else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT; else UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; inode->i_mtime = inode->i_atime = inode->i_ctime = UDF_I_CRTIME(inode) = CURRENT_TIME; UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = UDF_I_UCRTIME(inode) = CURRENT_UTIME; UDF_I_NEW_INODE(inode) = 1; insert_inode_hash(inode); mark_inode_dirty(inode); unlock_super(sb); if (DQUOT_ALLOC_INODE(inode)) { DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); *err = -EDQUOT; return NULL; } *err = 0; return inode; }
struct inode * udf_new_inode (struct inode *dir, int mode, int * err) { struct super_block *sb = dir->i_sb; struct udf_sb_info *sbi = UDF_SB(sb); struct inode * inode; int block; uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum; inode = new_inode(sb); if (!inode) { *err = -ENOMEM; return NULL; } *err = -ENOSPC; block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, start, err); if (*err) { iput(inode); return NULL; } lock_udf_alloc_sem(sbi); UDF_I_UNIQUE(inode) = 0; UDF_I_LENEXTENTS(inode) = 0; UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; UDF_I_NEXT_ALLOC_GOAL(inode) = 0; UDF_I_STRAT4096(inode) = 0; if (UDF_SB_LVIDBH(sb)) { struct logicalVolHeaderDesc *lvhd; uint64_t uniqueID; lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse); if (S_ISDIR(mode)) UDF_SB_LVIDIU(sb)->numDirs = cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1); else UDF_SB_LVIDIU(sb)->numFiles = cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1); UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID); if (!(++uniqueID & 0x00000000FFFFFFFFUL)) uniqueID += 16; lvhd->uniqueID = cpu_to_le64(uniqueID); mark_buffer_dirty(UDF_SB_LVIDBH(sb)); } inode->i_mode = mode; inode->i_uid = current->fsuid; if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) mode |= S_ISGID; } else inode->i_gid = current->fsgid; UDF_I_LOCATION(inode).logicalBlockNum = block; UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0); inode->i_blksize = PAGE_SIZE; inode->i_blocks = 0; UDF_I_LENEATTR(inode) = 0; UDF_I_LENALLOC(inode) = 0; UDF_I_USE(inode) = 0; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) { UDF_I_EFE(inode) = 1; UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE); UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL); memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); } else { UDF_I_EFE(inode) = 0; UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL); memset(UDF_I_DATA(inode), 0x00, inode->i_sb->s_blocksize - sizeof(struct fileEntry)); } if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT; else UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG; inode->i_mtime = inode->i_atime = inode->i_ctime = UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb); insert_inode_hash(inode); mark_inode_dirty(inode); unlock_udf_alloc_sem(sbi); if (DQUOT_ALLOC_INODE(inode)) { DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); *err = -EDQUOT; return NULL; } *err = 0; return inode; }