2023-05-22 07:54:34 +07:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-16 15:20:36 -07:00
/*
* ialloc . c
*
* PURPOSE
* Inode allocation handling routines for the OSTA - UDF ( tm ) filesystem .
*
* COPYRIGHT
* ( C ) 1998 - 2001 Ben Fennema
*
* HISTORY
*
* 02 / 24 / 99 blf Created .
*
*/
# include "udfdecl.h"
# include <linux/fs.h>
# include <linux/sched.h>
# include <linux/slab.h>
# include "udf_i.h"
# include "udf_sb.h"
2007-07-19 01:47:43 -07:00
void udf_free_inode ( struct inode * inode )
2005-04-16 15:20:36 -07:00
{
2023-01-25 19:31:38 +01:00
udf_free_blocks ( inode - > i_sb , NULL , & UDF_I ( inode ) - > i_location , 0 , 1 ) ;
2005-04-16 15:20:36 -07:00
}
2014-09-04 09:47:41 -04:00
struct inode * udf_new_inode ( struct inode * dir , umode_t mode )
2005-04-16 15:20:36 -07:00
{
struct super_block * sb = dir - > i_sb ;
struct udf_sb_info * sbi = UDF_SB ( sb ) ;
2007-07-19 01:47:43 -07:00
struct inode * inode ;
2017-10-12 08:48:40 -05:00
udf_pblk_t block ;
2008-02-08 04:20:42 -08:00
uint32_t start = UDF_I ( dir ) - > i_location . logicalBlockNum ;
2008-02-08 04:20:44 -08:00
struct udf_inode_info * iinfo ;
struct udf_inode_info * dinfo = UDF_I ( dir ) ;
2014-09-04 09:47:41 -04:00
int err ;
2005-04-16 15:20:36 -07:00
inode = new_inode ( sb ) ;
2014-09-04 09:47:41 -04:00
if ( ! inode )
return ERR_PTR ( - ENOMEM ) ;
2005-04-16 15:20:36 -07:00
2008-02-08 04:20:44 -08:00
iinfo = UDF_I ( inode ) ;
2008-08-18 13:44:48 +02:00
if ( UDF_QUERY_FLAG ( inode - > i_sb , UDF_FLAG_USE_EXTENDED_FE ) ) {
iinfo - > i_efe = 1 ;
if ( UDF_VERS_USE_EXTENDED_FE > sbi - > s_udfrev )
sbi - > s_udfrev = UDF_VERS_USE_EXTENDED_FE ;
2020-09-25 12:29:54 +02:00
iinfo - > i_data = kzalloc ( inode - > i_sb - > s_blocksize -
sizeof ( struct extendedFileEntry ) ,
GFP_KERNEL ) ;
2008-08-18 13:44:48 +02:00
} else {
iinfo - > i_efe = 0 ;
2020-09-25 12:29:54 +02:00
iinfo - > i_data = kzalloc ( inode - > i_sb - > s_blocksize -
sizeof ( struct fileEntry ) ,
GFP_KERNEL ) ;
2008-08-18 13:44:48 +02:00
}
2020-09-25 12:29:54 +02:00
if ( ! iinfo - > i_data ) {
2021-12-14 11:04:29 +01:00
make_bad_inode ( inode ) ;
2008-08-18 13:44:48 +02:00
iput ( inode ) ;
2014-09-04 09:47:41 -04:00
return ERR_PTR ( - ENOMEM ) ;
2008-08-18 13:44:48 +02:00
}
2006-08-05 12:15:17 -07:00
2014-09-04 09:47:41 -04:00
err = - ENOSPC ;
2008-02-08 04:20:36 -08:00
block = udf_new_block ( dir - > i_sb , NULL ,
2008-02-08 04:20:44 -08:00
dinfo - > i_location . partitionReferenceNum ,
2014-09-04 09:47:41 -04:00
start , & err ) ;
if ( err ) {
2021-12-14 11:04:29 +01:00
make_bad_inode ( inode ) ;
2005-04-16 15:20:36 -07:00
iput ( inode ) ;
2014-09-04 09:47:41 -04:00
return ERR_PTR ( err ) ;
2005-04-16 15:20:36 -07:00
}
2023-01-25 19:31:38 +01:00
iinfo - > i_unique = lvid_get_unique_id ( sb ) ;
inode - > i_generation = iinfo - > i_unique ;
2010-03-04 17:32:22 +03:00
2023-01-13 12:49:25 +01:00
inode_init_owner ( & nop_mnt_idmap , inode , dir , mode ) ;
2018-02-21 17:59:31 +01:00
if ( UDF_QUERY_FLAG ( sb , UDF_FLAG_UID_SET ) )
inode - > i_uid = sbi - > s_uid ;
if ( UDF_QUERY_FLAG ( sb , UDF_FLAG_GID_SET ) )
inode - > i_gid = sbi - > s_gid ;
2005-04-16 15:20:36 -07:00
2008-02-08 04:20:44 -08:00
iinfo - > i_location . logicalBlockNum = block ;
iinfo - > i_location . partitionReferenceNum =
dinfo - > i_location . partitionReferenceNum ;
2008-10-15 12:29:03 +02:00
inode - > i_ino = udf_get_lb_pblock ( sb , & iinfo - > i_location , 0 ) ;
2005-04-16 15:20:36 -07:00
inode - > i_blocks = 0 ;
2008-02-08 04:20:44 -08:00
iinfo - > i_lenEAttr = 0 ;
iinfo - > i_lenAlloc = 0 ;
iinfo - > i_use = 0 ;
2012-02-14 00:28:42 -05:00
iinfo - > i_checkpoint = 1 ;
2019-08-27 07:13:59 -05:00
iinfo - > i_extraPerms = FE_PERM_U_CHATTR ;
udf_update_extra_perms ( inode , mode ) ;
2005-04-16 15:20:36 -07:00
if ( UDF_QUERY_FLAG ( inode - > i_sb , UDF_FLAG_USE_AD_IN_ICB ) )
2008-02-08 04:20:44 -08:00
iinfo - > i_alloc_type = ICBTAG_FLAG_AD_IN_ICB ;
2005-04-16 15:20:36 -07:00
else if ( UDF_QUERY_FLAG ( inode - > i_sb , UDF_FLAG_USE_SHORT_AD ) )
2008-02-08 04:20:44 -08:00
iinfo - > i_alloc_type = ICBTAG_FLAG_AD_SHORT ;
2005-04-16 15:20:36 -07:00
else
2008-02-08 04:20:44 -08:00
iinfo - > i_alloc_type = ICBTAG_FLAG_AD_LONG ;
2023-10-04 14:52:59 -04:00
simple_inode_init_ts ( inode ) ;
iinfo - > i_crtime = inode_get_mtime ( inode ) ;
2014-09-04 09:38:11 -04:00
if ( unlikely ( insert_inode_locked ( inode ) < 0 ) ) {
make_bad_inode ( inode ) ;
iput ( inode ) ;
2014-09-04 09:47:41 -04:00
return ERR_PTR ( - EIO ) ;
2014-09-04 09:38:11 -04:00
}
2005-04-16 15:20:36 -07:00
mark_inode_dirty ( inode ) ;
return inode ;
}