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

namei.c (12929B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * NILFS pathname lookup operations.
      4 *
      5 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
      6 *
      7 * Modified for NILFS by Amagai Yoshiji and Ryusuke Konishi.
      8 */
      9/*
     10 *  linux/fs/ext2/namei.c
     11 *
     12 * Copyright (C) 1992, 1993, 1994, 1995
     13 * Remy Card (card@masi.ibp.fr)
     14 * Laboratoire MASI - Institut Blaise Pascal
     15 * Universite Pierre et Marie Curie (Paris VI)
     16 *
     17 *  from
     18 *
     19 *  linux/fs/minix/namei.c
     20 *
     21 *  Copyright (C) 1991, 1992  Linus Torvalds
     22 *
     23 *  Big-endian to little-endian byte-swapping/bitmaps by
     24 *        David S. Miller (davem@caip.rutgers.edu), 1995
     25 */
     26
     27#include <linux/pagemap.h>
     28#include "nilfs.h"
     29#include "export.h"
     30
     31#define NILFS_FID_SIZE_NON_CONNECTABLE \
     32	(offsetof(struct nilfs_fid, parent_gen) / 4)
     33#define NILFS_FID_SIZE_CONNECTABLE	(sizeof(struct nilfs_fid) / 4)
     34
     35static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
     36{
     37	int err = nilfs_add_link(dentry, inode);
     38
     39	if (!err) {
     40		d_instantiate_new(dentry, inode);
     41		return 0;
     42	}
     43	inode_dec_link_count(inode);
     44	unlock_new_inode(inode);
     45	iput(inode);
     46	return err;
     47}
     48
     49/*
     50 * Methods themselves.
     51 */
     52
     53static struct dentry *
     54nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
     55{
     56	struct inode *inode;
     57	ino_t ino;
     58
     59	if (dentry->d_name.len > NILFS_NAME_LEN)
     60		return ERR_PTR(-ENAMETOOLONG);
     61
     62	ino = nilfs_inode_by_name(dir, &dentry->d_name);
     63	inode = ino ? nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino) : NULL;
     64	return d_splice_alias(inode, dentry);
     65}
     66
     67/*
     68 * By the time this is called, we already have created
     69 * the directory cache entry for the new file, but it
     70 * is so far negative - it has no inode.
     71 *
     72 * If the create succeeds, we fill in the inode information
     73 * with d_instantiate().
     74 */
     75static int nilfs_create(struct user_namespace *mnt_userns, struct inode *dir,
     76			struct dentry *dentry, umode_t mode, bool excl)
     77{
     78	struct inode *inode;
     79	struct nilfs_transaction_info ti;
     80	int err;
     81
     82	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
     83	if (err)
     84		return err;
     85	inode = nilfs_new_inode(dir, mode);
     86	err = PTR_ERR(inode);
     87	if (!IS_ERR(inode)) {
     88		inode->i_op = &nilfs_file_inode_operations;
     89		inode->i_fop = &nilfs_file_operations;
     90		inode->i_mapping->a_ops = &nilfs_aops;
     91		nilfs_mark_inode_dirty(inode);
     92		err = nilfs_add_nondir(dentry, inode);
     93	}
     94	if (!err)
     95		err = nilfs_transaction_commit(dir->i_sb);
     96	else
     97		nilfs_transaction_abort(dir->i_sb);
     98
     99	return err;
    100}
    101
    102static int
    103nilfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
    104	    struct dentry *dentry, umode_t mode, dev_t rdev)
    105{
    106	struct inode *inode;
    107	struct nilfs_transaction_info ti;
    108	int err;
    109
    110	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
    111	if (err)
    112		return err;
    113	inode = nilfs_new_inode(dir, mode);
    114	err = PTR_ERR(inode);
    115	if (!IS_ERR(inode)) {
    116		init_special_inode(inode, inode->i_mode, rdev);
    117		nilfs_mark_inode_dirty(inode);
    118		err = nilfs_add_nondir(dentry, inode);
    119	}
    120	if (!err)
    121		err = nilfs_transaction_commit(dir->i_sb);
    122	else
    123		nilfs_transaction_abort(dir->i_sb);
    124
    125	return err;
    126}
    127
    128static int nilfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
    129			 struct dentry *dentry, const char *symname)
    130{
    131	struct nilfs_transaction_info ti;
    132	struct super_block *sb = dir->i_sb;
    133	unsigned int l = strlen(symname) + 1;
    134	struct inode *inode;
    135	int err;
    136
    137	if (l > sb->s_blocksize)
    138		return -ENAMETOOLONG;
    139
    140	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
    141	if (err)
    142		return err;
    143
    144	inode = nilfs_new_inode(dir, S_IFLNK | 0777);
    145	err = PTR_ERR(inode);
    146	if (IS_ERR(inode))
    147		goto out;
    148
    149	/* slow symlink */
    150	inode->i_op = &nilfs_symlink_inode_operations;
    151	inode_nohighmem(inode);
    152	inode->i_mapping->a_ops = &nilfs_aops;
    153	err = page_symlink(inode, symname, l);
    154	if (err)
    155		goto out_fail;
    156
    157	/* mark_inode_dirty(inode); */
    158	/* page_symlink() do this */
    159
    160	err = nilfs_add_nondir(dentry, inode);
    161out:
    162	if (!err)
    163		err = nilfs_transaction_commit(dir->i_sb);
    164	else
    165		nilfs_transaction_abort(dir->i_sb);
    166
    167	return err;
    168
    169out_fail:
    170	drop_nlink(inode);
    171	nilfs_mark_inode_dirty(inode);
    172	unlock_new_inode(inode);
    173	iput(inode);
    174	goto out;
    175}
    176
    177static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
    178		      struct dentry *dentry)
    179{
    180	struct inode *inode = d_inode(old_dentry);
    181	struct nilfs_transaction_info ti;
    182	int err;
    183
    184	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
    185	if (err)
    186		return err;
    187
    188	inode->i_ctime = current_time(inode);
    189	inode_inc_link_count(inode);
    190	ihold(inode);
    191
    192	err = nilfs_add_link(dentry, inode);
    193	if (!err) {
    194		d_instantiate(dentry, inode);
    195		err = nilfs_transaction_commit(dir->i_sb);
    196	} else {
    197		inode_dec_link_count(inode);
    198		iput(inode);
    199		nilfs_transaction_abort(dir->i_sb);
    200	}
    201
    202	return err;
    203}
    204
    205static int nilfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
    206		       struct dentry *dentry, umode_t mode)
    207{
    208	struct inode *inode;
    209	struct nilfs_transaction_info ti;
    210	int err;
    211
    212	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
    213	if (err)
    214		return err;
    215
    216	inc_nlink(dir);
    217
    218	inode = nilfs_new_inode(dir, S_IFDIR | mode);
    219	err = PTR_ERR(inode);
    220	if (IS_ERR(inode))
    221		goto out_dir;
    222
    223	inode->i_op = &nilfs_dir_inode_operations;
    224	inode->i_fop = &nilfs_dir_operations;
    225	inode->i_mapping->a_ops = &nilfs_aops;
    226
    227	inc_nlink(inode);
    228
    229	err = nilfs_make_empty(inode, dir);
    230	if (err)
    231		goto out_fail;
    232
    233	err = nilfs_add_link(dentry, inode);
    234	if (err)
    235		goto out_fail;
    236
    237	nilfs_mark_inode_dirty(inode);
    238	d_instantiate_new(dentry, inode);
    239out:
    240	if (!err)
    241		err = nilfs_transaction_commit(dir->i_sb);
    242	else
    243		nilfs_transaction_abort(dir->i_sb);
    244
    245	return err;
    246
    247out_fail:
    248	drop_nlink(inode);
    249	drop_nlink(inode);
    250	nilfs_mark_inode_dirty(inode);
    251	unlock_new_inode(inode);
    252	iput(inode);
    253out_dir:
    254	drop_nlink(dir);
    255	nilfs_mark_inode_dirty(dir);
    256	goto out;
    257}
    258
    259static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
    260{
    261	struct inode *inode;
    262	struct nilfs_dir_entry *de;
    263	struct page *page;
    264	int err;
    265
    266	err = -ENOENT;
    267	de = nilfs_find_entry(dir, &dentry->d_name, &page);
    268	if (!de)
    269		goto out;
    270
    271	inode = d_inode(dentry);
    272	err = -EIO;
    273	if (le64_to_cpu(de->inode) != inode->i_ino)
    274		goto out;
    275
    276	if (!inode->i_nlink) {
    277		nilfs_warn(inode->i_sb,
    278			   "deleting nonexistent file (ino=%lu), %d",
    279			   inode->i_ino, inode->i_nlink);
    280		set_nlink(inode, 1);
    281	}
    282	err = nilfs_delete_entry(de, page);
    283	if (err)
    284		goto out;
    285
    286	inode->i_ctime = dir->i_ctime;
    287	drop_nlink(inode);
    288	err = 0;
    289out:
    290	return err;
    291}
    292
    293static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
    294{
    295	struct nilfs_transaction_info ti;
    296	int err;
    297
    298	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
    299	if (err)
    300		return err;
    301
    302	err = nilfs_do_unlink(dir, dentry);
    303
    304	if (!err) {
    305		nilfs_mark_inode_dirty(dir);
    306		nilfs_mark_inode_dirty(d_inode(dentry));
    307		err = nilfs_transaction_commit(dir->i_sb);
    308	} else
    309		nilfs_transaction_abort(dir->i_sb);
    310
    311	return err;
    312}
    313
    314static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
    315{
    316	struct inode *inode = d_inode(dentry);
    317	struct nilfs_transaction_info ti;
    318	int err;
    319
    320	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
    321	if (err)
    322		return err;
    323
    324	err = -ENOTEMPTY;
    325	if (nilfs_empty_dir(inode)) {
    326		err = nilfs_do_unlink(dir, dentry);
    327		if (!err) {
    328			inode->i_size = 0;
    329			drop_nlink(inode);
    330			nilfs_mark_inode_dirty(inode);
    331			drop_nlink(dir);
    332			nilfs_mark_inode_dirty(dir);
    333		}
    334	}
    335	if (!err)
    336		err = nilfs_transaction_commit(dir->i_sb);
    337	else
    338		nilfs_transaction_abort(dir->i_sb);
    339
    340	return err;
    341}
    342
    343static int nilfs_rename(struct user_namespace *mnt_userns,
    344			struct inode *old_dir, struct dentry *old_dentry,
    345			struct inode *new_dir, struct dentry *new_dentry,
    346			unsigned int flags)
    347{
    348	struct inode *old_inode = d_inode(old_dentry);
    349	struct inode *new_inode = d_inode(new_dentry);
    350	struct page *dir_page = NULL;
    351	struct nilfs_dir_entry *dir_de = NULL;
    352	struct page *old_page;
    353	struct nilfs_dir_entry *old_de;
    354	struct nilfs_transaction_info ti;
    355	int err;
    356
    357	if (flags & ~RENAME_NOREPLACE)
    358		return -EINVAL;
    359
    360	err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
    361	if (unlikely(err))
    362		return err;
    363
    364	err = -ENOENT;
    365	old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
    366	if (!old_de)
    367		goto out;
    368
    369	if (S_ISDIR(old_inode->i_mode)) {
    370		err = -EIO;
    371		dir_de = nilfs_dotdot(old_inode, &dir_page);
    372		if (!dir_de)
    373			goto out_old;
    374	}
    375
    376	if (new_inode) {
    377		struct page *new_page;
    378		struct nilfs_dir_entry *new_de;
    379
    380		err = -ENOTEMPTY;
    381		if (dir_de && !nilfs_empty_dir(new_inode))
    382			goto out_dir;
    383
    384		err = -ENOENT;
    385		new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page);
    386		if (!new_de)
    387			goto out_dir;
    388		nilfs_set_link(new_dir, new_de, new_page, old_inode);
    389		nilfs_mark_inode_dirty(new_dir);
    390		new_inode->i_ctime = current_time(new_inode);
    391		if (dir_de)
    392			drop_nlink(new_inode);
    393		drop_nlink(new_inode);
    394		nilfs_mark_inode_dirty(new_inode);
    395	} else {
    396		err = nilfs_add_link(new_dentry, old_inode);
    397		if (err)
    398			goto out_dir;
    399		if (dir_de) {
    400			inc_nlink(new_dir);
    401			nilfs_mark_inode_dirty(new_dir);
    402		}
    403	}
    404
    405	/*
    406	 * Like most other Unix systems, set the ctime for inodes on a
    407	 * rename.
    408	 */
    409	old_inode->i_ctime = current_time(old_inode);
    410
    411	nilfs_delete_entry(old_de, old_page);
    412
    413	if (dir_de) {
    414		nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
    415		drop_nlink(old_dir);
    416	}
    417	nilfs_mark_inode_dirty(old_dir);
    418	nilfs_mark_inode_dirty(old_inode);
    419
    420	err = nilfs_transaction_commit(old_dir->i_sb);
    421	return err;
    422
    423out_dir:
    424	if (dir_de) {
    425		kunmap(dir_page);
    426		put_page(dir_page);
    427	}
    428out_old:
    429	kunmap(old_page);
    430	put_page(old_page);
    431out:
    432	nilfs_transaction_abort(old_dir->i_sb);
    433	return err;
    434}
    435
    436/*
    437 * Export operations
    438 */
    439static struct dentry *nilfs_get_parent(struct dentry *child)
    440{
    441	unsigned long ino;
    442	struct inode *inode;
    443	struct nilfs_root *root;
    444
    445	ino = nilfs_inode_by_name(d_inode(child), &dotdot_name);
    446	if (!ino)
    447		return ERR_PTR(-ENOENT);
    448
    449	root = NILFS_I(d_inode(child))->i_root;
    450
    451	inode = nilfs_iget(child->d_sb, root, ino);
    452	if (IS_ERR(inode))
    453		return ERR_CAST(inode);
    454
    455	return d_obtain_alias(inode);
    456}
    457
    458static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
    459				       u64 ino, u32 gen)
    460{
    461	struct nilfs_root *root;
    462	struct inode *inode;
    463
    464	if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
    465		return ERR_PTR(-ESTALE);
    466
    467	root = nilfs_lookup_root(sb->s_fs_info, cno);
    468	if (!root)
    469		return ERR_PTR(-ESTALE);
    470
    471	inode = nilfs_iget(sb, root, ino);
    472	nilfs_put_root(root);
    473
    474	if (IS_ERR(inode))
    475		return ERR_CAST(inode);
    476	if (gen && inode->i_generation != gen) {
    477		iput(inode);
    478		return ERR_PTR(-ESTALE);
    479	}
    480	return d_obtain_alias(inode);
    481}
    482
    483static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
    484					 int fh_len, int fh_type)
    485{
    486	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
    487
    488	if (fh_len < NILFS_FID_SIZE_NON_CONNECTABLE ||
    489	    (fh_type != FILEID_NILFS_WITH_PARENT &&
    490	     fh_type != FILEID_NILFS_WITHOUT_PARENT))
    491		return NULL;
    492
    493	return nilfs_get_dentry(sb, fid->cno, fid->ino, fid->gen);
    494}
    495
    496static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
    497					 int fh_len, int fh_type)
    498{
    499	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
    500
    501	if (fh_len < NILFS_FID_SIZE_CONNECTABLE ||
    502	    fh_type != FILEID_NILFS_WITH_PARENT)
    503		return NULL;
    504
    505	return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
    506}
    507
    508static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
    509			   struct inode *parent)
    510{
    511	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
    512	struct nilfs_root *root = NILFS_I(inode)->i_root;
    513	int type;
    514
    515	if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) {
    516		*lenp = NILFS_FID_SIZE_CONNECTABLE;
    517		return FILEID_INVALID;
    518	}
    519	if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) {
    520		*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
    521		return FILEID_INVALID;
    522	}
    523
    524	fid->cno = root->cno;
    525	fid->ino = inode->i_ino;
    526	fid->gen = inode->i_generation;
    527
    528	if (parent) {
    529		fid->parent_ino = parent->i_ino;
    530		fid->parent_gen = parent->i_generation;
    531		type = FILEID_NILFS_WITH_PARENT;
    532		*lenp = NILFS_FID_SIZE_CONNECTABLE;
    533	} else {
    534		type = FILEID_NILFS_WITHOUT_PARENT;
    535		*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
    536	}
    537
    538	return type;
    539}
    540
    541const struct inode_operations nilfs_dir_inode_operations = {
    542	.create		= nilfs_create,
    543	.lookup		= nilfs_lookup,
    544	.link		= nilfs_link,
    545	.unlink		= nilfs_unlink,
    546	.symlink	= nilfs_symlink,
    547	.mkdir		= nilfs_mkdir,
    548	.rmdir		= nilfs_rmdir,
    549	.mknod		= nilfs_mknod,
    550	.rename		= nilfs_rename,
    551	.setattr	= nilfs_setattr,
    552	.permission	= nilfs_permission,
    553	.fiemap		= nilfs_fiemap,
    554	.fileattr_get	= nilfs_fileattr_get,
    555	.fileattr_set	= nilfs_fileattr_set,
    556};
    557
    558const struct inode_operations nilfs_special_inode_operations = {
    559	.setattr	= nilfs_setattr,
    560	.permission	= nilfs_permission,
    561};
    562
    563const struct inode_operations nilfs_symlink_inode_operations = {
    564	.get_link	= page_get_link,
    565	.permission     = nilfs_permission,
    566};
    567
    568const struct export_operations nilfs_export_ops = {
    569	.encode_fh = nilfs_encode_fh,
    570	.fh_to_dentry = nilfs_fh_to_dentry,
    571	.fh_to_parent = nilfs_fh_to_parent,
    572	.get_parent = nilfs_get_parent,
    573};