1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ialloc.c 4 * 5 * PURPOSE 6 * Inode allocation handling routines for the OSTA-UDF(tm) filesystem. 7 * 8 * COPYRIGHT 9 * (C) 1998-2001 Ben Fennema 10 * 11 * HISTORY 12 * 13 * 02/24/99 blf Created. 14 * 15 */ 16 17 #include "udfdecl.h" 18 #include <linux/fs.h> 19 #include <linux/sched.h> 20 #include <linux/slab.h> 21 22 #include "udf_i.h" 23 #include "udf_sb.h" 24 25 void udf_free_inode(struct inode *inode) 26 { 27 udf_free_blocks(inode->i_sb, NULL, &UDF_I(inode)->i_location, 0, 1); 28 } 29 30 struct inode *udf_new_inode(struct inode *dir, umode_t mode) 31 { 32 struct super_block *sb = dir->i_sb; 33 struct udf_sb_info *sbi = UDF_SB(sb); 34 struct inode *inode; 35 udf_pblk_t block; 36 uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; 37 struct udf_inode_info *iinfo; 38 struct udf_inode_info *dinfo = UDF_I(dir); 39 int err; 40 41 inode = new_inode(sb); 42 43 if (!inode) 44 return ERR_PTR(-ENOMEM); 45 46 iinfo = UDF_I(inode); 47 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) { 48 iinfo->i_efe = 1; 49 if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev) 50 sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE; 51 iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - 52 sizeof(struct extendedFileEntry), 53 GFP_KERNEL); 54 } else { 55 iinfo->i_efe = 0; 56 iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - 57 sizeof(struct fileEntry), 58 GFP_KERNEL); 59 } 60 if (!iinfo->i_data) { 61 make_bad_inode(inode); 62 iput(inode); 63 return ERR_PTR(-ENOMEM); 64 } 65 66 err = -ENOSPC; 67 block = udf_new_block(dir->i_sb, NULL, 68 dinfo->i_location.partitionReferenceNum, 69 start, &err); 70 if (err) { 71 make_bad_inode(inode); 72 iput(inode); 73 return ERR_PTR(err); 74 } 75 76 iinfo->i_unique = lvid_get_unique_id(sb); 77 inode->i_generation = iinfo->i_unique; 78 79 inode_init_owner(&nop_mnt_idmap, inode, dir, mode); 80 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) 81 inode->i_uid = sbi->s_uid; 82 if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET)) 83 inode->i_gid = sbi->s_gid; 84 85 iinfo->i_location.logicalBlockNum = block; 86 iinfo->i_location.partitionReferenceNum = 87 dinfo->i_location.partitionReferenceNum; 88 inode->i_ino = udf_get_lb_pblock(sb, &iinfo->i_location, 0); 89 inode->i_blocks = 0; 90 iinfo->i_lenEAttr = 0; 91 iinfo->i_lenAlloc = 0; 92 iinfo->i_use = 0; 93 iinfo->i_checkpoint = 1; 94 iinfo->i_extraPerms = FE_PERM_U_CHATTR; 95 udf_update_extra_perms(inode, mode); 96 97 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) 98 iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; 99 else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) 100 iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; 101 else 102 iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; 103 simple_inode_init_ts(inode); 104 iinfo->i_crtime = inode_get_mtime(inode); 105 if (unlikely(insert_inode_locked(inode) < 0)) { 106 make_bad_inode(inode); 107 iput(inode); 108 return ERR_PTR(-EIO); 109 } 110 mark_inode_dirty(inode); 111 112 return inode; 113 } 114