162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  linux/fs/sysv/dir.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  minix/dir.c
662306a36Sopenharmony_ci *  Copyright (C) 1991, 1992  Linus Torvalds
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *  coh/dir.c
962306a36Sopenharmony_ci *  Copyright (C) 1993  Pascal Haible, Bruno Haible
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci *  sysv/dir.c
1262306a36Sopenharmony_ci *  Copyright (C) 1993  Bruno Haible
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci *  SystemV/Coherent directory handling functions
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <linux/pagemap.h>
1862306a36Sopenharmony_ci#include <linux/highmem.h>
1962306a36Sopenharmony_ci#include <linux/swap.h>
2062306a36Sopenharmony_ci#include "sysv.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic int sysv_readdir(struct file *, struct dir_context *);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciconst struct file_operations sysv_dir_operations = {
2562306a36Sopenharmony_ci	.llseek		= generic_file_llseek,
2662306a36Sopenharmony_ci	.read		= generic_read_dir,
2762306a36Sopenharmony_ci	.iterate_shared	= sysv_readdir,
2862306a36Sopenharmony_ci	.fsync		= generic_file_fsync,
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic void dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
3262306a36Sopenharmony_ci{
3362306a36Sopenharmony_ci	struct address_space *mapping = page->mapping;
3462306a36Sopenharmony_ci	struct inode *dir = mapping->host;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	block_write_end(NULL, mapping, pos, len, len, page, NULL);
3762306a36Sopenharmony_ci	if (pos+len > dir->i_size) {
3862306a36Sopenharmony_ci		i_size_write(dir, pos+len);
3962306a36Sopenharmony_ci		mark_inode_dirty(dir);
4062306a36Sopenharmony_ci	}
4162306a36Sopenharmony_ci	unlock_page(page);
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic int sysv_handle_dirsync(struct inode *dir)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	int err;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	err = filemap_write_and_wait(dir->i_mapping);
4962306a36Sopenharmony_ci	if (!err)
5062306a36Sopenharmony_ci		err = sync_inode_metadata(dir, 1);
5162306a36Sopenharmony_ci	return err;
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/*
5562306a36Sopenharmony_ci * Calls to dir_get_page()/unmap_and_put_page() must be nested according to the
5662306a36Sopenharmony_ci * rules documented in mm/highmem.rst.
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci * NOTE: sysv_find_entry() and sysv_dotdot() act as calls to dir_get_page()
5962306a36Sopenharmony_ci * and must be treated accordingly for nesting purposes.
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_cistatic void *dir_get_page(struct inode *dir, unsigned long n, struct page **p)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	struct address_space *mapping = dir->i_mapping;
6462306a36Sopenharmony_ci	struct page *page = read_mapping_page(mapping, n, NULL);
6562306a36Sopenharmony_ci	if (IS_ERR(page))
6662306a36Sopenharmony_ci		return ERR_CAST(page);
6762306a36Sopenharmony_ci	*p = page;
6862306a36Sopenharmony_ci	return kmap_local_page(page);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic int sysv_readdir(struct file *file, struct dir_context *ctx)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	unsigned long pos = ctx->pos;
7462306a36Sopenharmony_ci	struct inode *inode = file_inode(file);
7562306a36Sopenharmony_ci	struct super_block *sb = inode->i_sb;
7662306a36Sopenharmony_ci	unsigned long npages = dir_pages(inode);
7762306a36Sopenharmony_ci	unsigned offset;
7862306a36Sopenharmony_ci	unsigned long n;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	ctx->pos = pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
8162306a36Sopenharmony_ci	if (pos >= inode->i_size)
8262306a36Sopenharmony_ci		return 0;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	offset = pos & ~PAGE_MASK;
8562306a36Sopenharmony_ci	n = pos >> PAGE_SHIFT;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	for ( ; n < npages; n++, offset = 0) {
8862306a36Sopenharmony_ci		char *kaddr, *limit;
8962306a36Sopenharmony_ci		struct sysv_dir_entry *de;
9062306a36Sopenharmony_ci		struct page *page;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci		kaddr = dir_get_page(inode, n, &page);
9362306a36Sopenharmony_ci		if (IS_ERR(kaddr))
9462306a36Sopenharmony_ci			continue;
9562306a36Sopenharmony_ci		de = (struct sysv_dir_entry *)(kaddr+offset);
9662306a36Sopenharmony_ci		limit = kaddr + PAGE_SIZE - SYSV_DIRSIZE;
9762306a36Sopenharmony_ci		for ( ;(char*)de <= limit; de++, ctx->pos += sizeof(*de)) {
9862306a36Sopenharmony_ci			char *name = de->name;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci			if (!de->inode)
10162306a36Sopenharmony_ci				continue;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci			if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN),
10462306a36Sopenharmony_ci					fs16_to_cpu(SYSV_SB(sb), de->inode),
10562306a36Sopenharmony_ci					DT_UNKNOWN)) {
10662306a36Sopenharmony_ci				unmap_and_put_page(page, kaddr);
10762306a36Sopenharmony_ci				return 0;
10862306a36Sopenharmony_ci			}
10962306a36Sopenharmony_ci		}
11062306a36Sopenharmony_ci		unmap_and_put_page(page, kaddr);
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci	return 0;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/* compare strings: name[0..len-1] (not zero-terminated) and
11662306a36Sopenharmony_ci * buffer[0..] (filled with zeroes up to buffer[0..maxlen-1])
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_cistatic inline int namecompare(int len, int maxlen,
11962306a36Sopenharmony_ci	const char * name, const char * buffer)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	if (len < maxlen && buffer[len])
12262306a36Sopenharmony_ci		return 0;
12362306a36Sopenharmony_ci	return !memcmp(name, buffer, len);
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/*
12762306a36Sopenharmony_ci *	sysv_find_entry()
12862306a36Sopenharmony_ci *
12962306a36Sopenharmony_ci * finds an entry in the specified directory with the wanted name. It
13062306a36Sopenharmony_ci * returns the cache buffer in which the entry was found, and the entry
13162306a36Sopenharmony_ci * itself (as a parameter - res_dir). It does NOT read the inode of the
13262306a36Sopenharmony_ci * entry - you'll have to do that yourself if you want to.
13362306a36Sopenharmony_ci *
13462306a36Sopenharmony_ci * On Success unmap_and_put_page() should be called on *res_page.
13562306a36Sopenharmony_ci *
13662306a36Sopenharmony_ci * sysv_find_entry() acts as a call to dir_get_page() and must be treated
13762306a36Sopenharmony_ci * accordingly for nesting purposes.
13862306a36Sopenharmony_ci */
13962306a36Sopenharmony_cistruct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_page)
14062306a36Sopenharmony_ci{
14162306a36Sopenharmony_ci	const char * name = dentry->d_name.name;
14262306a36Sopenharmony_ci	int namelen = dentry->d_name.len;
14362306a36Sopenharmony_ci	struct inode * dir = d_inode(dentry->d_parent);
14462306a36Sopenharmony_ci	unsigned long start, n;
14562306a36Sopenharmony_ci	unsigned long npages = dir_pages(dir);
14662306a36Sopenharmony_ci	struct page *page = NULL;
14762306a36Sopenharmony_ci	struct sysv_dir_entry *de;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	*res_page = NULL;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	start = SYSV_I(dir)->i_dir_start_lookup;
15262306a36Sopenharmony_ci	if (start >= npages)
15362306a36Sopenharmony_ci		start = 0;
15462306a36Sopenharmony_ci	n = start;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	do {
15762306a36Sopenharmony_ci		char *kaddr = dir_get_page(dir, n, &page);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci		if (!IS_ERR(kaddr)) {
16062306a36Sopenharmony_ci			de = (struct sysv_dir_entry *)kaddr;
16162306a36Sopenharmony_ci			kaddr += PAGE_SIZE - SYSV_DIRSIZE;
16262306a36Sopenharmony_ci			for ( ; (char *) de <= kaddr ; de++) {
16362306a36Sopenharmony_ci				if (!de->inode)
16462306a36Sopenharmony_ci					continue;
16562306a36Sopenharmony_ci				if (namecompare(namelen, SYSV_NAMELEN,
16662306a36Sopenharmony_ci							name, de->name))
16762306a36Sopenharmony_ci					goto found;
16862306a36Sopenharmony_ci			}
16962306a36Sopenharmony_ci			unmap_and_put_page(page, kaddr);
17062306a36Sopenharmony_ci		}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci		if (++n >= npages)
17362306a36Sopenharmony_ci			n = 0;
17462306a36Sopenharmony_ci	} while (n != start);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	return NULL;
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cifound:
17962306a36Sopenharmony_ci	SYSV_I(dir)->i_dir_start_lookup = n;
18062306a36Sopenharmony_ci	*res_page = page;
18162306a36Sopenharmony_ci	return de;
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ciint sysv_add_link(struct dentry *dentry, struct inode *inode)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	struct inode *dir = d_inode(dentry->d_parent);
18762306a36Sopenharmony_ci	const char * name = dentry->d_name.name;
18862306a36Sopenharmony_ci	int namelen = dentry->d_name.len;
18962306a36Sopenharmony_ci	struct page *page = NULL;
19062306a36Sopenharmony_ci	struct sysv_dir_entry * de;
19162306a36Sopenharmony_ci	unsigned long npages = dir_pages(dir);
19262306a36Sopenharmony_ci	unsigned long n;
19362306a36Sopenharmony_ci	char *kaddr;
19462306a36Sopenharmony_ci	loff_t pos;
19562306a36Sopenharmony_ci	int err;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	/* We take care of directory expansion in the same loop */
19862306a36Sopenharmony_ci	for (n = 0; n <= npages; n++) {
19962306a36Sopenharmony_ci		kaddr = dir_get_page(dir, n, &page);
20062306a36Sopenharmony_ci		if (IS_ERR(kaddr))
20162306a36Sopenharmony_ci			return PTR_ERR(kaddr);
20262306a36Sopenharmony_ci		de = (struct sysv_dir_entry *)kaddr;
20362306a36Sopenharmony_ci		kaddr += PAGE_SIZE - SYSV_DIRSIZE;
20462306a36Sopenharmony_ci		while ((char *)de <= kaddr) {
20562306a36Sopenharmony_ci			if (!de->inode)
20662306a36Sopenharmony_ci				goto got_it;
20762306a36Sopenharmony_ci			err = -EEXIST;
20862306a36Sopenharmony_ci			if (namecompare(namelen, SYSV_NAMELEN, name, de->name))
20962306a36Sopenharmony_ci				goto out_page;
21062306a36Sopenharmony_ci			de++;
21162306a36Sopenharmony_ci		}
21262306a36Sopenharmony_ci		unmap_and_put_page(page, kaddr);
21362306a36Sopenharmony_ci	}
21462306a36Sopenharmony_ci	BUG();
21562306a36Sopenharmony_ci	return -EINVAL;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cigot_it:
21862306a36Sopenharmony_ci	pos = page_offset(page) + offset_in_page(de);
21962306a36Sopenharmony_ci	lock_page(page);
22062306a36Sopenharmony_ci	err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
22162306a36Sopenharmony_ci	if (err)
22262306a36Sopenharmony_ci		goto out_unlock;
22362306a36Sopenharmony_ci	memcpy (de->name, name, namelen);
22462306a36Sopenharmony_ci	memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
22562306a36Sopenharmony_ci	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
22662306a36Sopenharmony_ci	dir_commit_chunk(page, pos, SYSV_DIRSIZE);
22762306a36Sopenharmony_ci	dir->i_mtime = inode_set_ctime_current(dir);
22862306a36Sopenharmony_ci	mark_inode_dirty(dir);
22962306a36Sopenharmony_ci	err = sysv_handle_dirsync(dir);
23062306a36Sopenharmony_ciout_page:
23162306a36Sopenharmony_ci	unmap_and_put_page(page, kaddr);
23262306a36Sopenharmony_ci	return err;
23362306a36Sopenharmony_ciout_unlock:
23462306a36Sopenharmony_ci	unlock_page(page);
23562306a36Sopenharmony_ci	goto out_page;
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ciint sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
24162306a36Sopenharmony_ci	loff_t pos = page_offset(page) + offset_in_page(de);
24262306a36Sopenharmony_ci	int err;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	lock_page(page);
24562306a36Sopenharmony_ci	err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
24662306a36Sopenharmony_ci	if (err) {
24762306a36Sopenharmony_ci		unlock_page(page);
24862306a36Sopenharmony_ci		return err;
24962306a36Sopenharmony_ci	}
25062306a36Sopenharmony_ci	de->inode = 0;
25162306a36Sopenharmony_ci	dir_commit_chunk(page, pos, SYSV_DIRSIZE);
25262306a36Sopenharmony_ci	inode->i_mtime = inode_set_ctime_current(inode);
25362306a36Sopenharmony_ci	mark_inode_dirty(inode);
25462306a36Sopenharmony_ci	return sysv_handle_dirsync(inode);
25562306a36Sopenharmony_ci}
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ciint sysv_make_empty(struct inode *inode, struct inode *dir)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	struct page *page = grab_cache_page(inode->i_mapping, 0);
26062306a36Sopenharmony_ci	struct sysv_dir_entry * de;
26162306a36Sopenharmony_ci	char *base;
26262306a36Sopenharmony_ci	int err;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	if (!page)
26562306a36Sopenharmony_ci		return -ENOMEM;
26662306a36Sopenharmony_ci	err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE);
26762306a36Sopenharmony_ci	if (err) {
26862306a36Sopenharmony_ci		unlock_page(page);
26962306a36Sopenharmony_ci		goto fail;
27062306a36Sopenharmony_ci	}
27162306a36Sopenharmony_ci	base = kmap_local_page(page);
27262306a36Sopenharmony_ci	memset(base, 0, PAGE_SIZE);
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	de = (struct sysv_dir_entry *) base;
27562306a36Sopenharmony_ci	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
27662306a36Sopenharmony_ci	strcpy(de->name,".");
27762306a36Sopenharmony_ci	de++;
27862306a36Sopenharmony_ci	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino);
27962306a36Sopenharmony_ci	strcpy(de->name,"..");
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	kunmap_local(base);
28262306a36Sopenharmony_ci	dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
28362306a36Sopenharmony_ci	err = sysv_handle_dirsync(inode);
28462306a36Sopenharmony_cifail:
28562306a36Sopenharmony_ci	put_page(page);
28662306a36Sopenharmony_ci	return err;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/*
29062306a36Sopenharmony_ci * routine to check that the specified directory is empty (for rmdir)
29162306a36Sopenharmony_ci */
29262306a36Sopenharmony_ciint sysv_empty_dir(struct inode * inode)
29362306a36Sopenharmony_ci{
29462306a36Sopenharmony_ci	struct super_block *sb = inode->i_sb;
29562306a36Sopenharmony_ci	struct page *page = NULL;
29662306a36Sopenharmony_ci	unsigned long i, npages = dir_pages(inode);
29762306a36Sopenharmony_ci	char *kaddr;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	for (i = 0; i < npages; i++) {
30062306a36Sopenharmony_ci		struct sysv_dir_entry *de;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci		kaddr = dir_get_page(inode, i, &page);
30362306a36Sopenharmony_ci		if (IS_ERR(kaddr))
30462306a36Sopenharmony_ci			continue;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci		de = (struct sysv_dir_entry *)kaddr;
30762306a36Sopenharmony_ci		kaddr += PAGE_SIZE-SYSV_DIRSIZE;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci		for ( ;(char *)de <= kaddr; de++) {
31062306a36Sopenharmony_ci			if (!de->inode)
31162306a36Sopenharmony_ci				continue;
31262306a36Sopenharmony_ci			/* check for . and .. */
31362306a36Sopenharmony_ci			if (de->name[0] != '.')
31462306a36Sopenharmony_ci				goto not_empty;
31562306a36Sopenharmony_ci			if (!de->name[1]) {
31662306a36Sopenharmony_ci				if (de->inode == cpu_to_fs16(SYSV_SB(sb),
31762306a36Sopenharmony_ci							inode->i_ino))
31862306a36Sopenharmony_ci					continue;
31962306a36Sopenharmony_ci				goto not_empty;
32062306a36Sopenharmony_ci			}
32162306a36Sopenharmony_ci			if (de->name[1] != '.' || de->name[2])
32262306a36Sopenharmony_ci				goto not_empty;
32362306a36Sopenharmony_ci		}
32462306a36Sopenharmony_ci		unmap_and_put_page(page, kaddr);
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci	return 1;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_cinot_empty:
32962306a36Sopenharmony_ci	unmap_and_put_page(page, kaddr);
33062306a36Sopenharmony_ci	return 0;
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci/* Releases the page */
33462306a36Sopenharmony_ciint sysv_set_link(struct sysv_dir_entry *de, struct page *page,
33562306a36Sopenharmony_ci	struct inode *inode)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	struct inode *dir = page->mapping->host;
33862306a36Sopenharmony_ci	loff_t pos = page_offset(page) + offset_in_page(de);
33962306a36Sopenharmony_ci	int err;
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	lock_page(page);
34262306a36Sopenharmony_ci	err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
34362306a36Sopenharmony_ci	if (err) {
34462306a36Sopenharmony_ci		unlock_page(page);
34562306a36Sopenharmony_ci		return err;
34662306a36Sopenharmony_ci	}
34762306a36Sopenharmony_ci	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
34862306a36Sopenharmony_ci	dir_commit_chunk(page, pos, SYSV_DIRSIZE);
34962306a36Sopenharmony_ci	dir->i_mtime = inode_set_ctime_current(dir);
35062306a36Sopenharmony_ci	mark_inode_dirty(dir);
35162306a36Sopenharmony_ci	return sysv_handle_dirsync(inode);
35262306a36Sopenharmony_ci}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci/*
35562306a36Sopenharmony_ci * Calls to dir_get_page()/unmap_and_put_page() must be nested according to the
35662306a36Sopenharmony_ci * rules documented in mm/highmem.rst.
35762306a36Sopenharmony_ci *
35862306a36Sopenharmony_ci * sysv_dotdot() acts as a call to dir_get_page() and must be treated
35962306a36Sopenharmony_ci * accordingly for nesting purposes.
36062306a36Sopenharmony_ci */
36162306a36Sopenharmony_cistruct sysv_dir_entry *sysv_dotdot(struct inode *dir, struct page **p)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	struct sysv_dir_entry *de = dir_get_page(dir, 0, p);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	if (IS_ERR(de))
36662306a36Sopenharmony_ci		return NULL;
36762306a36Sopenharmony_ci	/* ".." is the second directory entry */
36862306a36Sopenharmony_ci	return de + 1;
36962306a36Sopenharmony_ci}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ciino_t sysv_inode_by_name(struct dentry *dentry)
37262306a36Sopenharmony_ci{
37362306a36Sopenharmony_ci	struct page *page;
37462306a36Sopenharmony_ci	struct sysv_dir_entry *de = sysv_find_entry (dentry, &page);
37562306a36Sopenharmony_ci	ino_t res = 0;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	if (de) {
37862306a36Sopenharmony_ci		res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode);
37962306a36Sopenharmony_ci		unmap_and_put_page(page, de);
38062306a36Sopenharmony_ci	}
38162306a36Sopenharmony_ci	return res;
38262306a36Sopenharmony_ci}
383