11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * ialloc.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * PURPOSE 51da177e4SLinus Torvalds * Inode allocation handling routines for the OSTA-UDF(tm) filesystem. 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * COPYRIGHT 81da177e4SLinus Torvalds * This file is distributed under the terms of the GNU General Public 91da177e4SLinus Torvalds * License (GPL). Copies of the GPL can be obtained from: 101da177e4SLinus Torvalds * ftp://prep.ai.mit.edu/pub/gnu/GPL 111da177e4SLinus Torvalds * Each contributing author retains all rights to their own work. 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * (C) 1998-2001 Ben Fennema 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * HISTORY 161da177e4SLinus Torvalds * 171da177e4SLinus Torvalds * 02/24/99 blf Created. 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds */ 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #include "udfdecl.h" 221da177e4SLinus Torvalds #include <linux/fs.h> 231da177e4SLinus Torvalds #include <linux/sched.h> 241da177e4SLinus Torvalds #include <linux/slab.h> 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds #include "udf_i.h" 271da177e4SLinus Torvalds #include "udf_sb.h" 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds void udf_free_inode(struct inode *inode) 301da177e4SLinus Torvalds { 31*085cf7b7SJan Kara udf_free_blocks(inode->i_sb, NULL, &UDF_I(inode)->i_location, 0, 1); 321da177e4SLinus Torvalds } 331da177e4SLinus Torvalds 340b93a92bSAl Viro struct inode *udf_new_inode(struct inode *dir, umode_t mode) 351da177e4SLinus Torvalds { 361da177e4SLinus Torvalds struct super_block *sb = dir->i_sb; 371da177e4SLinus Torvalds struct udf_sb_info *sbi = UDF_SB(sb); 381da177e4SLinus Torvalds struct inode *inode; 39b490bdd6SSteve Magnani udf_pblk_t block; 40c0b34438SMarcin Slusarz uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; 4148d6d8ffSMarcin Slusarz struct udf_inode_info *iinfo; 4248d6d8ffSMarcin Slusarz struct udf_inode_info *dinfo = UDF_I(dir); 430b93a92bSAl Viro int err; 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds inode = new_inode(sb); 461da177e4SLinus Torvalds 470b93a92bSAl Viro if (!inode) 480b93a92bSAl Viro return ERR_PTR(-ENOMEM); 491da177e4SLinus Torvalds 5048d6d8ffSMarcin Slusarz iinfo = UDF_I(inode); 5197e1cfb0SJan Kara if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) { 5297e1cfb0SJan Kara iinfo->i_efe = 1; 5397e1cfb0SJan Kara if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev) 5497e1cfb0SJan Kara sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE; 55382a2287SJan Kara iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - 5697e1cfb0SJan Kara sizeof(struct extendedFileEntry), 5797e1cfb0SJan Kara GFP_KERNEL); 5897e1cfb0SJan Kara } else { 5997e1cfb0SJan Kara iinfo->i_efe = 0; 60382a2287SJan Kara iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - 6197e1cfb0SJan Kara sizeof(struct fileEntry), 6297e1cfb0SJan Kara GFP_KERNEL); 6397e1cfb0SJan Kara } 64382a2287SJan Kara if (!iinfo->i_data) { 65f05f2429SJan Kara make_bad_inode(inode); 6697e1cfb0SJan Kara iput(inode); 670b93a92bSAl Viro return ERR_PTR(-ENOMEM); 6897e1cfb0SJan Kara } 69225add61SEric Sandeen 700b93a92bSAl Viro err = -ENOSPC; 714b11111aSMarcin Slusarz block = udf_new_block(dir->i_sb, NULL, 7248d6d8ffSMarcin Slusarz dinfo->i_location.partitionReferenceNum, 730b93a92bSAl Viro start, &err); 740b93a92bSAl Viro if (err) { 75f05f2429SJan Kara make_bad_inode(inode); 761da177e4SLinus Torvalds iput(inode); 770b93a92bSAl Viro return ERR_PTR(err); 781da177e4SLinus Torvalds } 791da177e4SLinus Torvalds 80d664b6afSJan Kara iinfo->i_unique = lvid_get_unique_id(sb); 81470cca56SJan Kara inode->i_generation = iinfo->i_unique; 82a6c5a034SDmitry Monakhov 8321cb47beSChristian Brauner inode_init_owner(&init_user_ns, inode, dir, mode); 84ecd10aa4SJan Kara if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) 85ecd10aa4SJan Kara inode->i_uid = sbi->s_uid; 86ecd10aa4SJan Kara if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET)) 87ecd10aa4SJan Kara inode->i_gid = sbi->s_gid; 881da177e4SLinus Torvalds 8948d6d8ffSMarcin Slusarz iinfo->i_location.logicalBlockNum = block; 9048d6d8ffSMarcin Slusarz iinfo->i_location.partitionReferenceNum = 9148d6d8ffSMarcin Slusarz dinfo->i_location.partitionReferenceNum; 9297e961fdSPekka Enberg inode->i_ino = udf_get_lb_pblock(sb, &iinfo->i_location, 0); 931da177e4SLinus Torvalds inode->i_blocks = 0; 9448d6d8ffSMarcin Slusarz iinfo->i_lenEAttr = 0; 9548d6d8ffSMarcin Slusarz iinfo->i_lenAlloc = 0; 9648d6d8ffSMarcin Slusarz iinfo->i_use = 0; 97d5e2cf07SSteve Nickel iinfo->i_checkpoint = 1; 98c3367a1bSSteven J. Magnani iinfo->i_extraPerms = FE_PERM_U_CHATTR; 99c3367a1bSSteven J. Magnani udf_update_extra_perms(inode, mode); 100c3367a1bSSteven J. Magnani 1011da177e4SLinus Torvalds if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) 10248d6d8ffSMarcin Slusarz iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; 1031da177e4SLinus Torvalds else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) 10448d6d8ffSMarcin Slusarz iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; 1051da177e4SLinus Torvalds else 10648d6d8ffSMarcin Slusarz iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; 10795582b00SDeepa Dinamani inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); 108c3b9cecdSArnd Bergmann iinfo->i_crtime = inode->i_mtime; 109b2315096SAl Viro if (unlikely(insert_inode_locked(inode) < 0)) { 110b2315096SAl Viro make_bad_inode(inode); 111b2315096SAl Viro iput(inode); 1120b93a92bSAl Viro return ERR_PTR(-EIO); 113b2315096SAl Viro } 1141da177e4SLinus Torvalds mark_inode_dirty(inode); 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds return inode; 1171da177e4SLinus Torvalds } 118