/* * Initialize ceph dentry state. */ int ceph_init_dentry(struct dentry *dentry) { struct ceph_dentry_info *di; if (dentry->d_fsdata) return 0; if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) dentry->d_op = &ceph_dentry_ops; else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) dentry->d_op = &ceph_snapdir_dentry_ops; else dentry->d_op = &ceph_snap_dentry_ops; di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO); if (!di) return -ENOMEM; /* oh well */ spin_lock(&dentry->d_lock); if (dentry->d_fsdata) { /* lost a race */ kmem_cache_free(ceph_dentry_cachep, di); goto out_unlock; } di->dentry = dentry; di->lease_session = NULL; dentry->d_fsdata = di; dentry->d_time = jiffies; ceph_dentry_lru_add(dentry); out_unlock: spin_unlock(&dentry->d_lock); return 0; }
/* * Initialize ceph dentry state. */ int ceph_init_dentry(struct dentry *dentry) { struct ceph_dentry_info *di; if (dentry->d_fsdata) return 0; di = kmem_cache_zalloc(ceph_dentry_cachep, GFP_KERNEL); if (!di) return -ENOMEM; /* oh well */ spin_lock(&dentry->d_lock); if (dentry->d_fsdata) { /* lost a race */ kmem_cache_free(ceph_dentry_cachep, di); goto out_unlock; } if (ceph_snap(d_inode(dentry->d_parent)) == CEPH_NOSNAP) d_set_d_op(dentry, &ceph_dentry_ops); else if (ceph_snap(d_inode(dentry->d_parent)) == CEPH_SNAPDIR) d_set_d_op(dentry, &ceph_snapdir_dentry_ops); else d_set_d_op(dentry, &ceph_snap_dentry_ops); di->dentry = dentry; di->lease_session = NULL; di->time = jiffies; /* avoid reordering d_fsdata setup so that the check above is safe */ smp_mb(); dentry->d_fsdata = di; ceph_dentry_lru_add(dentry); out_unlock: spin_unlock(&dentry->d_lock); return 0; }