^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) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/writeback.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/posix_acl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "super.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "mds_client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ceph/decode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Ceph inode operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Implement basic inode helpers (get, alloc) and inode ops (getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * setattr, etc.), xattr helpers, and helpers for assimilating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * metadata returned by the MDS into our cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Also define helpers for doing asynchronous writeback, invalidation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * and truncation for the benefit of those who can't afford to block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * (typically because they are in the message handler path).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct inode_operations ceph_symlink_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void ceph_inode_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * find or create an inode, given the ceph ino number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int ceph_set_ino_cb(struct inode *inode, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ci->i_vino = *(struct ceph_vino *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) inode->i_ino = ceph_vino_to_ino_t(ci->i_vino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) inode_set_iversion_raw(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) percpu_counter_inc(&mdsc->metric.total_inodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^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) struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ceph_vino_is_reserved(vino))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return ERR_PTR(-EREMOTEIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) inode = iget5_locked(sb, (unsigned long)vino.ino, ceph_ino_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ceph_set_ino_cb, &vino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dout("get_inode on %llu=%llx.%llx got %p new %d\n", ceph_present_inode(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ceph_vinop(inode), inode, !!(inode->i_state & I_NEW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * get/constuct snapdir inode for a given directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct inode *ceph_get_snapdir(struct inode *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct ceph_vino vino = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .ino = ceph_ino(parent),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .snap = CEPH_SNAPDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct inode *inode = ceph_get_inode(parent->i_sb, vino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) BUG_ON(!S_ISDIR(parent->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) inode->i_mode = parent->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) inode->i_uid = parent->i_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) inode->i_gid = parent->i_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) inode->i_mtime = parent->i_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) inode->i_ctime = parent->i_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) inode->i_atime = parent->i_atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ci->i_rbytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ci->i_btime = ceph_inode(parent)->i_btime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (inode->i_state & I_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) inode->i_op = &ceph_snapdir_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) inode->i_fop = &ceph_snapdir_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unlock_new_inode(inode);
^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) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const struct inode_operations ceph_file_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .permission = ceph_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .setattr = ceph_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .getattr = ceph_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .listxattr = ceph_listxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .get_acl = ceph_get_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .set_acl = ceph_set_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^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 use a 'frag tree' to keep track of the MDS's directory fragments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * for a given inode (usually there is just a single fragment). We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * need to know when a child frag is delegated to a new MDS, or when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * it is flagged as replicated, so we can direct our requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * find/create a frag in the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct rb_node **p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct ceph_inode_frag *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) p = &ci->i_fragtree.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) frag = rb_entry(parent, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) c = ceph_frag_compare(f, frag->frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (c < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) else if (c > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) frag = kmalloc(sizeof(*frag), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) frag->frag = f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) frag->split_by = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) frag->mds = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) frag->ndist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rb_link_node(&frag->node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rb_insert_color(&frag->node, &ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dout("get_or_create_frag added %llx.%llx frag %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ceph_vinop(&ci->vfs_inode), f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * find a specific frag @f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct rb_node *n = ci->i_fragtree.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct ceph_inode_frag *frag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rb_entry(n, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int c = ceph_frag_compare(f, frag->frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (c < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) else if (c > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * Choose frag containing the given value @v. If @pfrag is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * specified, copy the frag delegation info to the caller if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * it is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static u32 __ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct ceph_inode_frag *pfrag, int *found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u32 t = ceph_frag_make(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct ceph_inode_frag *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned nway, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) WARN_ON(!ceph_frag_contains_value(t, v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) frag = __ceph_find_frag(ci, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break; /* t is a leaf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (frag->split_by == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (pfrag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) memcpy(pfrag, frag, sizeof(*pfrag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* choose child */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) nway = 1 << frag->split_by;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dout("choose_frag(%x) %x splits by %d (%d ways)\n", v, t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) frag->split_by, nway);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) for (i = 0; i < nway; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) n = ceph_frag_make_child(t, frag->split_by, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ceph_frag_contains_value(n, v)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) t = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) BUG_ON(i == nway);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dout("choose_frag(%x) = %x\n", v, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct ceph_inode_frag *pfrag, int *found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mutex_lock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = __ceph_choose_frag(ci, v, pfrag, found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_unlock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^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) * Process dirfrag (delegation) info from the mds. Include leaf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * fragment in tree ONLY if ndist > 0. Otherwise, only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * branches/splits are included in i_fragtree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int ceph_fill_dirfrag(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct ceph_mds_reply_dirfrag *dirinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct ceph_inode_frag *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u32 id = le32_to_cpu(dirinfo->frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int mds = le32_to_cpu(dirinfo->auth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ndist = le32_to_cpu(dirinfo->ndist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int diri_auth = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ci->i_auth_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) diri_auth = ci->i_auth_cap->mds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (mds == -1) /* CDIR_AUTH_PARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mds = diri_auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mutex_lock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ndist == 0 && mds == diri_auth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* no delegation info needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) frag = __ceph_find_frag(ci, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (frag->split_by == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* tree leaf, remove */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dout("fill_dirfrag removed %llx.%llx frag %x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) " (no ref)\n", ceph_vinop(inode), id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) rb_erase(&frag->node, &ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) kfree(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* tree branch, keep and clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dout("fill_dirfrag cleared %llx.%llx frag %x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) " referral\n", ceph_vinop(inode), id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) frag->mds = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) frag->ndist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* find/add this frag to store mds delegation info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) frag = __get_or_create_frag(ci, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (IS_ERR(frag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* this is not the end of the world; we can continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) with bad/inaccurate delegation info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) pr_err("fill_dirfrag ENOMEM on mds ref %llx.%llx fg %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ceph_vinop(inode), le32_to_cpu(dirinfo->frag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) frag->mds = mds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) frag->ndist = min_t(u32, ndist, CEPH_MAX_DIRFRAG_REP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) for (i = 0; i < frag->ndist; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) frag->dist[i] = le32_to_cpu(dirinfo->dist[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dout("fill_dirfrag %llx.%llx frag %x ndist=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ceph_vinop(inode), frag->frag, frag->ndist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) mutex_unlock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int frag_tree_split_cmp(const void *l, const void *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct ceph_frag_tree_split *ls = (struct ceph_frag_tree_split*)l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct ceph_frag_tree_split *rs = (struct ceph_frag_tree_split*)r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ceph_frag_compare(le32_to_cpu(ls->frag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) le32_to_cpu(rs->frag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static bool is_frag_child(u32 f, struct ceph_inode_frag *frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return f == ceph_frag_make(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (ceph_frag_bits(f) != ceph_frag_bits(frag->frag) + frag->split_by)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ceph_frag_contains_value(frag->frag, ceph_frag_value(f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int ceph_fill_fragtree(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct ceph_frag_tree_head *fragtree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct ceph_mds_reply_dirfrag *dirinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct ceph_inode_frag *frag, *prev_frag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct rb_node *rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned i, split_by, nsplits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) bool update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mutex_lock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) nsplits = le32_to_cpu(fragtree->nsplits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (nsplits != ci->i_fragtree_nsplits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else if (nsplits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) i = prandom_u32() % nsplits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) id = le32_to_cpu(fragtree->splits[i].frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!__ceph_find_frag(ci, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) } else if (!RB_EMPTY_ROOT(&ci->i_fragtree)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rb_node = rb_first(&ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) frag = rb_entry(rb_node, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (frag->frag != ceph_frag_make(0, 0) || rb_next(rb_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!update && dirinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) id = le32_to_cpu(dirinfo->frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (id != __ceph_choose_frag(ci, id, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (nsplits > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) sort(fragtree->splits, nsplits, sizeof(fragtree->splits[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) frag_tree_split_cmp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dout("fill_fragtree %llx.%llx\n", ceph_vinop(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) rb_node = rb_first(&ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) for (i = 0; i < nsplits; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) id = le32_to_cpu(fragtree->splits[i].frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) split_by = le32_to_cpu(fragtree->splits[i].by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (split_by == 0 || ceph_frag_bits(id) + split_by > 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pr_err("fill_fragtree %llx.%llx invalid split %d/%u, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "frag %x split by %d\n", ceph_vinop(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) i, nsplits, id, split_by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) frag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) while (rb_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) frag = rb_entry(rb_node, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (ceph_frag_compare(frag->frag, id) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (frag->frag != id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) frag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rb_node = rb_next(rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) rb_node = rb_next(rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* delete stale split/leaf node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (frag->split_by > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) !is_frag_child(frag->frag, prev_frag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) rb_erase(&frag->node, &ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (frag->split_by > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ci->i_fragtree_nsplits--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) kfree(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) frag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!frag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) frag = __get_or_create_frag(ci, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (IS_ERR(frag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (frag->split_by == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ci->i_fragtree_nsplits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) frag->split_by = split_by;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dout(" frag %x split by %d\n", frag->frag, frag->split_by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) prev_frag = frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) while (rb_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) frag = rb_entry(rb_node, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) rb_node = rb_next(rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* delete stale split/leaf node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (frag->split_by > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) !is_frag_child(frag->frag, prev_frag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) rb_erase(&frag->node, &ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (frag->split_by > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ci->i_fragtree_nsplits--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) kfree(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) mutex_unlock(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * initialize a newly allocated inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct inode *ceph_alloc_inode(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct ceph_inode_info *ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ci = kmem_cache_alloc(ceph_inode_cachep, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) dout("alloc_inode %p\n", &ci->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) spin_lock_init(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ci->i_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ci->i_inline_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ci->i_time_warp_seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ci->i_ceph_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) atomic64_set(&ci->i_ordered_count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) atomic64_set(&ci->i_release_count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) atomic64_set(&ci->i_complete_seq[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) atomic64_set(&ci->i_complete_seq[1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ci->i_symlink = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ci->i_max_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ci->i_max_files = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) memset(&ci->i_cached_layout, 0, sizeof(ci->i_cached_layout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) RCU_INIT_POINTER(ci->i_layout.pool_ns, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ci->i_fragtree = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mutex_init(&ci->i_fragtree_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ci->i_xattrs.blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ci->i_xattrs.prealloc_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ci->i_xattrs.dirty = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ci->i_xattrs.index = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ci->i_xattrs.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ci->i_xattrs.names_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ci->i_xattrs.vals_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ci->i_xattrs.version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ci->i_xattrs.index_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ci->i_caps = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ci->i_auth_cap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ci->i_dirty_caps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ci->i_flushing_caps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) INIT_LIST_HEAD(&ci->i_dirty_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) INIT_LIST_HEAD(&ci->i_flushing_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ci->i_prealloc_cap_flush = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) INIT_LIST_HEAD(&ci->i_cap_flush_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) init_waitqueue_head(&ci->i_cap_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ci->i_hold_caps_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) INIT_LIST_HEAD(&ci->i_cap_delay_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) INIT_LIST_HEAD(&ci->i_cap_snaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ci->i_head_snapc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ci->i_snap_caps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ci->i_last_rd = ci->i_last_wr = jiffies - 3600 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) for (i = 0; i < CEPH_FILE_MODE_BITS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ci->i_nr_by_mode[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mutex_init(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ci->i_truncate_seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ci->i_truncate_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ci->i_truncate_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ci->i_max_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ci->i_reported_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ci->i_wanted_max_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ci->i_requested_max_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ci->i_pin_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ci->i_rd_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ci->i_rdcache_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ci->i_wr_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ci->i_wb_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ci->i_fx_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ci->i_wrbuffer_ref = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ci->i_wrbuffer_ref_head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) atomic_set(&ci->i_filelock_ref, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) atomic_set(&ci->i_shared_gen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ci->i_rdcache_gen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ci->i_rdcache_revoking = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) INIT_LIST_HEAD(&ci->i_unsafe_dirops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) INIT_LIST_HEAD(&ci->i_unsafe_iops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spin_lock_init(&ci->i_unsafe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ci->i_snap_realm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) INIT_LIST_HEAD(&ci->i_snap_realm_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) INIT_LIST_HEAD(&ci->i_snap_flush_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) INIT_WORK(&ci->i_work, ceph_inode_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ci->i_work_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) memset(&ci->i_btime, '\0', sizeof(ci->i_btime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ceph_fscache_inode_init(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return &ci->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) void ceph_free_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) kfree(ci->i_symlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) kmem_cache_free(ceph_inode_cachep, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) void ceph_evict_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct ceph_inode_frag *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dout("evict_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) percpu_counter_dec(&mdsc->metric.total_inodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) truncate_inode_pages_final(&inode->i_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) clear_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ceph_fscache_unregister_inode_cookie(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) __ceph_remove_caps(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (__ceph_has_any_quota(ci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ceph_adjust_quota_realms_count(inode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * we may still have a snap_realm reference if there are stray
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * caps in i_snap_caps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ci->i_snap_realm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (ceph_snap(inode) == CEPH_NOSNAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct ceph_snap_realm *realm = ci->i_snap_realm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dout(" dropping residual ref to snap realm %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) realm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) spin_lock(&realm->inodes_with_caps_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) list_del_init(&ci->i_snap_realm_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ci->i_snap_realm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (realm->ino == ci->i_vino.ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) realm->inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) spin_unlock(&realm->inodes_with_caps_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ceph_put_snap_realm(mdsc, realm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ceph_put_snapid_map(mdsc, ci->i_snapid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ci->i_snap_realm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) while ((n = rb_first(&ci->i_fragtree)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) frag = rb_entry(n, struct ceph_inode_frag, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rb_erase(n, &ci->i_fragtree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) kfree(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ci->i_fragtree_nsplits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) __ceph_destroy_xattrs(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ci->i_xattrs.blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ceph_buffer_put(ci->i_xattrs.blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (ci->i_xattrs.prealloc_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ceph_buffer_put(ci->i_xattrs.prealloc_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ceph_put_string(rcu_dereference_raw(ci->i_layout.pool_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ceph_put_string(rcu_dereference_raw(ci->i_cached_layout.pool_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static inline blkcnt_t calc_inode_blocks(u64 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return (size + (1<<9) - 1) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * Helpers to fill in size, ctime, mtime, and atime. We have to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * careful because either the client or MDS may have more up to date
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * info, depending on which capabilities are held, and whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * time_warp_seq or truncate_seq have increased. (Ordinarily, mtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * and size are monotonically increasing, except when utimes() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * truncate() increments the corresponding _seq values.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int ceph_fill_file_size(struct inode *inode, int issued,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) u32 truncate_seq, u64 truncate_size, u64 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int queue_trunc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dout("size %lld -> %llu\n", inode->i_size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (size > 0 && S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) pr_err("fill_file_size non-zero size for directory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) i_size_write(inode, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) inode->i_blocks = calc_inode_blocks(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ci->i_reported_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (truncate_seq != ci->i_truncate_seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dout("truncate_seq %u -> %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ci->i_truncate_seq, truncate_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ci->i_truncate_seq = truncate_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* the MDS should have revoked these caps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) WARN_ON_ONCE(issued & (CEPH_CAP_FILE_EXCL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) CEPH_CAP_FILE_RD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) CEPH_CAP_FILE_WR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) CEPH_CAP_FILE_LAZYIO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * If we hold relevant caps, or in the case where we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * not the only client referencing this file and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * don't hold those caps, then we need to check whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * the file is either opened or mmaped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if ((issued & (CEPH_CAP_FILE_CACHE|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) CEPH_CAP_FILE_BUFFER)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) mapping_mapped(inode->i_mapping) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) __ceph_is_file_opened(ci)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ci->i_truncate_pending++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) queue_trunc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ci->i_truncate_size != truncate_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dout("truncate_size %lld -> %llu\n", ci->i_truncate_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) truncate_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ci->i_truncate_size = truncate_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (queue_trunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ceph_fscache_invalidate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return queue_trunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void ceph_fill_file_time(struct inode *inode, int issued,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) u64 time_warp_seq, struct timespec64 *ctime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct timespec64 *mtime, struct timespec64 *atime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int warn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (issued & (CEPH_CAP_FILE_EXCL|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) CEPH_CAP_FILE_WR|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) CEPH_CAP_FILE_BUFFER|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) CEPH_CAP_AUTH_EXCL|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) CEPH_CAP_XATTR_EXCL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (ci->i_version == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) timespec64_compare(ctime, &inode->i_ctime) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dout("ctime %lld.%09ld -> %lld.%09ld inc w/ cap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ctime->tv_sec, ctime->tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) inode->i_ctime = *ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ci->i_version == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* the MDS did a utimes() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dout("mtime %lld.%09ld -> %lld.%09ld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) "tw %d -> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mtime->tv_sec, mtime->tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ci->i_time_warp_seq, (int)time_warp_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) inode->i_mtime = *mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) inode->i_atime = *atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) ci->i_time_warp_seq = time_warp_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) } else if (time_warp_seq == ci->i_time_warp_seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* nobody did utimes(); take the max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (timespec64_compare(mtime, &inode->i_mtime) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dout("mtime %lld.%09ld -> %lld.%09ld inc\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) inode->i_mtime.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) inode->i_mtime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mtime->tv_sec, mtime->tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) inode->i_mtime = *mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (timespec64_compare(atime, &inode->i_atime) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dout("atime %lld.%09ld -> %lld.%09ld inc\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) inode->i_atime.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) inode->i_atime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) atime->tv_sec, atime->tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) inode->i_atime = *atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) } else if (issued & CEPH_CAP_FILE_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* we did a utimes(); ignore mds values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) warn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* we have no write|excl caps; whatever the MDS says is true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) inode->i_ctime = *ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) inode->i_mtime = *mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) inode->i_atime = *atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ci->i_time_warp_seq = time_warp_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) warn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (warn) /* time_warp_seq shouldn't go backwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dout("%p mds time_warp_seq %llu < %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) inode, time_warp_seq, ci->i_time_warp_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Populate an inode based on info from mds. May be called on new or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * existing inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int ceph_fill_inode(struct inode *inode, struct page *locked_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct ceph_mds_reply_info_in *iinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct ceph_mds_reply_dirfrag *dirinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct ceph_mds_session *session, int cap_fmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct ceph_cap_reservation *caps_reservation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct ceph_mds_reply_inode *info = iinfo->in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int issued, new_issued, info_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct timespec64 mtime, atime, ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct ceph_buffer *xattr_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct ceph_buffer *old_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct ceph_string *pool_ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct ceph_cap *new_cap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) bool wake = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) bool queue_trunc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) bool new_version = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) bool fill_inline = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) lockdep_assert_held(&mdsc->snap_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) inode, ceph_vinop(inode), le64_to_cpu(info->version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ci->i_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) info_caps = le32_to_cpu(info->cap.caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* prealloc new cap struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (info_caps && ceph_snap(inode) == CEPH_NOSNAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) new_cap = ceph_get_cap(mdsc, caps_reservation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (!new_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * prealloc xattr data, if it looks like we'll need it. only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * if len > 4 (meaning there are actually xattrs; the first 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * bytes are the xattr count).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (iinfo->xattr_len > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!xattr_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) pr_err("%s ENOMEM xattr blob %d bytes\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) iinfo->xattr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (iinfo->pool_ns_len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) pool_ns = ceph_find_or_create_string(iinfo->pool_ns_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) iinfo->pool_ns_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ceph_snap(inode) != CEPH_NOSNAP && !ci->i_snapid_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ci->i_snapid_map = ceph_get_snapid_map(mdsc, ceph_snap(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * provided version will be odd if inode value is projected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * even if stable. skip the update if we have newer stable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * info (ours>=theirs, e.g. due to racing mds replies), unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * we are getting projected (unstable) info (in which case the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * version is odd, and we want ours>theirs).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * us them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * 2 2 skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * 3 2 skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * 3 3 update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ci->i_version == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) le64_to_cpu(info->version) > (ci->i_version & ~1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) new_version = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* Update change_attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) inode_set_max_iversion_raw(inode, iinfo->change_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) __ceph_caps_issued(ci, &issued);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) issued |= __ceph_caps_dirty(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) new_issued = ~issued & info_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* update inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) inode->i_rdev = le32_to_cpu(info->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* directories have fl_stripe_unit set to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (le32_to_cpu(info->layout.fl_stripe_unit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) inode->i_blkbits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) inode->i_blkbits = CEPH_BLOCK_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) __ceph_update_quota(ci, iinfo->max_bytes, iinfo->max_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) (issued & CEPH_CAP_AUTH_EXCL) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) inode->i_mode = le32_to_cpu(info->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) from_kuid(&init_user_ns, inode->i_uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) from_kgid(&init_user_ns, inode->i_gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ceph_decode_timespec64(&ci->i_btime, &iinfo->btime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ceph_decode_timespec64(&ci->i_snap_btime, &iinfo->snap_btime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if ((new_version || (new_issued & CEPH_CAP_LINK_SHARED)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) (issued & CEPH_CAP_LINK_EXCL) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) set_nlink(inode, le32_to_cpu(info->nlink));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (new_version || (new_issued & CEPH_CAP_ANY_RD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* be careful with mtime, atime, size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ceph_decode_timespec64(&atime, &info->atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ceph_decode_timespec64(&mtime, &info->mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ceph_decode_timespec64(&ctime, &info->ctime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ceph_fill_file_time(inode, issued,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) le32_to_cpu(info->time_warp_seq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) &ctime, &mtime, &atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (new_version || (info_caps & CEPH_CAP_FILE_SHARED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ci->i_files = le64_to_cpu(info->files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ci->i_subdirs = le64_to_cpu(info->subdirs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (new_version ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) (new_issued & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) s64 old_pool = ci->i_layout.pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct ceph_string *old_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ceph_file_layout_from_legacy(&ci->i_layout, &info->layout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) old_ns = rcu_dereference_protected(ci->i_layout.pool_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) lockdep_is_held(&ci->i_ceph_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) rcu_assign_pointer(ci->i_layout.pool_ns, pool_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (ci->i_layout.pool_id != old_pool || pool_ns != old_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) pool_ns = old_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) queue_trunc = ceph_fill_file_size(inode, issued,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) le32_to_cpu(info->truncate_seq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) le64_to_cpu(info->truncate_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) le64_to_cpu(info->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* only update max_size on auth cap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ci->i_max_size != le64_to_cpu(info->max_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dout("max_size %lld -> %llu\n", ci->i_max_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) le64_to_cpu(info->max_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ci->i_max_size = le64_to_cpu(info->max_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* layout and rstat are not tracked by capability, update them if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * the inode info is from auth mds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (new_version || (info->cap.flags & CEPH_CAP_FLAG_AUTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ci->i_dir_layout = iinfo->dir_layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ci->i_rbytes = le64_to_cpu(info->rbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ci->i_rfiles = le64_to_cpu(info->rfiles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) ci->i_dir_pin = iinfo->dir_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ceph_decode_timespec64(&ci->i_rctime, &info->rctime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* xattrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (ci->i_xattrs.blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) old_blob = ci->i_xattrs.blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ci->i_xattrs.blob = xattr_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (xattr_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) memcpy(ci->i_xattrs.blob->vec.iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) iinfo->xattr_data, iinfo->xattr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ci->i_xattrs.version = le64_to_cpu(info->xattr_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ceph_forget_all_cached_acls(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ceph_security_invalidate_secctx(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) xattr_blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* finally update i_version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (le64_to_cpu(info->version) > ci->i_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ci->i_version = le64_to_cpu(info->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) inode->i_mapping->a_ops = &ceph_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) switch (inode->i_mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case S_IFIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) case S_IFBLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) case S_IFCHR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) case S_IFSOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) inode->i_blkbits = PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) init_special_inode(inode, inode->i_mode, inode->i_rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) inode->i_op = &ceph_file_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) inode->i_op = &ceph_file_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) inode->i_fop = &ceph_file_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) inode->i_op = &ceph_symlink_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (!ci->i_symlink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) u32 symlen = iinfo->symlink_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) char *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (symlen != i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) pr_err("%s %llx.%llx BAD symlink "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) "size %lld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ceph_vinop(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) i_size_read(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) i_size_write(inode, symlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) inode->i_blocks = calc_inode_blocks(symlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) sym = kstrndup(iinfo->symlink, symlen, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (!ci->i_symlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ci->i_symlink = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) kfree(sym); /* lost a race */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) inode->i_link = ci->i_symlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) inode->i_op = &ceph_dir_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) inode->i_fop = &ceph_dir_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) pr_err("%s %llx.%llx BAD mode 0%o\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ceph_vinop(inode), inode->i_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* were we issued a capability? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (info_caps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (ceph_snap(inode) == CEPH_NOSNAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ceph_add_cap(inode, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) le64_to_cpu(info->cap.cap_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) info_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) le32_to_cpu(info->cap.wanted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) le32_to_cpu(info->cap.seq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) le32_to_cpu(info->cap.mseq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) le64_to_cpu(info->cap.realm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) info->cap.flags, &new_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* set dir completion flag? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (S_ISDIR(inode->i_mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ci->i_files == 0 && ci->i_subdirs == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) (info_caps & CEPH_CAP_FILE_SHARED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) (issued & CEPH_CAP_FILE_EXCL) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) !__ceph_dir_is_complete(ci)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dout(" marking %p complete (empty)\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) i_size_write(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) __ceph_dir_set_complete(ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) atomic64_read(&ci->i_release_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) atomic64_read(&ci->i_ordered_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) wake = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dout(" %p got snap_caps %s\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ceph_cap_string(info_caps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ci->i_snap_caps |= info_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (iinfo->inline_version > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) iinfo->inline_version >= ci->i_inline_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ci->i_inline_version = iinfo->inline_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (ci->i_inline_version != CEPH_INLINE_NONE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) (locked_page || (info_caps & cache_caps)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) fill_inline = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (cap_fmode >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!info_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) pr_warn("mds issued no caps on %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) ceph_vinop(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) __ceph_touch_fmode(ci, mdsc, cap_fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (fill_inline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) ceph_fill_inline_data(inode, locked_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) iinfo->inline_data, iinfo->inline_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (wake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) wake_up_all(&ci->i_cap_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /* queue truncate if we saw i_size decrease */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (queue_trunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) ceph_queue_vmtruncate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* populate frag tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ceph_fill_fragtree(inode, &info->fragtree, dirinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /* update delegation info? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (dirinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ceph_fill_dirfrag(inode, dirinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (new_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) ceph_put_cap(mdsc, new_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) ceph_buffer_put(old_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) ceph_buffer_put(xattr_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) ceph_put_string(pool_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * caller should hold session s_mutex and dentry->d_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void __update_dentry_lease(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct ceph_mds_reply_lease *lease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct ceph_mds_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) unsigned long from_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct ceph_mds_session **old_lease_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct ceph_dentry_info *di = ceph_dentry(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) unsigned mask = le16_to_cpu(lease->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) long unsigned duration = le32_to_cpu(lease->duration_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) long unsigned ttl = from_time + (duration * HZ) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) long unsigned half_ttl = from_time + (duration * HZ / 2) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) dout("update_dentry_lease %p duration %lu ms ttl %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) dentry, duration, ttl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* only track leases on regular dentries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (ceph_snap(dir) != CEPH_NOSNAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (mask & CEPH_LEASE_PRIMARY_LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) di->flags |= CEPH_DENTRY_PRIMARY_LINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) di->flags &= ~CEPH_DENTRY_PRIMARY_LINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) di->lease_shared_gen = atomic_read(&ceph_inode(dir)->i_shared_gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!(mask & CEPH_LEASE_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) __ceph_dentry_dir_lease_touch(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (di->lease_gen == session->s_cap_gen &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) time_before(ttl, di->time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return; /* we already have a newer lease. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (di->lease_session && di->lease_session != session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) *old_lease_session = di->lease_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) di->lease_session = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (!di->lease_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) di->lease_session = ceph_get_mds_session(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) di->lease_gen = session->s_cap_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) di->lease_seq = le32_to_cpu(lease->seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) di->lease_renew_after = half_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) di->lease_renew_from = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) di->time = ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) __ceph_dentry_lease_touch(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static inline void update_dentry_lease(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) struct ceph_mds_reply_lease *lease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct ceph_mds_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) unsigned long from_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct ceph_mds_session *old_lease_session = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) __update_dentry_lease(dir, dentry, lease, session, from_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) &old_lease_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ceph_put_mds_session(old_lease_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * update dentry lease without having parent inode locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static void update_dentry_lease_careful(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct ceph_mds_reply_lease *lease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct ceph_mds_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) unsigned long from_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) char *dname, u32 dname_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) struct ceph_vino *pdvino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct ceph_vino *ptvino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct inode *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct ceph_mds_session *old_lease_session = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /* make sure dentry's name matches target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (dentry->d_name.len != dname_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) memcmp(dentry->d_name.name, dname, dname_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dir = d_inode(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /* make sure parent matches dvino */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!ceph_ino_compare(dir, pdvino))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* make sure dentry's inode matches target. NULL ptvino means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * we expect a negative dentry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (ptvino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (d_really_is_negative(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (!ceph_ino_compare(d_inode(dentry), ptvino))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) __update_dentry_lease(dir, dentry, lease, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) from_time, &old_lease_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ceph_put_mds_session(old_lease_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * splice a dentry to an inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * caller must hold directory i_mutex for this to be safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static int splice_dentry(struct dentry **pdn, struct inode *in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct dentry *dn = *pdn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct dentry *realdn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) BUG_ON(d_inode(dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (S_ISDIR(in->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /* If inode is directory, d_splice_alias() below will remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * 'realdn' from its origin parent. We need to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * origin parent's readdir cache will not reference 'realdn'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) realdn = d_find_any_alias(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (realdn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) struct ceph_dentry_info *di = ceph_dentry(realdn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) spin_lock(&realdn->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) realdn->d_op->d_prune(realdn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) di->time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) di->lease_shared_gen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) di->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) spin_unlock(&realdn->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dput(realdn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* dn must be unhashed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!d_unhashed(dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) d_drop(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) realdn = d_splice_alias(in, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (IS_ERR(realdn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) PTR_ERR(realdn), dn, in, ceph_vinop(in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return PTR_ERR(realdn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (realdn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) dout("dn %p (%d) spliced with %p (%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) "inode %p ino %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dn, d_count(dn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) realdn, d_count(realdn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) d_inode(realdn), ceph_vinop(d_inode(realdn)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) dput(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) *pdn = realdn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) BUG_ON(!ceph_dentry(dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) dout("dn %p attached to %p ino %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dn, d_inode(dn), ceph_vinop(d_inode(dn)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Incorporate results into the local cache. This is either just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * one inode, or a directory, dentry, and possibly linked-to inode (e.g.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * after a lookup).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * A reply may contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * a directory inode along with a dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * and/or a target inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * Called with snap_rwsem (read).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct ceph_mds_session *session = req->r_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) struct inode *in = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct ceph_vino tvino, dvino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) dout("fill_trace %p is_dentry %d is_target %d\n", req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) rinfo->head->is_dentry, rinfo->head->is_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (!rinfo->head->is_target && !rinfo->head->is_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dout("fill_trace reply is empty!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (rinfo->head->result == 0 && req->r_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ceph_invalidate_dir_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (rinfo->head->is_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct inode *dir = req->r_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) err = ceph_fill_inode(dir, NULL, &rinfo->diri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) rinfo->dirfrag, session, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) &req->r_caps_reservation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct qstr dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct dentry *dn, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) BUG_ON(!rinfo->head->is_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) BUG_ON(req->r_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) parent = d_find_any_alias(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) BUG_ON(!parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) dname.name = rinfo->dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) dname.len = rinfo->dname_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) dname.hash = full_name_hash(parent, dname.name, dname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) tvino.ino = le64_to_cpu(rinfo->targeti.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) tvino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) retry_lookup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) dn = d_lookup(parent, &dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) dout("d_lookup on parent=%p name=%.*s got %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) parent, dname.len, dname.name, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (!dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) dn = d_alloc(parent, &dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dout("d_alloc %p '%.*s' = %p\n", parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) dname.len, dname.name, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (!dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) } else if (d_really_is_positive(dn) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) (ceph_ino(d_inode(dn)) != tvino.ino ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ceph_snap(d_inode(dn)) != tvino.snap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) dout(" dn %p points to wrong inode %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) dn, d_inode(dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ceph_dir_clear_ordered(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) d_delete(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) dput(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) goto retry_lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) req->r_dentry = dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (rinfo->head->is_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) tvino.ino = le64_to_cpu(rinfo->targeti.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) tvino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) in = ceph_get_inode(sb, tvino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (IS_ERR(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) err = PTR_ERR(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) err = ceph_fill_inode(in, req->r_locked_page, &rinfo->targeti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) NULL, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) (!test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) !test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) rinfo->head->result == 0) ? req->r_fmode : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) &req->r_caps_reservation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) pr_err("ceph_fill_inode badness %p %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) in, ceph_vinop(in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (in->i_state & I_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) discard_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) iput(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) req->r_target_inode = in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (in->i_state & I_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) unlock_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * ignore null lease/binding on snapdir ENOENT, or else we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * will have trouble splicing in the virtual snapdir later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (rinfo->head->is_dentry &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) fsc->mount_options->snapdir_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) req->r_dentry->d_name.len))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) * lookup link rename : null -> possibly existing inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * mknod symlink mkdir : null -> new inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * unlink : linked -> null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct inode *dir = req->r_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct dentry *dn = req->r_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) bool have_dir_cap, have_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) BUG_ON(!dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) BUG_ON(!dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) BUG_ON(d_inode(dn->d_parent) != dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dvino.ino = le64_to_cpu(rinfo->diri.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dvino.snap = le64_to_cpu(rinfo->diri.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) BUG_ON(ceph_ino(dir) != dvino.ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) BUG_ON(ceph_snap(dir) != dvino.snap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /* do we have a lease on the whole dir? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) have_dir_cap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) (le32_to_cpu(rinfo->diri.in->cap.caps) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) CEPH_CAP_FILE_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) /* do we have a dn lease? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) have_lease = have_dir_cap ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) le32_to_cpu(rinfo->dlease->duration_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (!have_lease)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) dout("fill_trace no dentry lease or dir cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* rename? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct inode *olddir = req->r_old_dentry_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) BUG_ON(!olddir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) dout(" src %p '%pd' dst %p '%pd'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) req->r_old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) req->r_old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) dn, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dout("fill_trace doing d_move %p -> %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) req->r_old_dentry, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /* d_move screws up sibling dentries' offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ceph_dir_clear_ordered(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) ceph_dir_clear_ordered(olddir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) d_move(req->r_old_dentry, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) dout(" src %p '%pd' dst %p '%pd'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) req->r_old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) req->r_old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) dn, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* ensure target dentry is invalidated, despite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) rehashing bug in vfs_rename_dir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ceph_invalidate_dentry_lease(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) dout("dn %p gets new offset %lld\n", req->r_old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) ceph_dentry(req->r_old_dentry)->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* swap r_dentry and r_old_dentry in case that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) * splice_dentry() gets called later. This is safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * because no other place will use them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) req->r_dentry = req->r_old_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) req->r_old_dentry = dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) dn = req->r_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) /* null dentry? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (!rinfo->head->is_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) dout("fill_trace null dentry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (d_really_is_positive(dn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) dout("d_delete %p\n", dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) ceph_dir_clear_ordered(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) d_delete(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) } else if (have_lease) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (d_unhashed(dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) d_add(dn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) update_dentry_lease(dir, dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) rinfo->dlease, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) req->r_request_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* attach proper inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (d_really_is_negative(dn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) ceph_dir_clear_ordered(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ihold(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) err = splice_dentry(&req->r_dentry, in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) dn = req->r_dentry; /* may have spliced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) } else if (d_really_is_positive(dn) && d_inode(dn) != in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) dn, d_inode(dn), ceph_vinop(d_inode(dn)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) ceph_vinop(in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) d_invalidate(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) have_lease = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (have_lease) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) update_dentry_lease(dir, dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) rinfo->dlease, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) req->r_request_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) dout(" final dn %p\n", dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) } else if ((req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) req->r_op == CEPH_MDS_OP_MKSNAP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct inode *dir = req->r_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* fill out a snapdir LOOKUPSNAP dentry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) BUG_ON(!dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) BUG_ON(ceph_snap(dir) != CEPH_SNAPDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) BUG_ON(!req->r_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) dout(" linking snapped dir %p to dn %p\n", in, req->r_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) ceph_dir_clear_ordered(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) ihold(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) err = splice_dentry(&req->r_dentry, in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) } else if (rinfo->head->is_dentry && req->r_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* parent inode is not locked, be carefull */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct ceph_vino *ptvino = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) dvino.ino = le64_to_cpu(rinfo->diri.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) dvino.snap = le64_to_cpu(rinfo->diri.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (rinfo->head->is_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) tvino.ino = le64_to_cpu(rinfo->targeti.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) tvino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ptvino = &tvino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) update_dentry_lease_careful(req->r_dentry, rinfo->dlease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) session, req->r_request_started,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) rinfo->dname, rinfo->dname_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) &dvino, ptvino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) dout("fill_trace done err=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * Prepopulate our cache with readdir results, leases, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct ceph_mds_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) for (i = 0; i < rinfo->dir_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct ceph_vino vino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct inode *in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) vino.ino = le64_to_cpu(rde->inode.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) vino.snap = le64_to_cpu(rde->inode.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) in = ceph_get_inode(req->r_dentry->d_sb, vino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (IS_ERR(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) err = PTR_ERR(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) dout("new_inode badness got %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) rc = ceph_fill_inode(in, NULL, &rde->inode, NULL, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) -1, &req->r_caps_reservation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) pr_err("ceph_fill_inode badness on %p got %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) in, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (in->i_state & I_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) ihold(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) discard_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) } else if (in->i_state & I_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) unlock_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /* avoid calling iput_final() in mds dispatch threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ceph_async_iput(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) void ceph_readdir_cache_release(struct ceph_readdir_cache_control *ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (ctl->page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) kunmap(ctl->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) put_page(ctl->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ctl->page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static int fill_readdir_cache(struct inode *dir, struct dentry *dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct ceph_readdir_cache_control *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct ceph_mds_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) struct ceph_inode_info *ci = ceph_inode(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) unsigned nsize = PAGE_SIZE / sizeof(struct dentry*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) unsigned idx = ctl->index % nsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) pgoff_t pgoff = ctl->index / nsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (!ctl->page || pgoff != page_index(ctl->page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) ceph_readdir_cache_release(ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) ctl->page = grab_cache_page(&dir->i_data, pgoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) ctl->page = find_lock_page(&dir->i_data, pgoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (!ctl->page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) ctl->index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return idx == 0 ? -ENOMEM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* reading/filling the cache are serialized by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * i_mutex, no need to use page lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) unlock_page(ctl->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ctl->dentries = kmap(ctl->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) memset(ctl->dentries, 0, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (req->r_dir_release_cnt == atomic64_read(&ci->i_release_count) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) req->r_dir_ordered_cnt == atomic64_read(&ci->i_ordered_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) dout("readdir cache dn %p idx %d\n", dn, ctl->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) ctl->dentries[idx] = dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) ctl->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) dout("disable readdir cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ctl->index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int ceph_readdir_prepopulate(struct ceph_mds_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) struct ceph_mds_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) struct dentry *parent = req->r_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) struct ceph_inode_info *ci = ceph_inode(d_inode(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct qstr dname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) struct dentry *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct inode *in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) int err = 0, skipped = 0, ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) u32 frag = le32_to_cpu(rhead->args.readdir.frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) u32 last_hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) u32 fpos_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct ceph_readdir_cache_control cache_ctl = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return readdir_prepopulate_inodes_only(req, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (rinfo->hash_order) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (req->r_path2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) last_hash = ceph_str_hash(ci->i_dir_layout.dl_dir_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) req->r_path2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) strlen(req->r_path2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) last_hash = ceph_frag_value(last_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) } else if (rinfo->offset_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) /* mds understands offset_hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) WARN_ON_ONCE(req->r_readdir_offset != 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) last_hash = le32_to_cpu(rhead->args.readdir.offset_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (rinfo->dir_dir &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) le32_to_cpu(rinfo->dir_dir->frag) != frag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) dout("readdir_prepopulate got new frag %x -> %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) frag, le32_to_cpu(rinfo->dir_dir->frag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) frag = le32_to_cpu(rinfo->dir_dir->frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (!rinfo->hash_order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) req->r_readdir_offset = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) dout("readdir_prepopulate %d items under SNAPDIR dn %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) rinfo->dir_nr, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) dout("readdir_prepopulate %d items under dn %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) rinfo->dir_nr, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (rinfo->dir_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ceph_fill_dirfrag(d_inode(parent), rinfo->dir_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (ceph_frag_is_leftmost(frag) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) req->r_readdir_offset == 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) !(rinfo->hash_order && last_hash)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* note dir version at start of readdir so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * tell if any dentries get dropped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) req->r_dir_release_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) atomic64_read(&ci->i_release_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) req->r_dir_ordered_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) atomic64_read(&ci->i_ordered_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) req->r_readdir_cache_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) cache_ctl.index = req->r_readdir_cache_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) fpos_offset = req->r_readdir_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) /* FIXME: release caps/leases if error occurs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) for (i = 0; i < rinfo->dir_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct ceph_vino tvino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) dname.name = rde->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) dname.len = rde->name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) dname.hash = full_name_hash(parent, dname.name, dname.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) tvino.ino = le64_to_cpu(rde->inode.in->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) tvino.snap = le64_to_cpu(rde->inode.in->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (rinfo->hash_order) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) u32 hash = ceph_str_hash(ci->i_dir_layout.dl_dir_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) rde->name, rde->name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) hash = ceph_frag_value(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (hash != last_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) fpos_offset = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) last_hash = hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) rde->offset = ceph_make_fpos(hash, fpos_offset++, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) rde->offset = ceph_make_fpos(frag, fpos_offset++, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) retry_lookup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dn = d_lookup(parent, &dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) dout("d_lookup on parent=%p name=%.*s got %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) parent, dname.len, dname.name, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (!dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) dn = d_alloc(parent, &dname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) dout("d_alloc %p '%.*s' = %p\n", parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) dname.len, dname.name, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (!dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) dout("d_alloc badness\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) } else if (d_really_is_positive(dn) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) (ceph_ino(d_inode(dn)) != tvino.ino ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) ceph_snap(d_inode(dn)) != tvino.snap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct ceph_dentry_info *di = ceph_dentry(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) dout(" dn %p points to wrong inode %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) dn, d_inode(dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) spin_lock(&dn->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (di->offset > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) di->lease_shared_gen ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) atomic_read(&ci->i_shared_gen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) __ceph_dir_clear_ordered(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) di->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) spin_unlock(&dn->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) d_delete(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) dput(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) goto retry_lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /* inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (d_really_is_positive(dn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) in = d_inode(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) in = ceph_get_inode(parent->d_sb, tvino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (IS_ERR(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) dout("new_inode badness\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) d_drop(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) dput(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) err = PTR_ERR(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) ret = ceph_fill_inode(in, NULL, &rde->inode, NULL, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) -1, &req->r_caps_reservation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) pr_err("ceph_fill_inode badness on %p\n", in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (d_really_is_negative(dn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) /* avoid calling iput_final() in mds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * dispatch threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (in->i_state & I_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) ihold(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) discard_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) ceph_async_iput(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) d_drop(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) goto next_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (in->i_state & I_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) unlock_new_inode(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (d_really_is_negative(dn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) if (ceph_security_xattr_deadlock(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) dout(" skip splicing dn %p to inode %p"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) " (security xattr deadlock)\n", dn, in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) ceph_async_iput(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) skipped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) goto next_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) err = splice_dentry(&dn, in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) goto next_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) ceph_dentry(dn)->offset = rde->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) update_dentry_lease(d_inode(parent), dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) rde->lease, req->r_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) req->r_request_started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (err == 0 && skipped == 0 && cache_ctl.index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) ret = fill_readdir_cache(d_inode(parent), dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) &cache_ctl, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) next_item:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) dput(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (err == 0 && skipped == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) set_bit(CEPH_MDS_R_DID_PREPOPULATE, &req->r_req_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) req->r_readdir_cache_idx = cache_ctl.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) ceph_readdir_cache_release(&cache_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) dout("readdir_prepopulate done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) bool ceph_inode_set_size(struct inode *inode, loff_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) i_size_write(inode, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) inode->i_blocks = calc_inode_blocks(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) ret = __ceph_should_report_size(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * Put reference to inode, but avoid calling iput_final() in current thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) * iput_final() may wait for reahahead pages. The wait can cause deadlock in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) * some contexts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) void ceph_async_iput(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (atomic_add_unless(&inode->i_count, -1, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (queue_work(ceph_inode_to_client(inode)->inode_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) &ceph_inode(inode)->i_work))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) /* queue work failed, i_count must be at least 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) * Write back inode data in a worker thread. (This can't be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * in the message handler context.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) void ceph_queue_writeback(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) set_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (queue_work(ceph_inode_to_client(inode)->inode_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) &ci->i_work)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) dout("ceph_queue_writeback %p\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) dout("ceph_queue_writeback %p already queued, mask=%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) inode, ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * queue an async invalidation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) void ceph_queue_invalidate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) set_bit(CEPH_I_WORK_INVALIDATE_PAGES, &ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) if (queue_work(ceph_inode_to_client(inode)->inode_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) &ceph_inode(inode)->i_work)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) dout("ceph_queue_invalidate %p\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) dout("ceph_queue_invalidate %p already queued, mask=%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) inode, ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * Queue an async vmtruncate. If we fail to queue work, we will handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) * the truncation the next time we call __ceph_do_pending_vmtruncate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) void ceph_queue_vmtruncate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) set_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) if (queue_work(ceph_inode_to_client(inode)->inode_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) &ci->i_work)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) dout("ceph_queue_vmtruncate %p\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) dout("ceph_queue_vmtruncate %p already queued, mask=%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) inode, ci->i_work_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static void ceph_do_invalidate_pages(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) u32 orig_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) int check = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) mutex_lock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) pr_warn_ratelimited("invalidate_pages %p %lld forced umount\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) inode, ceph_ino(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) mapping_set_error(inode->i_mapping, -EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) truncate_pagecache(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) mutex_unlock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) dout("invalidate_pages %p gen %d revoking %d\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) ci->i_rdcache_gen, ci->i_rdcache_revoking);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (__ceph_caps_revoking_other(ci, NULL, CEPH_CAP_FILE_CACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) check = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) mutex_unlock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) orig_gen = ci->i_rdcache_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) ceph_fscache_invalidate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (invalidate_inode_pages2(inode->i_mapping) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) pr_err("invalidate_pages %p fails\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (orig_gen == ci->i_rdcache_gen &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) orig_gen == ci->i_rdcache_revoking) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) dout("invalidate_pages %p gen %d successful\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) ci->i_rdcache_gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) ci->i_rdcache_revoking--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) check = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) dout("invalidate_pages %p gen %d raced, now %d revoking %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) inode, orig_gen, ci->i_rdcache_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) ci->i_rdcache_revoking);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (__ceph_caps_revoking_other(ci, NULL, CEPH_CAP_FILE_CACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) check = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) mutex_unlock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) ceph_check_caps(ci, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) * Make sure any pending truncation is applied before doing anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) * that may depend on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) void __ceph_do_pending_vmtruncate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) u64 to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) int wrbuffer_refs, finish = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) mutex_lock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (ci->i_truncate_pending == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) dout("__do_pending_vmtruncate %p none pending\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) mutex_unlock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * make sure any dirty snapped pages are flushed before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) * possibly truncate them.. so write AND block!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) dout("__do_pending_vmtruncate %p flushing snaps first\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) filemap_write_and_wait_range(&inode->i_data, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) inode->i_sb->s_maxbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) /* there should be no reader or writer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) WARN_ON_ONCE(ci->i_rd_ref || ci->i_wr_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) to = ci->i_truncate_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) wrbuffer_refs = ci->i_wrbuffer_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) ci->i_truncate_pending, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) truncate_pagecache(inode, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (to == ci->i_truncate_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) ci->i_truncate_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) finish = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) if (!finish)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) mutex_unlock(&ci->i_truncate_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) if (wrbuffer_refs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ceph_check_caps(ci, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) wake_up_all(&ci->i_cap_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static void ceph_inode_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) i_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) struct inode *inode = &ci->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (test_and_clear_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) dout("writeback %p\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) filemap_fdatawrite(&inode->i_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (test_and_clear_bit(CEPH_I_WORK_INVALIDATE_PAGES, &ci->i_work_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) ceph_do_invalidate_pages(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (test_and_clear_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) __ceph_do_pending_vmtruncate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) * symlinks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) static const struct inode_operations ceph_symlink_iops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) .get_link = simple_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) .setattr = ceph_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) .getattr = ceph_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) .listxattr = ceph_listxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) int __ceph_setattr(struct inode *inode, struct iattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) unsigned int ia_valid = attr->ia_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) struct ceph_mds_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) struct ceph_cap_flush *prealloc_cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) int issued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) int release = 0, dirtied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) int inode_dirty_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) bool lock_snap_rwsem = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) prealloc_cf = ceph_alloc_cap_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (!prealloc_cf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) USE_AUTH_MDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (IS_ERR(req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) ceph_free_cap_flush(prealloc_cf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) issued = __ceph_caps_issued(ci, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (!ci->i_head_snapc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) (issued & (CEPH_CAP_ANY_EXCL | CEPH_CAP_FILE_WR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) lock_snap_rwsem = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (!down_read_trylock(&mdsc->snap_rwsem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) down_read(&mdsc->snap_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) issued = __ceph_caps_issued(ci, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) dout("setattr %p issued %s\n", inode, ceph_cap_string(issued));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (ia_valid & ATTR_UID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) dout("setattr %p uid %d -> %d\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) from_kuid(&init_user_ns, inode->i_uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) from_kuid(&init_user_ns, attr->ia_uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (issued & CEPH_CAP_AUTH_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) inode->i_uid = attr->ia_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) dirtied |= CEPH_CAP_AUTH_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) !uid_eq(attr->ia_uid, inode->i_uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) req->r_args.setattr.uid = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) from_kuid(&init_user_ns, attr->ia_uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) mask |= CEPH_SETATTR_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) release |= CEPH_CAP_AUTH_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if (ia_valid & ATTR_GID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) dout("setattr %p gid %d -> %d\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) from_kgid(&init_user_ns, inode->i_gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) from_kgid(&init_user_ns, attr->ia_gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (issued & CEPH_CAP_AUTH_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) inode->i_gid = attr->ia_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) dirtied |= CEPH_CAP_AUTH_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) !gid_eq(attr->ia_gid, inode->i_gid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) req->r_args.setattr.gid = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) from_kgid(&init_user_ns, attr->ia_gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) mask |= CEPH_SETATTR_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) release |= CEPH_CAP_AUTH_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) if (ia_valid & ATTR_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) dout("setattr %p mode 0%o -> 0%o\n", inode, inode->i_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) attr->ia_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (issued & CEPH_CAP_AUTH_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) inode->i_mode = attr->ia_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) dirtied |= CEPH_CAP_AUTH_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) attr->ia_mode != inode->i_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) inode->i_mode = attr->ia_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) req->r_args.setattr.mode = cpu_to_le32(attr->ia_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) mask |= CEPH_SETATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) release |= CEPH_CAP_AUTH_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (ia_valid & ATTR_ATIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) dout("setattr %p atime %lld.%ld -> %lld.%ld\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (issued & CEPH_CAP_FILE_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) ci->i_time_warp_seq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) inode->i_atime = attr->ia_atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) dirtied |= CEPH_CAP_FILE_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) } else if ((issued & CEPH_CAP_FILE_WR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) timespec64_compare(&inode->i_atime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) &attr->ia_atime) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) inode->i_atime = attr->ia_atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) dirtied |= CEPH_CAP_FILE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) !timespec64_equal(&inode->i_atime, &attr->ia_atime)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) ceph_encode_timespec64(&req->r_args.setattr.atime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) &attr->ia_atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) mask |= CEPH_SETATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) release |= CEPH_CAP_FILE_SHARED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (ia_valid & ATTR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) dout("setattr %p size %lld -> %lld\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) inode->i_size, attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if ((issued & CEPH_CAP_FILE_EXCL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) attr->ia_size > inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) i_size_write(inode, attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) inode->i_blocks = calc_inode_blocks(attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ci->i_reported_size = attr->ia_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) dirtied |= CEPH_CAP_FILE_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) ia_valid |= ATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) attr->ia_size != inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) req->r_args.setattr.size = cpu_to_le64(attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) req->r_args.setattr.old_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) cpu_to_le64(inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) mask |= CEPH_SETATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (ia_valid & ATTR_MTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) dout("setattr %p mtime %lld.%ld -> %lld.%ld\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (issued & CEPH_CAP_FILE_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) ci->i_time_warp_seq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) inode->i_mtime = attr->ia_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) dirtied |= CEPH_CAP_FILE_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) } else if ((issued & CEPH_CAP_FILE_WR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) timespec64_compare(&inode->i_mtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) &attr->ia_mtime) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) inode->i_mtime = attr->ia_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) dirtied |= CEPH_CAP_FILE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) !timespec64_equal(&inode->i_mtime, &attr->ia_mtime)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) ceph_encode_timespec64(&req->r_args.setattr.mtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) &attr->ia_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) mask |= CEPH_SETATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) release |= CEPH_CAP_FILE_SHARED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) /* these do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (ia_valid & ATTR_CTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) dout("setattr %p ctime %lld.%ld -> %lld.%ld (%s)\n", inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) only ? "ctime only" : "ignored");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if (only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * if kernel wants to dirty ctime but nothing else,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) * we need to choose a cap to dirty under, or do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) * a almost-no-op setattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (issued & CEPH_CAP_AUTH_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) dirtied |= CEPH_CAP_AUTH_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) else if (issued & CEPH_CAP_FILE_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) dirtied |= CEPH_CAP_FILE_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) else if (issued & CEPH_CAP_XATTR_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) dirtied |= CEPH_CAP_XATTR_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) mask |= CEPH_SETATTR_CTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (ia_valid & ATTR_FILE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) dout("setattr %p ATTR_FILE ... hrm!\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if (dirtied) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) &prealloc_cf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) inode->i_ctime = attr->ia_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) release &= issued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (lock_snap_rwsem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) up_read(&mdsc->snap_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (inode_dirty_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) __mark_inode_dirty(inode, inode_dirty_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) req->r_inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) req->r_inode_drop = release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) req->r_args.setattr.mask = cpu_to_le32(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) req->r_num_caps = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) req->r_stamp = attr->ia_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) err = ceph_mdsc_do_request(mdsc, NULL, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) ceph_cap_string(dirtied), mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) ceph_mdsc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) ceph_free_cap_flush(prealloc_cf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (err >= 0 && (mask & CEPH_SETATTR_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) __ceph_do_pending_vmtruncate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) * setattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) int ceph_setattr(struct dentry *dentry, struct iattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) if (ceph_snap(inode) != CEPH_NOSNAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) return -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) err = setattr_prepare(dentry, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) if ((attr->ia_valid & ATTR_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) attr->ia_size > max(inode->i_size, fsc->max_file_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if ((attr->ia_valid & ATTR_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return -EDQUOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) err = __ceph_setattr(inode, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if (err >= 0 && (attr->ia_valid & ATTR_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) err = posix_acl_chmod(inode, attr->ia_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * Verify that we have a lease on the given mask. If not,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) * do a getattr against an mds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) int mask, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) struct ceph_mds_client *mdsc = fsc->mdsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) struct ceph_mds_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (ceph_snap(inode) == CEPH_SNAPDIR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) dout("do_getattr inode %p SNAPDIR\n", inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) dout("do_getattr inode %p mask %s mode 0%o\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) inode, ceph_cap_string(mask), inode->i_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (!force && ceph_caps_issued_mask_metric(ceph_inode(inode), mask, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) mode = (mask & CEPH_STAT_RSTAT) ? USE_AUTH_MDS : USE_ANY_MDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) req->r_inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) req->r_num_caps = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) req->r_args.getattr.mask = cpu_to_le32(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) req->r_locked_page = locked_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) err = ceph_mdsc_do_request(mdsc, NULL, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (locked_page && err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) u64 inline_version = req->r_reply_info.targeti.inline_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (inline_version == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) /* the reply is supposed to contain inline data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) } else if (inline_version == CEPH_INLINE_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) err = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) err = req->r_reply_info.targeti.inline_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) ceph_mdsc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) dout("do_getattr result=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * Check inode permissions. We verify we have a valid value for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) * the AUTH cap, then call the generic handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) int ceph_permission(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (mask & MAY_NOT_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) err = generic_permission(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) /* Craft a mask of needed caps given a set of requested statx attrs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) static int statx_to_caps(u32 want)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (want & (STATX_MODE|STATX_UID|STATX_GID|STATX_CTIME|STATX_BTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) mask |= CEPH_CAP_AUTH_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) if (want & (STATX_NLINK|STATX_CTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) mask |= CEPH_CAP_LINK_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (want & (STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_SIZE|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) STATX_BLOCKS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) mask |= CEPH_CAP_FILE_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (want & (STATX_CTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) mask |= CEPH_CAP_XATTR_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) * Get all the attributes. If we have sufficient caps for the requested attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) * then we can avoid talking to the MDS at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) int ceph_getattr(const struct path *path, struct kstat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) u32 request_mask, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) struct inode *inode = d_inode(path->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) u32 valid_mask = STATX_BASIC_STATS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) /* Skip the getattr altogether if we're asked not to sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) if (!(flags & AT_STATX_DONT_SYNC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) err = ceph_do_getattr(inode, statx_to_caps(request_mask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) flags & AT_STATX_FORCE_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) generic_fillattr(inode, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) stat->ino = ceph_present_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) * btime on newly-allocated inodes is 0, so if this is still set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) * that, then assume that it's not valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) if (ci->i_btime.tv_sec || ci->i_btime.tv_nsec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) stat->btime = ci->i_btime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) valid_mask |= STATX_BTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) if (ceph_snap(inode) == CEPH_NOSNAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) stat->dev = inode->i_sb->s_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) stat->dev = ci->i_snapid_map ? ci->i_snapid_map->dev : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) RBYTES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) stat->size = ci->i_rbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) stat->size = ci->i_files + ci->i_subdirs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) stat->blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) stat->blksize = 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) * Some applications rely on the number of st_nlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) * value on directories to be either 0 (if unlinked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) * or 2 + number of subdirectories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) if (stat->nlink == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /* '.' + '..' + subdirs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) stat->nlink = 1 + 1 + ci->i_subdirs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) stat->result_mask = request_mask & valid_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }