cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode.c (9660B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   Copyright (C) International Business Machines Corp., 2000-2004
      4 *   Portions Copyright (C) Christoph Hellwig, 2001-2002
      5 */
      6
      7#include <linux/fs.h>
      8#include <linux/mpage.h>
      9#include <linux/buffer_head.h>
     10#include <linux/pagemap.h>
     11#include <linux/quotaops.h>
     12#include <linux/uio.h>
     13#include <linux/writeback.h>
     14#include "jfs_incore.h"
     15#include "jfs_inode.h"
     16#include "jfs_filsys.h"
     17#include "jfs_imap.h"
     18#include "jfs_extent.h"
     19#include "jfs_unicode.h"
     20#include "jfs_debug.h"
     21#include "jfs_dmap.h"
     22
     23
     24struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
     25{
     26	struct inode *inode;
     27	int ret;
     28
     29	inode = iget_locked(sb, ino);
     30	if (!inode)
     31		return ERR_PTR(-ENOMEM);
     32	if (!(inode->i_state & I_NEW))
     33		return inode;
     34
     35	ret = diRead(inode);
     36	if (ret < 0) {
     37		iget_failed(inode);
     38		return ERR_PTR(ret);
     39	}
     40
     41	if (S_ISREG(inode->i_mode)) {
     42		inode->i_op = &jfs_file_inode_operations;
     43		inode->i_fop = &jfs_file_operations;
     44		inode->i_mapping->a_ops = &jfs_aops;
     45	} else if (S_ISDIR(inode->i_mode)) {
     46		inode->i_op = &jfs_dir_inode_operations;
     47		inode->i_fop = &jfs_dir_operations;
     48	} else if (S_ISLNK(inode->i_mode)) {
     49		if (inode->i_size >= IDATASIZE) {
     50			inode->i_op = &page_symlink_inode_operations;
     51			inode_nohighmem(inode);
     52			inode->i_mapping->a_ops = &jfs_aops;
     53		} else {
     54			inode->i_op = &jfs_fast_symlink_inode_operations;
     55			inode->i_link = JFS_IP(inode)->i_inline;
     56			/*
     57			 * The inline data should be null-terminated, but
     58			 * don't let on-disk corruption crash the kernel
     59			 */
     60			inode->i_link[inode->i_size] = '\0';
     61		}
     62	} else {
     63		inode->i_op = &jfs_file_inode_operations;
     64		init_special_inode(inode, inode->i_mode, inode->i_rdev);
     65	}
     66	unlock_new_inode(inode);
     67	return inode;
     68}
     69
     70/*
     71 * Workhorse of both fsync & write_inode
     72 */
     73int jfs_commit_inode(struct inode *inode, int wait)
     74{
     75	int rc = 0;
     76	tid_t tid;
     77	static int noisy = 5;
     78
     79	jfs_info("In jfs_commit_inode, inode = 0x%p", inode);
     80
     81	/*
     82	 * Don't commit if inode has been committed since last being
     83	 * marked dirty, or if it has been deleted.
     84	 */
     85	if (inode->i_nlink == 0 || !test_cflag(COMMIT_Dirty, inode))
     86		return 0;
     87
     88	if (isReadOnly(inode)) {
     89		/* kernel allows writes to devices on read-only
     90		 * partitions and may think inode is dirty
     91		 */
     92		if (!special_file(inode->i_mode) && noisy) {
     93			jfs_err("jfs_commit_inode(0x%p) called on read-only volume",
     94				inode);
     95			jfs_err("Is remount racy?");
     96			noisy--;
     97		}
     98		return 0;
     99	}
    100
    101	tid = txBegin(inode->i_sb, COMMIT_INODE);
    102	mutex_lock(&JFS_IP(inode)->commit_mutex);
    103
    104	/*
    105	 * Retest inode state after taking commit_mutex
    106	 */
    107	if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
    108		rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
    109
    110	txEnd(tid);
    111	mutex_unlock(&JFS_IP(inode)->commit_mutex);
    112	return rc;
    113}
    114
    115int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
    116{
    117	int wait = wbc->sync_mode == WB_SYNC_ALL;
    118
    119	if (inode->i_nlink == 0)
    120		return 0;
    121	/*
    122	 * If COMMIT_DIRTY is not set, the inode isn't really dirty.
    123	 * It has been committed since the last change, but was still
    124	 * on the dirty inode list.
    125	 */
    126	if (!test_cflag(COMMIT_Dirty, inode)) {
    127		/* Make sure committed changes hit the disk */
    128		jfs_flush_journal(JFS_SBI(inode->i_sb)->log, wait);
    129		return 0;
    130	}
    131
    132	if (jfs_commit_inode(inode, wait)) {
    133		jfs_err("jfs_write_inode: jfs_commit_inode failed!");
    134		return -EIO;
    135	} else
    136		return 0;
    137}
    138
    139void jfs_evict_inode(struct inode *inode)
    140{
    141	struct jfs_inode_info *ji = JFS_IP(inode);
    142
    143	jfs_info("In jfs_evict_inode, inode = 0x%p", inode);
    144
    145	if (!inode->i_nlink && !is_bad_inode(inode)) {
    146		dquot_initialize(inode);
    147
    148		if (JFS_IP(inode)->fileset == FILESYSTEM_I) {
    149			struct inode *ipimap = JFS_SBI(inode->i_sb)->ipimap;
    150			truncate_inode_pages_final(&inode->i_data);
    151
    152			if (test_cflag(COMMIT_Freewmap, inode))
    153				jfs_free_zero_link(inode);
    154
    155			if (ipimap && JFS_IP(ipimap)->i_imap)
    156				diFree(inode);
    157
    158			/*
    159			 * Free the inode from the quota allocation.
    160			 */
    161			dquot_free_inode(inode);
    162		}
    163	} else {
    164		truncate_inode_pages_final(&inode->i_data);
    165	}
    166	clear_inode(inode);
    167	dquot_drop(inode);
    168
    169	BUG_ON(!list_empty(&ji->anon_inode_list));
    170
    171	spin_lock_irq(&ji->ag_lock);
    172	if (ji->active_ag != -1) {
    173		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
    174		atomic_dec(&bmap->db_active[ji->active_ag]);
    175		ji->active_ag = -1;
    176	}
    177	spin_unlock_irq(&ji->ag_lock);
    178}
    179
    180void jfs_dirty_inode(struct inode *inode, int flags)
    181{
    182	static int noisy = 5;
    183
    184	if (isReadOnly(inode)) {
    185		if (!special_file(inode->i_mode) && noisy) {
    186			/* kernel allows writes to devices on read-only
    187			 * partitions and may try to mark inode dirty
    188			 */
    189			jfs_err("jfs_dirty_inode called on read-only volume");
    190			jfs_err("Is remount racy?");
    191			noisy--;
    192		}
    193		return;
    194	}
    195
    196	set_cflag(COMMIT_Dirty, inode);
    197}
    198
    199int jfs_get_block(struct inode *ip, sector_t lblock,
    200		  struct buffer_head *bh_result, int create)
    201{
    202	s64 lblock64 = lblock;
    203	int rc = 0;
    204	xad_t xad;
    205	s64 xaddr;
    206	int xflag;
    207	s32 xlen = bh_result->b_size >> ip->i_blkbits;
    208
    209	/*
    210	 * Take appropriate lock on inode
    211	 */
    212	if (create)
    213		IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
    214	else
    215		IREAD_LOCK(ip, RDWRLOCK_NORMAL);
    216
    217	if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
    218	    (!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) &&
    219	    xaddr) {
    220		if (xflag & XAD_NOTRECORDED) {
    221			if (!create)
    222				/*
    223				 * Allocated but not recorded, read treats
    224				 * this as a hole
    225				 */
    226				goto unlock;
    227			XADoffset(&xad, lblock64);
    228			XADlength(&xad, xlen);
    229			XADaddress(&xad, xaddr);
    230			rc = extRecord(ip, &xad);
    231			if (rc)
    232				goto unlock;
    233			set_buffer_new(bh_result);
    234		}
    235
    236		map_bh(bh_result, ip->i_sb, xaddr);
    237		bh_result->b_size = xlen << ip->i_blkbits;
    238		goto unlock;
    239	}
    240	if (!create)
    241		goto unlock;
    242
    243	/*
    244	 * Allocate a new block
    245	 */
    246	if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
    247		goto unlock;
    248	rc = extAlloc(ip, xlen, lblock64, &xad, false);
    249	if (rc)
    250		goto unlock;
    251
    252	set_buffer_new(bh_result);
    253	map_bh(bh_result, ip->i_sb, addressXAD(&xad));
    254	bh_result->b_size = lengthXAD(&xad) << ip->i_blkbits;
    255
    256      unlock:
    257	/*
    258	 * Release lock on inode
    259	 */
    260	if (create)
    261		IWRITE_UNLOCK(ip);
    262	else
    263		IREAD_UNLOCK(ip);
    264	return rc;
    265}
    266
    267static int jfs_writepage(struct page *page, struct writeback_control *wbc)
    268{
    269	return block_write_full_page(page, jfs_get_block, wbc);
    270}
    271
    272static int jfs_writepages(struct address_space *mapping,
    273			struct writeback_control *wbc)
    274{
    275	return mpage_writepages(mapping, wbc, jfs_get_block);
    276}
    277
    278static int jfs_read_folio(struct file *file, struct folio *folio)
    279{
    280	return mpage_read_folio(folio, jfs_get_block);
    281}
    282
    283static void jfs_readahead(struct readahead_control *rac)
    284{
    285	mpage_readahead(rac, jfs_get_block);
    286}
    287
    288static void jfs_write_failed(struct address_space *mapping, loff_t to)
    289{
    290	struct inode *inode = mapping->host;
    291
    292	if (to > inode->i_size) {
    293		truncate_pagecache(inode, inode->i_size);
    294		jfs_truncate(inode);
    295	}
    296}
    297
    298static int jfs_write_begin(struct file *file, struct address_space *mapping,
    299				loff_t pos, unsigned len,
    300				struct page **pagep, void **fsdata)
    301{
    302	int ret;
    303
    304	ret = nobh_write_begin(mapping, pos, len, pagep, fsdata, jfs_get_block);
    305	if (unlikely(ret))
    306		jfs_write_failed(mapping, pos + len);
    307
    308	return ret;
    309}
    310
    311static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
    312{
    313	return generic_block_bmap(mapping, block, jfs_get_block);
    314}
    315
    316static ssize_t jfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
    317{
    318	struct file *file = iocb->ki_filp;
    319	struct address_space *mapping = file->f_mapping;
    320	struct inode *inode = file->f_mapping->host;
    321	size_t count = iov_iter_count(iter);
    322	ssize_t ret;
    323
    324	ret = blockdev_direct_IO(iocb, inode, iter, jfs_get_block);
    325
    326	/*
    327	 * In case of error extending write may have instantiated a few
    328	 * blocks outside i_size. Trim these off again.
    329	 */
    330	if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
    331		loff_t isize = i_size_read(inode);
    332		loff_t end = iocb->ki_pos + count;
    333
    334		if (end > isize)
    335			jfs_write_failed(mapping, end);
    336	}
    337
    338	return ret;
    339}
    340
    341const struct address_space_operations jfs_aops = {
    342	.dirty_folio	= block_dirty_folio,
    343	.invalidate_folio = block_invalidate_folio,
    344	.read_folio	= jfs_read_folio,
    345	.readahead	= jfs_readahead,
    346	.writepage	= jfs_writepage,
    347	.writepages	= jfs_writepages,
    348	.write_begin	= jfs_write_begin,
    349	.write_end	= nobh_write_end,
    350	.bmap		= jfs_bmap,
    351	.direct_IO	= jfs_direct_IO,
    352};
    353
    354/*
    355 * Guts of jfs_truncate.  Called with locks already held.  Can be called
    356 * with directory for truncating directory index table.
    357 */
    358void jfs_truncate_nolock(struct inode *ip, loff_t length)
    359{
    360	loff_t newsize;
    361	tid_t tid;
    362
    363	ASSERT(length >= 0);
    364
    365	if (test_cflag(COMMIT_Nolink, ip)) {
    366		xtTruncate(0, ip, length, COMMIT_WMAP);
    367		return;
    368	}
    369
    370	do {
    371		tid = txBegin(ip->i_sb, 0);
    372
    373		/*
    374		 * The commit_mutex cannot be taken before txBegin.
    375		 * txBegin may block and there is a chance the inode
    376		 * could be marked dirty and need to be committed
    377		 * before txBegin unblocks
    378		 */
    379		mutex_lock(&JFS_IP(ip)->commit_mutex);
    380
    381		newsize = xtTruncate(tid, ip, length,
    382				     COMMIT_TRUNCATE | COMMIT_PWMAP);
    383		if (newsize < 0) {
    384			txEnd(tid);
    385			mutex_unlock(&JFS_IP(ip)->commit_mutex);
    386			break;
    387		}
    388
    389		ip->i_mtime = ip->i_ctime = current_time(ip);
    390		mark_inode_dirty(ip);
    391
    392		txCommit(tid, 1, &ip, 0);
    393		txEnd(tid);
    394		mutex_unlock(&JFS_IP(ip)->commit_mutex);
    395	} while (newsize > length);	/* Truncate isn't always atomic */
    396}
    397
    398void jfs_truncate(struct inode *ip)
    399{
    400	jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
    401
    402	nobh_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block);
    403
    404	IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
    405	jfs_truncate_nolock(ip, ip->i_size);
    406	IWRITE_UNLOCK(ip);
    407}