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

stack.c (2597B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <linux/export.h>
      3#include <linux/fs.h>
      4#include <linux/fs_stack.h>
      5
      6/* does _NOT_ require i_mutex to be held.
      7 *
      8 * This function cannot be inlined since i_size_{read,write} is rather
      9 * heavy-weight on 32-bit systems
     10 */
     11void fsstack_copy_inode_size(struct inode *dst, struct inode *src)
     12{
     13	loff_t i_size;
     14	blkcnt_t i_blocks;
     15
     16	/*
     17	 * i_size_read() includes its own seqlocking and protection from
     18	 * preemption (see include/linux/fs.h): we need nothing extra for
     19	 * that here, and prefer to avoid nesting locks than attempt to keep
     20	 * i_size and i_blocks in sync together.
     21	 */
     22	i_size = i_size_read(src);
     23
     24	/*
     25	 * But on 32-bit, we ought to make an effort to keep the two halves of
     26	 * i_blocks in sync despite SMP or PREEMPTION - though stat's
     27	 * generic_fillattr() doesn't bother, and we won't be applying quotas
     28	 * (where i_blocks does become important) at the upper level.
     29	 *
     30	 * We don't actually know what locking is used at the lower level;
     31	 * but if it's a filesystem that supports quotas, it will be using
     32	 * i_lock as in inode_add_bytes().
     33	 */
     34	if (sizeof(i_blocks) > sizeof(long))
     35		spin_lock(&src->i_lock);
     36	i_blocks = src->i_blocks;
     37	if (sizeof(i_blocks) > sizeof(long))
     38		spin_unlock(&src->i_lock);
     39
     40	/*
     41	 * If CONFIG_SMP or CONFIG_PREEMPTION on 32-bit, it's vital for
     42	 * fsstack_copy_inode_size() to hold some lock around
     43	 * i_size_write(), otherwise i_size_read() may spin forever (see
     44	 * include/linux/fs.h).  We don't necessarily hold i_mutex when this
     45	 * is called, so take i_lock for that case.
     46	 *
     47	 * And if on 32-bit, continue our effort to keep the two halves of
     48	 * i_blocks in sync despite SMP or PREEMPTION: use i_lock for that case
     49	 * too, and do both at once by combining the tests.
     50	 *
     51	 * There is none of this locking overhead in the 64-bit case.
     52	 */
     53	if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
     54		spin_lock(&dst->i_lock);
     55	i_size_write(dst, i_size);
     56	dst->i_blocks = i_blocks;
     57	if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
     58		spin_unlock(&dst->i_lock);
     59}
     60EXPORT_SYMBOL_GPL(fsstack_copy_inode_size);
     61
     62/* copy all attributes */
     63void fsstack_copy_attr_all(struct inode *dest, const struct inode *src)
     64{
     65	dest->i_mode = src->i_mode;
     66	dest->i_uid = src->i_uid;
     67	dest->i_gid = src->i_gid;
     68	dest->i_rdev = src->i_rdev;
     69	dest->i_atime = src->i_atime;
     70	dest->i_mtime = src->i_mtime;
     71	dest->i_ctime = src->i_ctime;
     72	dest->i_blkbits = src->i_blkbits;
     73	dest->i_flags = src->i_flags;
     74	set_nlink(dest, src->i_nlink);
     75}
     76EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);