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/exportfs.h> 15 #include <linux/gfs2_ondisk.h> 16 #include <linux/crc32.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 "super.h" 25 #include "rgrp.h" 26 #include "util.h" 27 28 #define GFS2_SMALL_FH_SIZE 4 29 #define GFS2_LARGE_FH_SIZE 8 30 #define GFS2_OLD_FH_SIZE 10 31 32 static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, 33 int connectable) 34 { 35 __be32 *fh = (__force __be32 *)p; 36 struct inode *inode = dentry->d_inode; 37 struct super_block *sb = inode->i_sb; 38 struct gfs2_inode *ip = GFS2_I(inode); 39 40 if (*len < GFS2_SMALL_FH_SIZE || 41 (connectable && *len < GFS2_LARGE_FH_SIZE)) 42 return 255; 43 44 fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); 45 fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); 46 fh[2] = cpu_to_be32(ip->i_no_addr >> 32); 47 fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 48 *len = GFS2_SMALL_FH_SIZE; 49 50 if (!connectable || inode == sb->s_root->d_inode) 51 return *len; 52 53 spin_lock(&dentry->d_lock); 54 inode = dentry->d_parent->d_inode; 55 ip = GFS2_I(inode); 56 igrab(inode); 57 spin_unlock(&dentry->d_lock); 58 59 fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); 60 fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); 61 fh[6] = cpu_to_be32(ip->i_no_addr >> 32); 62 fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); 63 *len = GFS2_LARGE_FH_SIZE; 64 65 iput(inode); 66 67 return *len; 68 } 69 70 struct get_name_filldir { 71 struct gfs2_inum_host inum; 72 char *name; 73 }; 74 75 static int get_name_filldir(void *opaque, const char *name, int length, 76 loff_t offset, u64 inum, unsigned int type) 77 { 78 struct get_name_filldir *gnfd = opaque; 79 80 if (inum != gnfd->inum.no_addr) 81 return 0; 82 83 memcpy(gnfd->name, name, length); 84 gnfd->name[length] = 0; 85 86 return 1; 87 } 88 89 static int gfs2_get_name(struct dentry *parent, char *name, 90 struct dentry *child) 91 { 92 struct inode *dir = parent->d_inode; 93 struct inode *inode = child->d_inode; 94 struct gfs2_inode *dip, *ip; 95 struct get_name_filldir gnfd; 96 struct gfs2_holder gh; 97 u64 offset = 0; 98 int error; 99 100 if (!dir) 101 return -EINVAL; 102 103 if (!S_ISDIR(dir->i_mode) || !inode) 104 return -EINVAL; 105 106 dip = GFS2_I(dir); 107 ip = GFS2_I(inode); 108 109 *name = 0; 110 gnfd.inum.no_addr = ip->i_no_addr; 111 gnfd.inum.no_formal_ino = ip->i_no_formal_ino; 112 gnfd.name = name; 113 114 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); 115 if (error) 116 return error; 117 118 error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir); 119 120 gfs2_glock_dq_uninit(&gh); 121 122 if (!error && !*name) 123 error = -ENOENT; 124 125 return error; 126 } 127 128 static struct dentry *gfs2_get_parent(struct dentry *child) 129 { 130 struct qstr dotdot; 131 struct dentry *dentry; 132 133 /* 134 * XXX(hch): it would be a good idea to keep this around as a 135 * static variable. 136 */ 137 gfs2_str2qstr(&dotdot, ".."); 138 139 dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1)); 140 if (!IS_ERR(dentry)) 141 dentry->d_op = &gfs2_dops; 142 return dentry; 143 } 144 145 static struct dentry *gfs2_get_dentry(struct super_block *sb, 146 struct gfs2_inum_host *inum) 147 { 148 struct gfs2_sbd *sdp = sb->s_fs_info; 149 struct gfs2_holder i_gh; 150 struct inode *inode; 151 struct dentry *dentry; 152 int error; 153 154 inode = gfs2_ilookup(sb, inum->no_addr); 155 if (inode) { 156 if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { 157 iput(inode); 158 return ERR_PTR(-ESTALE); 159 } 160 goto out_inode; 161 } 162 163 error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops, 164 LM_ST_SHARED, LM_FLAG_ANY, &i_gh); 165 if (error) 166 return ERR_PTR(error); 167 168 error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE); 169 if (error) 170 goto fail; 171 172 inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0); 173 if (IS_ERR(inode)) { 174 error = PTR_ERR(inode); 175 goto fail; 176 } 177 178 error = gfs2_inode_refresh(GFS2_I(inode)); 179 if (error) { 180 iput(inode); 181 goto fail; 182 } 183 184 /* Pick up the works we bypass in gfs2_inode_lookup */ 185 if (inode->i_state & I_NEW) 186 gfs2_set_iop(inode); 187 188 if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { 189 iput(inode); 190 goto fail; 191 } 192 193 error = -EIO; 194 if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) { 195 iput(inode); 196 goto fail; 197 } 198 199 gfs2_glock_dq_uninit(&i_gh); 200 201 out_inode: 202 dentry = d_obtain_alias(inode); 203 if (!IS_ERR(dentry)) 204 dentry->d_op = &gfs2_dops; 205 return dentry; 206 fail: 207 gfs2_glock_dq_uninit(&i_gh); 208 return ERR_PTR(error); 209 } 210 211 static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, 212 int fh_len, int fh_type) 213 { 214 struct gfs2_inum_host this; 215 __be32 *fh = (__force __be32 *)fid->raw; 216 217 switch (fh_type) { 218 case GFS2_SMALL_FH_SIZE: 219 case GFS2_LARGE_FH_SIZE: 220 case GFS2_OLD_FH_SIZE: 221 this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; 222 this.no_formal_ino |= be32_to_cpu(fh[1]); 223 this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; 224 this.no_addr |= be32_to_cpu(fh[3]); 225 return gfs2_get_dentry(sb, &this); 226 default: 227 return NULL; 228 } 229 } 230 231 static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid, 232 int fh_len, int fh_type) 233 { 234 struct gfs2_inum_host parent; 235 __be32 *fh = (__force __be32 *)fid->raw; 236 237 switch (fh_type) { 238 case GFS2_LARGE_FH_SIZE: 239 case GFS2_OLD_FH_SIZE: 240 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; 241 parent.no_formal_ino |= be32_to_cpu(fh[5]); 242 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; 243 parent.no_addr |= be32_to_cpu(fh[7]); 244 return gfs2_get_dentry(sb, &parent); 245 default: 246 return NULL; 247 } 248 } 249 250 const struct export_operations gfs2_export_ops = { 251 .encode_fh = gfs2_encode_fh, 252 .fh_to_dentry = gfs2_fh_to_dentry, 253 .fh_to_parent = gfs2_fh_to_parent, 254 .get_name = gfs2_get_name, 255 .get_parent = gfs2_get_parent, 256 }; 257 258