1/* 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4 * 5 * This copyrighted material is made available to anyone wishing to use, 6 * modify, copy, or redistribute it subject to the terms and conditions 7 * of the GNU General Public License version 2. 8 */ 9 10#include <linux/slab.h> 11#include <linux/spinlock.h> 12#include <linux/completion.h> 13#include <linux/buffer_head.h> 14#include <linux/gfs2_ondisk.h> 15#include <linux/crc32.h> 16#include <linux/lm_interface.h> 17 18#include "gfs2.h" 19#include "incore.h" 20#include "dir.h" 21#include "glock.h" 22#include "glops.h" 23#include "inode.h" 24#include "ops_dentry.h" 25#include "ops_export.h" 26#include "rgrp.h" 27#include "util.h" 28 29static struct dentry *gfs2_decode_fh(struct super_block *sb, 30 __u32 *p, 31 int fh_len, 32 int fh_type, 33 int (*acceptable)(void *context, 34 struct dentry *dentry), 35 void *context) 36{ 37 __be32 *fh = (__force __be32 *)p; 38 struct gfs2_fh_obj fh_obj; 39 struct gfs2_inum_host *this, parent; 40 41 this = &fh_obj.this; 42 fh_obj.imode = DT_UNKNOWN; 43 memset(&parent, 0, sizeof(struct gfs2_inum)); 44 45 switch (fh_len) { 46 case GFS2_LARGE_FH_SIZE: 47 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; 48 parent.no_formal_ino |= be32_to_cpu(fh[5]); 49 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; 50 parent.no_addr |= be32_to_cpu(fh[7]); 51 fh_obj.imode = be32_to_cpu(fh[8]); 52 case GFS2_SMALL_FH_SIZE: 53 this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; 54 this->no_formal_ino |= be32_to_cpu(fh[1]); 55 this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; 56 this->no_addr |= be32_to_cpu(fh[3]); 57 break; 58 default: 59 return NULL; 60 } 61 62 return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, 63 acceptable, context); 64} 65 66static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, 67 int connectable) 68{ 69 __be32 *fh = (__force __be32 *)p; 70 struct inode *inode = dentry->d_inode; 71 struct super_block *sb = inode->i_sb; 72 struct gfs2_inode *ip = GFS2_I(inode); 73 74 if (*len < GFS2_SMALL_FH_SIZE || 75 (connectable && *len < GFS2_LARGE_FH_SIZE)) 76 return 255; 77 78 fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); 79 fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); 80 fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); 81 fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); 82 *len = GFS2_SMALL_FH_SIZE; 83 84 if (!connectable || inode == sb->s_root->d_inode) 85 return *len; 86 87 spin_lock(&dentry->d_lock); 88 inode = dentry->d_parent->d_inode; 89 ip = GFS2_I(inode); 90 igrab(inode); 91 spin_unlock(&dentry->d_lock); 92 93 fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); 94 fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); 95 fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); 96 fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); 97 98 fh[8] = cpu_to_be32(inode->i_mode); 99 fh[9] = 0; /* pad to double word */ 100 *len = GFS2_LARGE_FH_SIZE; 101 102 iput(inode); 103 104 return *len; 105} 106 107struct get_name_filldir { 108 struct gfs2_inum_host inum; 109 char *name; 110}; 111 112static int get_name_filldir(void *opaque, const char *name, int length, 113 loff_t offset, u64 inum, unsigned int type) 114{ 115 struct get_name_filldir *gnfd = opaque; 116 117 if (inum != gnfd->inum.no_addr) 118 return 0; 119 120 memcpy(gnfd->name, name, length); 121 gnfd->name[length] = 0; 122 123 return 1; 124} 125 126static int gfs2_get_name(struct dentry *parent, char *name, 127 struct dentry *child) 128{ 129 struct inode *dir = parent->d_inode; 130 struct inode *inode = child->d_inode; 131 struct gfs2_inode *dip, *ip; 132 struct get_name_filldir gnfd; 133 struct gfs2_holder gh; 134 u64 offset = 0; 135 int error; 136 137 if (!dir) 138 return -EINVAL; 139 140 if (!S_ISDIR(dir->i_mode) || !inode) 141 return -EINVAL; 142 143 dip = GFS2_I(dir); 144 ip = GFS2_I(inode); 145 146 *name = 0; 147 gnfd.inum = ip->i_num; 148 gnfd.name = name; 149 150 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); 151 if (error) 152 return error; 153 154 error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir); 155 156 gfs2_glock_dq_uninit(&gh); 157 158 if (!error && !*name) 159 error = -ENOENT; 160 161 return error; 162} 163 164static struct dentry *gfs2_get_parent(struct dentry *child) 165{ 166 struct qstr dotdot; 167 struct inode *inode; 168 struct dentry *dentry; 169 170 gfs2_str2qstr(&dotdot, ".."); 171 inode = gfs2_lookupi(child->d_inode, &dotdot, 1, NULL); 172 173 if (!inode) 174 return ERR_PTR(-ENOENT); 175 /* 176 * In case of an error, @inode carries the error value, and we 177 * have to return that as a(n invalid) pointer to dentry. 178 */ 179 if (IS_ERR(inode)) 180 return ERR_PTR(PTR_ERR(inode)); 181 182 dentry = d_alloc_anon(inode); 183 if (!dentry) { 184 iput(inode); 185 return ERR_PTR(-ENOMEM); 186 } 187 188 dentry->d_op = &gfs2_dops; 189 return dentry; 190} 191 192static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) 193{ 194 struct gfs2_sbd *sdp = sb->s_fs_info; 195 struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; 196 struct gfs2_inum_host *inum = &fh_obj->this; 197 struct gfs2_holder i_gh, ri_gh, rgd_gh; 198 struct gfs2_rgrpd *rgd; 199 struct inode *inode; 200 struct dentry *dentry; 201 int error; 202 203 /* System files? */ 204 205 inode = gfs2_ilookup(sb, inum); 206 if (inode) { 207 if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { 208 iput(inode); 209 return ERR_PTR(-ESTALE); 210 } 211 goto out_inode; 212 } 213 214 error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops, 215 LM_ST_SHARED, LM_FLAG_ANY, &i_gh); 216 if (error) 217 return ERR_PTR(error); 218 219 error = gfs2_rindex_hold(sdp, &ri_gh); 220 if (error) 221 goto fail; 222 223 error = -EINVAL; 224 rgd = gfs2_blk2rgrpd(sdp, inum->no_addr); 225 if (!rgd) 226 goto fail_rindex; 227 228 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); 229 if (error) 230 goto fail_rindex; 231 232 error = -ESTALE; 233 if (gfs2_get_block_type(rgd, inum->no_addr) != GFS2_BLKST_DINODE) 234 goto fail_rgd; 235 236 gfs2_glock_dq_uninit(&rgd_gh); 237 gfs2_glock_dq_uninit(&ri_gh); 238 239 inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); 240 if (!inode) 241 goto fail; 242 if (IS_ERR(inode)) { 243 error = PTR_ERR(inode); 244 goto fail; 245 } 246 247 error = gfs2_inode_refresh(GFS2_I(inode)); 248 if (error) { 249 iput(inode); 250 goto fail; 251 } 252 253 error = -EIO; 254 if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { 255 iput(inode); 256 goto fail; 257 } 258 259 gfs2_glock_dq_uninit(&i_gh); 260 261out_inode: 262 dentry = d_alloc_anon(inode); 263 if (!dentry) { 264 iput(inode); 265 return ERR_PTR(-ENOMEM); 266 } 267 268 dentry->d_op = &gfs2_dops; 269 return dentry; 270 271fail_rgd: 272 gfs2_glock_dq_uninit(&rgd_gh); 273 274fail_rindex: 275 gfs2_glock_dq_uninit(&ri_gh); 276 277fail: 278 gfs2_glock_dq_uninit(&i_gh); 279 return ERR_PTR(error); 280} 281 282struct export_operations gfs2_export_ops = { 283 .decode_fh = gfs2_decode_fh, 284 .encode_fh = gfs2_encode_fh, 285 .get_name = gfs2_get_name, 286 .get_parent = gfs2_get_parent, 287 .get_dentry = gfs2_get_dentry, 288}; 289