^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Directory operations for Coda filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Original version: (C) 1996 P. Braam and M. Callahan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Carnegie Mellon encourages users to contribute improvements to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/coda.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "coda_psdev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "coda_linux.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "coda_cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "coda_int.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* same as fs/bad_inode.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int coda_return_EIO(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CODA_EIO_ERROR ((void *) (coda_return_EIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* inode operations for directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* access routines: lookup, readlink, permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) const char *name = entry->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) size_t length = entry->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (length > CODA_MAXNAMLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) pr_err("name too long: lookup, %s %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) coda_i2s(dir), length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* control object, create inode on the fly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (is_root_inode(dir) && coda_iscontrol(name, length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) inode = coda_cnode_makectl(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) type = CODA_NOCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct CodaFid fid = { { 0, } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int error = venus_lookup(sb, coda_i2f(dir), name, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) &type, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) inode = !error ? coda_cnode_make(&fid, sb) : ERR_PTR(error);
^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) if (!IS_ERR(inode) && (type & CODA_NOCACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) coda_flag_inode(inode, C_VATTR | C_PURGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (inode == ERR_PTR(-ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return d_splice_alias(inode, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int coda_permission(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (mask & MAY_NOT_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if ((mask & MAY_EXEC) && !execute_ok(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (coda_cache_check(inode, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) error = venus_access(inode->i_sb, coda_i2f(inode), mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) coda_cache_enter(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static inline void coda_dir_update_mtime(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #ifdef REQUERY_VENUS_FOR_MTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* invalidate the directory cnode's attributes so we refetch the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * attributes from venus next time the inode is referenced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) coda_flag_inode(dir, C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* optimistically we can also act as if our nose bleeds. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * granularity of the mtime is coarse anyways so we might actually be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * right most of the time. Note: we only do this for directories. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dir->i_mtime = dir->i_ctime = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* we have to wrap inc_nlink/drop_nlink because sometimes userspace uses a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * trick to fool GNU find's optimizations. If we can't be sure of the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * (because of volume mount points) we set i_nlink to 1 which forces find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * to consider every child as a possible directory. We should also never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * see an increment or decrement for deleted directories where i_nlink == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static inline void coda_dir_inc_nlink(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (dir->i_nlink >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) inc_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static inline void coda_dir_drop_nlink(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (dir->i_nlink > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) drop_nlink(dir);
^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) /* creation routines: create, mknod, mkdir, link, symlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) const char *name=de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int length=de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct CodaFid newfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct coda_vattr attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (is_root_inode(dir) && coda_iscontrol(name, length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 0, mode, &newfid, &attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) inode = coda_iget(dir->i_sb, &newfid, &attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) error = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* invalidate the directory cnode's attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) coda_dir_update_mtime(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) d_instantiate(de, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) d_drop(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct coda_vattr attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const char *name = de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int len = de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct CodaFid newfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (is_root_inode(dir) && coda_iscontrol(name, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) attrs.va_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) error = venus_mkdir(dir->i_sb, coda_i2f(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) name, len, &newfid, &attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) inode = coda_iget(dir->i_sb, &newfid, &attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) error = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* invalidate the directory cnode's attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) coda_dir_inc_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) coda_dir_update_mtime(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) d_instantiate(de, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) d_drop(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return error;
^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) /* try to make de an entry in dir_inodde linked to source_de */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int coda_link(struct dentry *source_de, struct inode *dir_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct dentry *de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct inode *inode = d_inode(source_de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) const char * name = de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int len = de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (is_root_inode(dir_inode) && coda_iscontrol(name, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) error = venus_link(dir_inode->i_sb, coda_i2f(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) coda_i2f(dir_inode), (const char *)name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) d_drop(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) coda_dir_update_mtime(dir_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) d_instantiate(de, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) inc_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int coda_symlink(struct inode *dir_inode, struct dentry *de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) const char *name = de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int len = de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int symlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (is_root_inode(dir_inode) && coda_iscontrol(name, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) symlen = strlen(symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (symlen > CODA_MAXPATHLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * This entry is now negative. Since we do not create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * an inode for the entry we have to drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) d_drop(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) symname, symlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* mtime is no good anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) coda_dir_update_mtime(dir_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* destruction routines: unlink, rmdir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int coda_unlink(struct inode *dir, struct dentry *de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) const char *name = de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int len = de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) coda_dir_update_mtime(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) drop_nlink(d_inode(de));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int coda_rmdir(struct inode *dir, struct dentry *de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const char *name = de->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int len = de->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* VFS may delete the child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (d_really_is_positive(de))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) clear_nlink(d_inode(de));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* fix the link count of the parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) coda_dir_drop_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) coda_dir_update_mtime(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* rename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) const char *old_name = old_dentry->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const char *new_name = new_dentry->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int old_length = old_dentry->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int new_length = new_dentry->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) coda_i2f(new_dir), old_length, new_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) (const char *) old_name, (const char *)new_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (d_really_is_positive(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (d_is_dir(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) coda_dir_drop_nlink(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) coda_dir_inc_nlink(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) coda_dir_update_mtime(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) coda_dir_update_mtime(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) coda_flag_inode(d_inode(new_dentry), C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) coda_flag_inode(old_dir, C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) coda_flag_inode(new_dir, C_VATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static inline unsigned int CDT2DT(unsigned char cdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned int dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) switch(cdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case CDT_UNKNOWN: dt = DT_UNKNOWN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case CDT_FIFO: dt = DT_FIFO; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case CDT_CHR: dt = DT_CHR; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case CDT_DIR: dt = DT_DIR; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case CDT_BLK: dt = DT_BLK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case CDT_REG: dt = DT_REG; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case CDT_LNK: dt = DT_LNK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case CDT_SOCK: dt = DT_SOCK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case CDT_WHT: dt = DT_WHT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) default: dt = DT_UNKNOWN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* support routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct coda_file_info *cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct coda_inode_info *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct file *host_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct venus_dirent *vdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned long vdir_size = offsetof(struct venus_dirent, d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct qstr name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ino_t ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) cfi = coda_ftoc(coda_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) host_file = cfi->cfi_container;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cii = ITOC(file_inode(coda_file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!vdir) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!dir_emit_dots(coda_file, ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) loff_t pos = ctx->pos - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* read entries from the directory file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = kernel_read(host_file, vdir, sizeof(*vdir), &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pr_err("%s: read dir %s failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) __func__, coda_f2s(&cii->c_fid), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (ret == 0) break; /* end of directory file reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* catch truncated reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pr_err("%s: short read on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) __func__, coda_f2s(&cii->c_fid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* validate whether the directory file actually makes sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pr_err("%s: invalid dir %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) __func__, coda_f2s(&cii->c_fid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) name.len = vdir->d_namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) name.name = vdir->d_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Make sure we skip '.' and '..', we already got those */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (name.name[0] == '.' && (name.len == 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) (name.name[1] == '.' && name.len == 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) vdir->d_fileno = name.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* skip null entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (vdir->d_fileno && name.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ino = vdir->d_fileno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) type = CDT2DT(vdir->d_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!dir_emit(ctx, name.name, name.len, ino, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* we'll always have progress because d_reclen is unsigned and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * we've already established it is non-zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ctx->pos += vdir->d_reclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) kfree(vdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* file operations for directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct coda_file_info *cfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct file *host_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) cfi = coda_ftoc(coda_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) host_file = cfi->cfi_container;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (host_file->f_op->iterate || host_file->f_op->iterate_shared) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct inode *host_inode = file_inode(host_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (!IS_DEADDIR(host_inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (host_file->f_op->iterate_shared) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) inode_lock_shared(host_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = host_file->f_op->iterate_shared(host_file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) file_accessed(host_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) inode_unlock_shared(host_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) inode_lock(host_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = host_file->f_op->iterate(host_file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) file_accessed(host_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) inode_unlock(host_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Venus: we must read Venus dirents from a file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return coda_venus_readdir(coda_file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* called when a cache lookup succeeds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct coda_inode_info *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) inode = d_inode(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!inode || is_root_inode(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (is_bad_inode(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) cii = ITOC(d_inode(de));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!(cii->c_flags & (C_PURGE | C_FLUSH)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) shrink_dcache_parent(de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* propagate for a flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (cii->c_flags & C_FLUSH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) coda_flag_inode_children(inode, C_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (d_count(de) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* pretend it's valid, but don't change the flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* clear the flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_lock(&cii->c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) spin_unlock(&cii->c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * This is the callback from dput() when d_count is going to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * We use this to unhash dentries with bad inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static int coda_dentry_delete(const struct dentry * dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (d_really_is_negative(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) flags = (ITOC(d_inode(dentry))->c_flags) & C_PURGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (is_bad_inode(d_inode(dentry)) || flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * This is called when we want to check if the inode has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * changed on the server. Coda makes this easy since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * cache manager Venus issues a downcall to the kernel when this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * happens
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int coda_revalidate_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct coda_vattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int old_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ino_t old_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct coda_inode_info *cii = ITOC(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!cii->c_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* this inode may be lost if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) - it's ino changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) - type changes must be permitted for repair and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) missing mount points.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) old_mode = inode->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) old_ino = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) coda_vattr_to_iattr(inode, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pr_warn("inode %ld, fid %s changed type!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) inode->i_ino, coda_f2s(&(cii->c_fid)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* the following can happen when a local fid is replaced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) with a global one, here we lose and declare the inode bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (inode->i_ino != old_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) coda_flag_inode_children(inode, C_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) spin_lock(&cii->c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) spin_unlock(&cii->c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) const struct dentry_operations coda_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .d_revalidate = coda_dentry_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .d_delete = coda_dentry_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) const struct inode_operations coda_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .create = coda_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .lookup = coda_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .link = coda_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .unlink = coda_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .symlink = coda_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .mkdir = coda_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .rmdir = coda_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .mknod = CODA_EIO_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .rename = coda_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .permission = coda_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .getattr = coda_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .setattr = coda_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) const struct file_operations coda_dir_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .read = generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .iterate = coda_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .open = coda_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .release = coda_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .fsync = coda_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) };