^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) }