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 (16347B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  linux/fs/hpfs/namei.c
      4 *
      5 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
      6 *
      7 *  adding & removing files & directories
      8 */
      9#include <linux/sched.h>
     10#include "hpfs_fn.h"
     11
     12static void hpfs_update_directory_times(struct inode *dir)
     13{
     14	time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
     15	if (t == dir->i_mtime.tv_sec &&
     16	    t == dir->i_ctime.tv_sec)
     17		return;
     18	dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
     19	dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
     20	hpfs_write_inode_nolock(dir);
     21}
     22
     23static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
     24		      struct dentry *dentry, umode_t mode)
     25{
     26	const unsigned char *name = dentry->d_name.name;
     27	unsigned len = dentry->d_name.len;
     28	struct quad_buffer_head qbh0;
     29	struct buffer_head *bh;
     30	struct hpfs_dirent *de;
     31	struct fnode *fnode;
     32	struct dnode *dnode;
     33	struct inode *result;
     34	fnode_secno fno;
     35	dnode_secno dno;
     36	int r;
     37	struct hpfs_dirent dee;
     38	int err;
     39	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
     40	hpfs_lock(dir->i_sb);
     41	err = -ENOSPC;
     42	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
     43	if (!fnode)
     44		goto bail;
     45	dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
     46	if (!dnode)
     47		goto bail1;
     48	memset(&dee, 0, sizeof dee);
     49	dee.directory = 1;
     50	if (!(mode & 0222)) dee.read_only = 1;
     51	/*dee.archive = 0;*/
     52	dee.hidden = name[0] == '.';
     53	dee.fnode = cpu_to_le32(fno);
     54	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
     55	result = new_inode(dir->i_sb);
     56	if (!result)
     57		goto bail2;
     58	hpfs_init_inode(result);
     59	result->i_ino = fno;
     60	hpfs_i(result)->i_parent_dir = dir->i_ino;
     61	hpfs_i(result)->i_dno = dno;
     62	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
     63	result->i_ctime.tv_nsec = 0; 
     64	result->i_mtime.tv_nsec = 0; 
     65	result->i_atime.tv_nsec = 0; 
     66	hpfs_i(result)->i_ea_size = 0;
     67	result->i_mode |= S_IFDIR;
     68	result->i_op = &hpfs_dir_iops;
     69	result->i_fop = &hpfs_dir_ops;
     70	result->i_blocks = 4;
     71	result->i_size = 2048;
     72	set_nlink(result, 2);
     73	if (dee.read_only)
     74		result->i_mode &= ~0222;
     75
     76	r = hpfs_add_dirent(dir, name, len, &dee);
     77	if (r == 1)
     78		goto bail3;
     79	if (r == -1) {
     80		err = -EEXIST;
     81		goto bail3;
     82	}
     83	fnode->len = len;
     84	memcpy(fnode->name, name, len > 15 ? 15 : len);
     85	fnode->up = cpu_to_le32(dir->i_ino);
     86	fnode->flags |= FNODE_dir;
     87	fnode->btree.n_free_nodes = 7;
     88	fnode->btree.n_used_nodes = 1;
     89	fnode->btree.first_free = cpu_to_le16(0x14);
     90	fnode->u.external[0].disk_secno = cpu_to_le32(dno);
     91	fnode->u.external[0].file_secno = cpu_to_le32(-1);
     92	dnode->root_dnode = 1;
     93	dnode->up = cpu_to_le32(fno);
     94	de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
     95	de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
     96	if (!(mode & 0222)) de->read_only = 1;
     97	de->first = de->directory = 1;
     98	/*de->hidden = de->system = 0;*/
     99	de->fnode = cpu_to_le32(fno);
    100	mark_buffer_dirty(bh);
    101	brelse(bh);
    102	hpfs_mark_4buffers_dirty(&qbh0);
    103	hpfs_brelse4(&qbh0);
    104	inc_nlink(dir);
    105	insert_inode_hash(result);
    106
    107	if (!uid_eq(result->i_uid, current_fsuid()) ||
    108	    !gid_eq(result->i_gid, current_fsgid()) ||
    109	    result->i_mode != (mode | S_IFDIR)) {
    110		result->i_uid = current_fsuid();
    111		result->i_gid = current_fsgid();
    112		result->i_mode = mode | S_IFDIR;
    113		hpfs_write_inode_nolock(result);
    114	}
    115	hpfs_update_directory_times(dir);
    116	d_instantiate(dentry, result);
    117	hpfs_unlock(dir->i_sb);
    118	return 0;
    119bail3:
    120	iput(result);
    121bail2:
    122	hpfs_brelse4(&qbh0);
    123	hpfs_free_dnode(dir->i_sb, dno);
    124bail1:
    125	brelse(bh);
    126	hpfs_free_sectors(dir->i_sb, fno, 1);
    127bail:
    128	hpfs_unlock(dir->i_sb);
    129	return err;
    130}
    131
    132static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir,
    133		       struct dentry *dentry, umode_t mode, bool excl)
    134{
    135	const unsigned char *name = dentry->d_name.name;
    136	unsigned len = dentry->d_name.len;
    137	struct inode *result = NULL;
    138	struct buffer_head *bh;
    139	struct fnode *fnode;
    140	fnode_secno fno;
    141	int r;
    142	struct hpfs_dirent dee;
    143	int err;
    144	if ((err = hpfs_chk_name(name, &len)))
    145		return err==-ENOENT ? -EINVAL : err;
    146	hpfs_lock(dir->i_sb);
    147	err = -ENOSPC;
    148	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
    149	if (!fnode)
    150		goto bail;
    151	memset(&dee, 0, sizeof dee);
    152	if (!(mode & 0222)) dee.read_only = 1;
    153	dee.archive = 1;
    154	dee.hidden = name[0] == '.';
    155	dee.fnode = cpu_to_le32(fno);
    156	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
    157
    158	result = new_inode(dir->i_sb);
    159	if (!result)
    160		goto bail1;
    161	
    162	hpfs_init_inode(result);
    163	result->i_ino = fno;
    164	result->i_mode |= S_IFREG;
    165	result->i_mode &= ~0111;
    166	result->i_op = &hpfs_file_iops;
    167	result->i_fop = &hpfs_file_ops;
    168	set_nlink(result, 1);
    169	hpfs_i(result)->i_parent_dir = dir->i_ino;
    170	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
    171	result->i_ctime.tv_nsec = 0;
    172	result->i_mtime.tv_nsec = 0;
    173	result->i_atime.tv_nsec = 0;
    174	hpfs_i(result)->i_ea_size = 0;
    175	if (dee.read_only)
    176		result->i_mode &= ~0222;
    177	result->i_blocks = 1;
    178	result->i_size = 0;
    179	result->i_data.a_ops = &hpfs_aops;
    180	hpfs_i(result)->mmu_private = 0;
    181
    182	r = hpfs_add_dirent(dir, name, len, &dee);
    183	if (r == 1)
    184		goto bail2;
    185	if (r == -1) {
    186		err = -EEXIST;
    187		goto bail2;
    188	}
    189	fnode->len = len;
    190	memcpy(fnode->name, name, len > 15 ? 15 : len);
    191	fnode->up = cpu_to_le32(dir->i_ino);
    192	mark_buffer_dirty(bh);
    193	brelse(bh);
    194
    195	insert_inode_hash(result);
    196
    197	if (!uid_eq(result->i_uid, current_fsuid()) ||
    198	    !gid_eq(result->i_gid, current_fsgid()) ||
    199	    result->i_mode != (mode | S_IFREG)) {
    200		result->i_uid = current_fsuid();
    201		result->i_gid = current_fsgid();
    202		result->i_mode = mode | S_IFREG;
    203		hpfs_write_inode_nolock(result);
    204	}
    205	hpfs_update_directory_times(dir);
    206	d_instantiate(dentry, result);
    207	hpfs_unlock(dir->i_sb);
    208	return 0;
    209
    210bail2:
    211	iput(result);
    212bail1:
    213	brelse(bh);
    214	hpfs_free_sectors(dir->i_sb, fno, 1);
    215bail:
    216	hpfs_unlock(dir->i_sb);
    217	return err;
    218}
    219
    220static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
    221		      struct dentry *dentry, umode_t mode, dev_t rdev)
    222{
    223	const unsigned char *name = dentry->d_name.name;
    224	unsigned len = dentry->d_name.len;
    225	struct buffer_head *bh;
    226	struct fnode *fnode;
    227	fnode_secno fno;
    228	int r;
    229	struct hpfs_dirent dee;
    230	struct inode *result = NULL;
    231	int err;
    232	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
    233	if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
    234	hpfs_lock(dir->i_sb);
    235	err = -ENOSPC;
    236	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
    237	if (!fnode)
    238		goto bail;
    239	memset(&dee, 0, sizeof dee);
    240	if (!(mode & 0222)) dee.read_only = 1;
    241	dee.archive = 1;
    242	dee.hidden = name[0] == '.';
    243	dee.fnode = cpu_to_le32(fno);
    244	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
    245
    246	result = new_inode(dir->i_sb);
    247	if (!result)
    248		goto bail1;
    249
    250	hpfs_init_inode(result);
    251	result->i_ino = fno;
    252	hpfs_i(result)->i_parent_dir = dir->i_ino;
    253	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
    254	result->i_ctime.tv_nsec = 0;
    255	result->i_mtime.tv_nsec = 0;
    256	result->i_atime.tv_nsec = 0;
    257	hpfs_i(result)->i_ea_size = 0;
    258	result->i_uid = current_fsuid();
    259	result->i_gid = current_fsgid();
    260	set_nlink(result, 1);
    261	result->i_size = 0;
    262	result->i_blocks = 1;
    263	init_special_inode(result, mode, rdev);
    264
    265	r = hpfs_add_dirent(dir, name, len, &dee);
    266	if (r == 1)
    267		goto bail2;
    268	if (r == -1) {
    269		err = -EEXIST;
    270		goto bail2;
    271	}
    272	fnode->len = len;
    273	memcpy(fnode->name, name, len > 15 ? 15 : len);
    274	fnode->up = cpu_to_le32(dir->i_ino);
    275	mark_buffer_dirty(bh);
    276
    277	insert_inode_hash(result);
    278
    279	hpfs_write_inode_nolock(result);
    280	hpfs_update_directory_times(dir);
    281	d_instantiate(dentry, result);
    282	brelse(bh);
    283	hpfs_unlock(dir->i_sb);
    284	return 0;
    285bail2:
    286	iput(result);
    287bail1:
    288	brelse(bh);
    289	hpfs_free_sectors(dir->i_sb, fno, 1);
    290bail:
    291	hpfs_unlock(dir->i_sb);
    292	return err;
    293}
    294
    295static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
    296			struct dentry *dentry, const char *symlink)
    297{
    298	const unsigned char *name = dentry->d_name.name;
    299	unsigned len = dentry->d_name.len;
    300	struct buffer_head *bh;
    301	struct fnode *fnode;
    302	fnode_secno fno;
    303	int r;
    304	struct hpfs_dirent dee;
    305	struct inode *result;
    306	int err;
    307	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
    308	hpfs_lock(dir->i_sb);
    309	if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
    310		hpfs_unlock(dir->i_sb);
    311		return -EPERM;
    312	}
    313	err = -ENOSPC;
    314	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
    315	if (!fnode)
    316		goto bail;
    317	memset(&dee, 0, sizeof dee);
    318	dee.archive = 1;
    319	dee.hidden = name[0] == '.';
    320	dee.fnode = cpu_to_le32(fno);
    321	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
    322
    323	result = new_inode(dir->i_sb);
    324	if (!result)
    325		goto bail1;
    326	result->i_ino = fno;
    327	hpfs_init_inode(result);
    328	hpfs_i(result)->i_parent_dir = dir->i_ino;
    329	result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date));
    330	result->i_ctime.tv_nsec = 0;
    331	result->i_mtime.tv_nsec = 0;
    332	result->i_atime.tv_nsec = 0;
    333	hpfs_i(result)->i_ea_size = 0;
    334	result->i_mode = S_IFLNK | 0777;
    335	result->i_uid = current_fsuid();
    336	result->i_gid = current_fsgid();
    337	result->i_blocks = 1;
    338	set_nlink(result, 1);
    339	result->i_size = strlen(symlink);
    340	inode_nohighmem(result);
    341	result->i_op = &page_symlink_inode_operations;
    342	result->i_data.a_ops = &hpfs_symlink_aops;
    343
    344	r = hpfs_add_dirent(dir, name, len, &dee);
    345	if (r == 1)
    346		goto bail2;
    347	if (r == -1) {
    348		err = -EEXIST;
    349		goto bail2;
    350	}
    351	fnode->len = len;
    352	memcpy(fnode->name, name, len > 15 ? 15 : len);
    353	fnode->up = cpu_to_le32(dir->i_ino);
    354	hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
    355	mark_buffer_dirty(bh);
    356	brelse(bh);
    357
    358	insert_inode_hash(result);
    359
    360	hpfs_write_inode_nolock(result);
    361	hpfs_update_directory_times(dir);
    362	d_instantiate(dentry, result);
    363	hpfs_unlock(dir->i_sb);
    364	return 0;
    365bail2:
    366	iput(result);
    367bail1:
    368	brelse(bh);
    369	hpfs_free_sectors(dir->i_sb, fno, 1);
    370bail:
    371	hpfs_unlock(dir->i_sb);
    372	return err;
    373}
    374
    375static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
    376{
    377	const unsigned char *name = dentry->d_name.name;
    378	unsigned len = dentry->d_name.len;
    379	struct quad_buffer_head qbh;
    380	struct hpfs_dirent *de;
    381	struct inode *inode = d_inode(dentry);
    382	dnode_secno dno;
    383	int r;
    384	int err;
    385
    386	hpfs_lock(dir->i_sb);
    387	hpfs_adjust_length(name, &len);
    388
    389	err = -ENOENT;
    390	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
    391	if (!de)
    392		goto out;
    393
    394	err = -EPERM;
    395	if (de->first)
    396		goto out1;
    397
    398	err = -EISDIR;
    399	if (de->directory)
    400		goto out1;
    401
    402	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
    403	switch (r) {
    404	case 1:
    405		hpfs_error(dir->i_sb, "there was error when removing dirent");
    406		err = -EFSERROR;
    407		break;
    408	case 2:		/* no space for deleting */
    409		err = -ENOSPC;
    410		break;
    411	default:
    412		drop_nlink(inode);
    413		err = 0;
    414	}
    415	goto out;
    416
    417out1:
    418	hpfs_brelse4(&qbh);
    419out:
    420	if (!err)
    421		hpfs_update_directory_times(dir);
    422	hpfs_unlock(dir->i_sb);
    423	return err;
    424}
    425
    426static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
    427{
    428	const unsigned char *name = dentry->d_name.name;
    429	unsigned len = dentry->d_name.len;
    430	struct quad_buffer_head qbh;
    431	struct hpfs_dirent *de;
    432	struct inode *inode = d_inode(dentry);
    433	dnode_secno dno;
    434	int n_items = 0;
    435	int err;
    436	int r;
    437
    438	hpfs_adjust_length(name, &len);
    439	hpfs_lock(dir->i_sb);
    440	err = -ENOENT;
    441	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
    442	if (!de)
    443		goto out;
    444
    445	err = -EPERM;
    446	if (de->first)
    447		goto out1;
    448
    449	err = -ENOTDIR;
    450	if (!de->directory)
    451		goto out1;
    452
    453	hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
    454	err = -ENOTEMPTY;
    455	if (n_items)
    456		goto out1;
    457
    458	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
    459	switch (r) {
    460	case 1:
    461		hpfs_error(dir->i_sb, "there was error when removing dirent");
    462		err = -EFSERROR;
    463		break;
    464	case 2:
    465		err = -ENOSPC;
    466		break;
    467	default:
    468		drop_nlink(dir);
    469		clear_nlink(inode);
    470		err = 0;
    471	}
    472	goto out;
    473out1:
    474	hpfs_brelse4(&qbh);
    475out:
    476	if (!err)
    477		hpfs_update_directory_times(dir);
    478	hpfs_unlock(dir->i_sb);
    479	return err;
    480}
    481
    482static int hpfs_symlink_read_folio(struct file *file, struct folio *folio)
    483{
    484	struct page *page = &folio->page;
    485	char *link = page_address(page);
    486	struct inode *i = page->mapping->host;
    487	struct fnode *fnode;
    488	struct buffer_head *bh;
    489	int err;
    490
    491	err = -EIO;
    492	hpfs_lock(i->i_sb);
    493	if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
    494		goto fail;
    495	err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
    496	brelse(bh);
    497	if (err)
    498		goto fail;
    499	hpfs_unlock(i->i_sb);
    500	SetPageUptodate(page);
    501	unlock_page(page);
    502	return 0;
    503
    504fail:
    505	hpfs_unlock(i->i_sb);
    506	SetPageError(page);
    507	unlock_page(page);
    508	return err;
    509}
    510
    511const struct address_space_operations hpfs_symlink_aops = {
    512	.read_folio	= hpfs_symlink_read_folio
    513};
    514
    515static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
    516		       struct dentry *old_dentry, struct inode *new_dir,
    517		       struct dentry *new_dentry, unsigned int flags)
    518{
    519	const unsigned char *old_name = old_dentry->d_name.name;
    520	unsigned old_len = old_dentry->d_name.len;
    521	const unsigned char *new_name = new_dentry->d_name.name;
    522	unsigned new_len = new_dentry->d_name.len;
    523	struct inode *i = d_inode(old_dentry);
    524	struct inode *new_inode = d_inode(new_dentry);
    525	struct quad_buffer_head qbh, qbh1;
    526	struct hpfs_dirent *dep, *nde;
    527	struct hpfs_dirent de;
    528	dnode_secno dno;
    529	int r;
    530	struct buffer_head *bh;
    531	struct fnode *fnode;
    532	int err;
    533
    534	if (flags & ~RENAME_NOREPLACE)
    535		return -EINVAL;
    536
    537	if ((err = hpfs_chk_name(new_name, &new_len))) return err;
    538	err = 0;
    539	hpfs_adjust_length(old_name, &old_len);
    540
    541	hpfs_lock(i->i_sb);
    542	/* order doesn't matter, due to VFS exclusion */
    543	
    544	/* Erm? Moving over the empty non-busy directory is perfectly legal */
    545	if (new_inode && S_ISDIR(new_inode->i_mode)) {
    546		err = -EINVAL;
    547		goto end1;
    548	}
    549
    550	if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
    551		hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
    552		err = -ENOENT;
    553		goto end1;
    554	}
    555	copy_de(&de, dep);
    556	de.hidden = new_name[0] == '.';
    557
    558	if (new_inode) {
    559		int r;
    560		if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
    561			if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
    562				clear_nlink(new_inode);
    563				copy_de(nde, &de);
    564				memcpy(nde->name, new_name, new_len);
    565				hpfs_mark_4buffers_dirty(&qbh1);
    566				hpfs_brelse4(&qbh1);
    567				goto end;
    568			}
    569			hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
    570			err = -EFSERROR;
    571			goto end1;
    572		}
    573		err = -ENOSPC;
    574		goto end1;
    575	}
    576
    577	if (new_dir == old_dir) hpfs_brelse4(&qbh);
    578
    579	if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
    580		if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
    581		err = r == 1 ? -ENOSPC : -EFSERROR;
    582		if (new_dir != old_dir) hpfs_brelse4(&qbh);
    583		goto end1;
    584	}
    585	
    586	if (new_dir == old_dir)
    587		if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
    588			hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
    589			err = -ENOENT;
    590			goto end1;
    591		}
    592
    593	if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
    594		hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
    595		err = r == 2 ? -ENOSPC : -EFSERROR;
    596		goto end1;
    597	}
    598
    599end:
    600	hpfs_i(i)->i_parent_dir = new_dir->i_ino;
    601	if (S_ISDIR(i->i_mode)) {
    602		inc_nlink(new_dir);
    603		drop_nlink(old_dir);
    604	}
    605	if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
    606		fnode->up = cpu_to_le32(new_dir->i_ino);
    607		fnode->len = new_len;
    608		memcpy(fnode->name, new_name, new_len>15?15:new_len);
    609		if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
    610		mark_buffer_dirty(bh);
    611		brelse(bh);
    612	}
    613end1:
    614	if (!err) {
    615		hpfs_update_directory_times(old_dir);
    616		hpfs_update_directory_times(new_dir);
    617	}
    618	hpfs_unlock(i->i_sb);
    619	return err;
    620}
    621
    622const struct inode_operations hpfs_dir_iops =
    623{
    624	.create		= hpfs_create,
    625	.lookup		= hpfs_lookup,
    626	.unlink		= hpfs_unlink,
    627	.symlink	= hpfs_symlink,
    628	.mkdir		= hpfs_mkdir,
    629	.rmdir		= hpfs_rmdir,
    630	.mknod		= hpfs_mknod,
    631	.rename		= hpfs_rename,
    632	.setattr	= hpfs_setattr,
    633};