Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (c) 2000-2001 Christoph Hellwig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2016 Krzysztof Blaszkowski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *    notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *    without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * 2. The name of the author may not be used to endorse or promote products
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *    derived from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * GNU General Public License ("GPL").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * Veritas filesystem driver - lookup and other directory related code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "vxfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include "vxfs_dir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "vxfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "vxfs_extern.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * Number of VxFS blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define VXFS_BLOCK_PER_PAGE(sbp)  ((PAGE_SIZE / (sbp)->s_blocksize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static struct dentry *	vxfs_lookup(struct inode *, struct dentry *, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static int		vxfs_readdir(struct file *, struct dir_context *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) const struct inode_operations vxfs_dir_inode_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	.lookup =		vxfs_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) const struct file_operations vxfs_dir_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	.llseek =		generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	.read =			generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	.iterate_shared =	vxfs_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * vxfs_find_entry - find a mathing directory entry for a dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * @ip:		directory inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * @dp:		dentry for which we want to find a direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * @ppp:	gets filled with the page the return value sits in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *   vxfs_find_entry finds a &struct vxfs_direct for the VFS directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  *   cache entry @dp.  @ppp will be filled with the page the return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *   value resides in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *   The wanted direct on success, else a NULL pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static struct vxfs_direct *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	u_long bsize = ip->i_sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	const char *name = dp->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int namelen = dp->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	loff_t limit = VXFS_DIRROUND(ip->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct vxfs_direct *de_exit = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	while (pos < limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		struct page *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		char *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		int pg_ofs = pos & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if (IS_ERR(pp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		kaddr = (char *)page_address(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		while (pg_ofs < PAGE_SIZE && pos < limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			struct vxfs_direct *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			if ((pos & (bsize - 1)) < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				struct vxfs_dirblk *dbp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 					(struct vxfs_dirblk *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 					 (kaddr + (pos & ~PAGE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				int overhead = VXFS_DIRBLKOV(sbi, dbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				pos += overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 				pg_ofs += overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			de = (struct vxfs_direct *)(kaddr + pg_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			if (!de->d_reclen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				pos += bsize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 				pos &= ~(bsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			pg_ofs += fs16_to_cpu(sbi, de->d_reclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			pos += fs16_to_cpu(sbi, de->d_reclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			if (!de->d_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			if (namelen != fs16_to_cpu(sbi, de->d_namelen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			if (!memcmp(name, de->d_name, namelen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 				*ppp = pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 				de_exit = de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		if (!de_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			vxfs_put_page(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return de_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * vxfs_inode_by_name - find inode number for dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * @dip:	directory to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * @dp:		dentry we search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *   vxfs_inode_by_name finds out the inode number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *   the path component described by @dp in @dip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *   The wanted inode number on success, else Zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static ino_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	struct vxfs_direct		*de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	struct page			*pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	ino_t				ino = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	de = vxfs_find_entry(dip, dp, &pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (de) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		kunmap(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		put_page(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return (ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * vxfs_lookup - lookup pathname component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * @dip:	dir in which we lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @dp:		dentry we lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @flags:	lookup flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *   vxfs_lookup tries to lookup the pathname component described
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *   by @dp in @dip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  *   A NULL-pointer on success, else a negative error code encoded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *   in the return pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static struct dentry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	struct inode		*ip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	ino_t			ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (dp->d_name.len > VXFS_NAMELEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 				 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	ino = vxfs_inode_by_name(dip, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		ip = vxfs_iget(dip->i_sb, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return d_splice_alias(ip, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * vxfs_readdir - read a directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * @fp:		the directory to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * @retp:	return buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * @filler:	filldir callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  *   vxfs_readdir fills @retp with directory entries from @fp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  *   using the VFS supplied callback @filler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  *   Zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) vxfs_readdir(struct file *fp, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct inode		*ip = file_inode(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct super_block	*sbp = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	u_long			bsize = sbp->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	loff_t			pos, limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (ctx->pos == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (!dir_emit_dot(fp, ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		ctx->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (ctx->pos == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		ctx->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	limit = VXFS_DIRROUND(ip->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (ctx->pos > limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	pos = ctx->pos & ~3L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	while (pos < limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		struct page *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		char *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		int pg_ofs = pos & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		if (IS_ERR(pp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		kaddr = (char *)page_address(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		while (pg_ofs < PAGE_SIZE && pos < limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			struct vxfs_direct *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			if ((pos & (bsize - 1)) < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				struct vxfs_dirblk *dbp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 					(struct vxfs_dirblk *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 					 (kaddr + (pos & ~PAGE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				int overhead = VXFS_DIRBLKOV(sbi, dbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				pos += overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 				pg_ofs += overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			de = (struct vxfs_direct *)(kaddr + pg_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			if (!de->d_reclen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				pos += bsize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				pos &= ~(bsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			pg_ofs += fs16_to_cpu(sbi, de->d_reclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			pos += fs16_to_cpu(sbi, de->d_reclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			if (!de->d_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			rc = dir_emit(ctx, de->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 					fs16_to_cpu(sbi, de->d_namelen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 					fs32_to_cpu(sbi, de->d_ino),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 					DT_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 				/* the dir entry was not read, fix pos. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				pos -= fs16_to_cpu(sbi, de->d_reclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		vxfs_put_page(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	ctx->pos = pos | 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }