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

symlink.c (2875B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  linux/fs/ext4/symlink.c
      4 *
      5 * Only fast symlinks left here - the rest is done by generic code. AV, 1999
      6 *
      7 * Copyright (C) 1992, 1993, 1994, 1995
      8 * Remy Card (card@masi.ibp.fr)
      9 * Laboratoire MASI - Institut Blaise Pascal
     10 * Universite Pierre et Marie Curie (Paris VI)
     11 *
     12 *  from
     13 *
     14 *  linux/fs/minix/symlink.c
     15 *
     16 *  Copyright (C) 1991, 1992  Linus Torvalds
     17 *
     18 *  ext4 symlink handling code
     19 */
     20
     21#include <linux/fs.h>
     22#include <linux/namei.h>
     23#include "ext4.h"
     24#include "xattr.h"
     25
     26static const char *ext4_encrypted_get_link(struct dentry *dentry,
     27					   struct inode *inode,
     28					   struct delayed_call *done)
     29{
     30	struct buffer_head *bh = NULL;
     31	const void *caddr;
     32	unsigned int max_size;
     33	const char *paddr;
     34
     35	if (!dentry)
     36		return ERR_PTR(-ECHILD);
     37
     38	if (ext4_inode_is_fast_symlink(inode)) {
     39		caddr = EXT4_I(inode)->i_data;
     40		max_size = sizeof(EXT4_I(inode)->i_data);
     41	} else {
     42		bh = ext4_bread(NULL, inode, 0, 0);
     43		if (IS_ERR(bh))
     44			return ERR_CAST(bh);
     45		if (!bh) {
     46			EXT4_ERROR_INODE(inode, "bad symlink.");
     47			return ERR_PTR(-EFSCORRUPTED);
     48		}
     49		caddr = bh->b_data;
     50		max_size = inode->i_sb->s_blocksize;
     51	}
     52
     53	paddr = fscrypt_get_symlink(inode, caddr, max_size, done);
     54	brelse(bh);
     55	return paddr;
     56}
     57
     58static int ext4_encrypted_symlink_getattr(struct user_namespace *mnt_userns,
     59					  const struct path *path,
     60					  struct kstat *stat, u32 request_mask,
     61					  unsigned int query_flags)
     62{
     63	ext4_getattr(mnt_userns, path, stat, request_mask, query_flags);
     64
     65	return fscrypt_symlink_getattr(path, stat);
     66}
     67
     68static void ext4_free_link(void *bh)
     69{
     70	brelse(bh);
     71}
     72
     73static const char *ext4_get_link(struct dentry *dentry, struct inode *inode,
     74				 struct delayed_call *callback)
     75{
     76	struct buffer_head *bh;
     77
     78	if (!dentry) {
     79		bh = ext4_getblk(NULL, inode, 0, EXT4_GET_BLOCKS_CACHED_NOWAIT);
     80		if (IS_ERR(bh))
     81			return ERR_CAST(bh);
     82		if (!bh || !ext4_buffer_uptodate(bh))
     83			return ERR_PTR(-ECHILD);
     84	} else {
     85		bh = ext4_bread(NULL, inode, 0, 0);
     86		if (IS_ERR(bh))
     87			return ERR_CAST(bh);
     88		if (!bh) {
     89			EXT4_ERROR_INODE(inode, "bad symlink.");
     90			return ERR_PTR(-EFSCORRUPTED);
     91		}
     92	}
     93
     94	set_delayed_call(callback, ext4_free_link, bh);
     95	nd_terminate_link(bh->b_data, inode->i_size,
     96			  inode->i_sb->s_blocksize - 1);
     97	return bh->b_data;
     98}
     99
    100const struct inode_operations ext4_encrypted_symlink_inode_operations = {
    101	.get_link	= ext4_encrypted_get_link,
    102	.setattr	= ext4_setattr,
    103	.getattr	= ext4_encrypted_symlink_getattr,
    104	.listxattr	= ext4_listxattr,
    105};
    106
    107const struct inode_operations ext4_symlink_inode_operations = {
    108	.get_link	= ext4_get_link,
    109	.setattr	= ext4_setattr,
    110	.getattr	= ext4_getattr,
    111	.listxattr	= ext4_listxattr,
    112};
    113
    114const struct inode_operations ext4_fast_symlink_inode_operations = {
    115	.get_link	= simple_get_link,
    116	.setattr	= ext4_setattr,
    117	.getattr	= ext4_getattr,
    118	.listxattr	= ext4_listxattr,
    119};