linux/fs/udf/inode.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * inode.c
 *
 * PURPOSE
 *  Inode handling routines for the OSTA-UDF(tm) filesystem.
 *
 * COPYRIGHT
 *  (C) 1998 Dave Boynton
 *  (C) 1998-2004 Ben Fennema
 *  (C) 1999-2000 Stelias Computing Inc
 *
 * HISTORY
 *
 *  10/04/98 dgb  Added rudimentary directory functions
 *  10/07/98      Fully working udf_block_map! It works!
 *  11/25/98      bmap altered to better support extents
 *  12/06/98 blf  partition support in udf_iget, udf_block_map
 *                and udf_read_inode
 *  12/12/98      rewrote udf_block_map to handle next extents and descs across
 *                block boundaries (which is not actually allowed)
 *  12/20/98      added support for strategy 4096
 *  03/07/99      rewrote udf_block_map (again)
 *                New funcs, inode_bmap, udf_next_aext
 *  04/19/99      Support for writing device EA's for major/minor #
 */

#include "udfdecl.h"
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/writeback.h>
#include <linux/slab.h>
#include <linux/crc-itu-t.h>
#include <linux/mpage.h>
#include <linux/uio.h>
#include <linux/bio.h>

#include "udf_i.h"
#include "udf_sb.h"

#define EXTENT_MERGE_SIZE

#define FE_MAPPED_PERMS

#define FE_DELETE_PERMS

struct udf_map_rq;

static umode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static int udf_sync_inode(struct inode *inode);
static int udf_alloc_i_data(struct inode *inode, size_t size);
static int inode_getblk(struct inode *inode, struct udf_map_rq *map);
static int udf_insert_aext(struct inode *, struct extent_position,
			   struct kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, udf_pblk_t,
			      struct kernel_long_ad *, int *);
static void udf_prealloc_extents(struct inode *, int, int,
				 struct kernel_long_ad *, int *);
static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *);
static int udf_update_extents(struct inode *, struct kernel_long_ad *, int,
			      int, struct extent_position *);
static int udf_get_block_wb(struct inode *inode, sector_t block,
			    struct buffer_head *bh_result, int create);

static void __udf_clear_extent_cache(struct inode *inode)
{}

/* Invalidate extent cache */
static void udf_clear_extent_cache(struct inode *inode)
{}

/* Return contents of extent cache */
static int udf_read_extent_cache(struct inode *inode, loff_t bcount,
				 loff_t *lbcount, struct extent_position *pos)
{}

/* Add extent to extent cache */
static void udf_update_extent_cache(struct inode *inode, loff_t estart,
				    struct extent_position *pos)
{}

void udf_evict_inode(struct inode *inode)
{}

static void udf_write_failed(struct address_space *mapping, loff_t to)
{}

static int udf_adinicb_writepage(struct folio *folio,
				 struct writeback_control *wbc, void *data)
{}

static int udf_writepages(struct address_space *mapping,
			  struct writeback_control *wbc)
{}

static void udf_adinicb_read_folio(struct folio *folio)
{}

static int udf_read_folio(struct file *file, struct folio *folio)
{}

static void udf_readahead(struct readahead_control *rac)
{}

static int udf_write_begin(struct file *file, struct address_space *mapping,
			   loff_t pos, unsigned len,
			   struct page **pagep, void **fsdata)
{}

static int udf_write_end(struct file *file, struct address_space *mapping,
			 loff_t pos, unsigned len, unsigned copied,
			 struct page *page, void *fsdata)
{}

static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
{}

static sector_t udf_bmap(struct address_space *mapping, sector_t block)
{}

const struct address_space_operations udf_aops =;

/*
 * Expand file stored in ICB to a normal one-block-file
 *
 * This function requires i_mutex held
 */
int udf_expand_file_adinicb(struct inode *inode)
{}

#define UDF_MAP_CREATE
#define UDF_MAP_NOPREALLOC

#define UDF_BLK_MAPPED
#define UDF_BLK_NEW

struct udf_map_rq {};

static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
{}

static int __udf_get_block(struct inode *inode, sector_t block,
			   struct buffer_head *bh_result, int flags)
{}

int udf_get_block(struct inode *inode, sector_t block,
		  struct buffer_head *bh_result, int create)
{}

/*
 * We shouldn't be allocating blocks on page writeback since we allocate them
 * on page fault. We can spot dirty buffers without allocated blocks though
 * when truncate expands file. These however don't have valid data so we can
 * safely ignore them. So never allocate blocks from page writeback.
 */
static int udf_get_block_wb(struct inode *inode, sector_t block,
			    struct buffer_head *bh_result, int create)
{}

/* Extend the file with new blocks totaling 'new_block_bytes',
 * return the number of extents added
 */
static int udf_do_extend_file(struct inode *inode,
			      struct extent_position *last_pos,
			      struct kernel_long_ad *last_ext,
			      loff_t new_block_bytes)
{}

/* Extend the final block of the file to final_block_len bytes */
static void udf_do_extend_final_block(struct inode *inode,
				      struct extent_position *last_pos,
				      struct kernel_long_ad *last_ext,
				      uint32_t new_elen)
{}

static int udf_extend_file(struct inode *inode, loff_t newsize)
{}

static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
{}

static void udf_split_extents(struct inode *inode, int *c, int offset,
			       udf_pblk_t newblocknum,
			       struct kernel_long_ad *laarr, int *endnum)
{}

static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
				 struct kernel_long_ad *laarr,
				 int *endnum)
{}

static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
			      int *endnum)
{}

static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
			      int startnum, int endnum,
			      struct extent_position *epos)
{}

struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
			      int create, int *err)
{}

int udf_setsize(struct inode *inode, loff_t newsize)
{}

/*
 * Maximum length of linked list formed by ICB hierarchy. The chosen number is
 * arbitrary - just that we hopefully don't limit any real use of rewritten
 * inode on write-once media but avoid looping for too long on corrupted media.
 */
#define UDF_MAX_ICB_NESTING

static int udf_read_inode(struct inode *inode, bool hidden_inode)
{}

static int udf_alloc_i_data(struct inode *inode, size_t size)
{}

static umode_t udf_convert_permissions(struct fileEntry *fe)
{}

void udf_update_extra_perms(struct inode *inode, umode_t mode)
{}

int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
{}

static int udf_sync_inode(struct inode *inode)
{}

static void udf_adjust_time(struct udf_inode_info *iinfo, struct timespec64 time)
{}

static int udf_update_inode(struct inode *inode, int do_sync)
{}

struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino,
			 bool hidden_inode)
{}

int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
			    struct extent_position *epos)
{}

/*
 * Append extent at the given position - should be the first free one in inode
 * / indirect extent. This function assumes there is enough space in the inode
 * or indirect extent. Use udf_add_aext() if you didn't check for this before.
 */
int __udf_add_aext(struct inode *inode, struct extent_position *epos,
		   struct kernel_lb_addr *eloc, uint32_t elen, int inc)
{}

/*
 * Append extent at given position - should be the first free one in inode
 * / indirect extent. Takes care of allocating and linking indirect blocks.
 */
int udf_add_aext(struct inode *inode, struct extent_position *epos,
		 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
{}

void udf_write_aext(struct inode *inode, struct extent_position *epos,
		    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
{}

/*
 * Only 1 indirect extent in a row really makes sense but allow upto 16 in case
 * someone does some weird stuff.
 */
#define UDF_MAX_INDIR_EXTS

int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
		     struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
{}

int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
			struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
{}

static int udf_insert_aext(struct inode *inode, struct extent_position epos,
			   struct kernel_lb_addr neloc, uint32_t nelen)
{}

int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
{}

int8_t inode_bmap(struct inode *inode, sector_t block,
		  struct extent_position *pos, struct kernel_lb_addr *eloc,
		  uint32_t *elen, sector_t *offset)
{}