0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/types.h>
0012
0013 #include <cluster/masklog.h>
0014
0015 #include "ocfs2.h"
0016
0017 #include "alloc.h"
0018 #include "dir.h"
0019 #include "dlmglue.h"
0020 #include "dcache.h"
0021 #include "export.h"
0022 #include "inode.h"
0023
0024 #include "buffer_head_io.h"
0025 #include "suballoc.h"
0026 #include "ocfs2_trace.h"
0027
0028 struct ocfs2_inode_handle
0029 {
0030 u64 ih_blkno;
0031 u32 ih_generation;
0032 };
0033
0034 static struct dentry *ocfs2_get_dentry(struct super_block *sb,
0035 struct ocfs2_inode_handle *handle)
0036 {
0037 struct inode *inode;
0038 struct ocfs2_super *osb = OCFS2_SB(sb);
0039 u64 blkno = handle->ih_blkno;
0040 int status, set;
0041 struct dentry *result;
0042
0043 trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno);
0044
0045 if (blkno == 0) {
0046 result = ERR_PTR(-ESTALE);
0047 goto bail;
0048 }
0049
0050 inode = ocfs2_ilookup(sb, blkno);
0051
0052
0053
0054
0055 if (inode)
0056 goto check_gen;
0057
0058
0059
0060
0061
0062 status = ocfs2_nfs_sync_lock(osb, 1);
0063 if (status < 0) {
0064 mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
0065 goto check_err;
0066 }
0067
0068 status = ocfs2_test_inode_bit(osb, blkno, &set);
0069 if (status < 0) {
0070 if (status == -EINVAL) {
0071
0072
0073
0074
0075
0076 status = -ESTALE;
0077 } else
0078 mlog(ML_ERROR, "test inode bit failed %d\n", status);
0079 goto unlock_nfs_sync;
0080 }
0081
0082 trace_ocfs2_get_dentry_test_bit(status, set);
0083
0084 if (!set) {
0085 status = -ESTALE;
0086 goto unlock_nfs_sync;
0087 }
0088
0089 inode = ocfs2_iget(osb, blkno, 0, 0);
0090
0091 unlock_nfs_sync:
0092 ocfs2_nfs_sync_unlock(osb, 1);
0093
0094 check_err:
0095 if (status < 0) {
0096 if (status == -ESTALE) {
0097 trace_ocfs2_get_dentry_stale((unsigned long long)blkno,
0098 handle->ih_generation);
0099 }
0100 result = ERR_PTR(status);
0101 goto bail;
0102 }
0103
0104 if (IS_ERR(inode)) {
0105 mlog_errno(PTR_ERR(inode));
0106 result = ERR_CAST(inode);
0107 goto bail;
0108 }
0109
0110 check_gen:
0111 if (handle->ih_generation != inode->i_generation) {
0112 trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
0113 handle->ih_generation,
0114 inode->i_generation);
0115 iput(inode);
0116 result = ERR_PTR(-ESTALE);
0117 goto bail;
0118 }
0119
0120 result = d_obtain_alias(inode);
0121 if (IS_ERR(result))
0122 mlog_errno(PTR_ERR(result));
0123
0124 bail:
0125 trace_ocfs2_get_dentry_end(result);
0126 return result;
0127 }
0128
0129 static struct dentry *ocfs2_get_parent(struct dentry *child)
0130 {
0131 int status;
0132 u64 blkno;
0133 struct dentry *parent;
0134 struct inode *dir = d_inode(child);
0135 int set;
0136
0137 trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
0138 (unsigned long long)OCFS2_I(dir)->ip_blkno);
0139
0140 status = ocfs2_nfs_sync_lock(OCFS2_SB(dir->i_sb), 1);
0141 if (status < 0) {
0142 mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
0143 parent = ERR_PTR(status);
0144 goto bail;
0145 }
0146
0147 status = ocfs2_inode_lock(dir, NULL, 0);
0148 if (status < 0) {
0149 if (status != -ENOENT)
0150 mlog_errno(status);
0151 parent = ERR_PTR(status);
0152 goto unlock_nfs_sync;
0153 }
0154
0155 status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
0156 if (status < 0) {
0157 parent = ERR_PTR(-ENOENT);
0158 goto bail_unlock;
0159 }
0160
0161 status = ocfs2_test_inode_bit(OCFS2_SB(dir->i_sb), blkno, &set);
0162 if (status < 0) {
0163 if (status == -EINVAL) {
0164 status = -ESTALE;
0165 } else
0166 mlog(ML_ERROR, "test inode bit failed %d\n", status);
0167 parent = ERR_PTR(status);
0168 goto bail_unlock;
0169 }
0170
0171 trace_ocfs2_get_dentry_test_bit(status, set);
0172 if (!set) {
0173 status = -ESTALE;
0174 parent = ERR_PTR(status);
0175 goto bail_unlock;
0176 }
0177
0178 parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
0179
0180 bail_unlock:
0181 ocfs2_inode_unlock(dir, 0);
0182
0183 unlock_nfs_sync:
0184 ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
0185
0186 bail:
0187 trace_ocfs2_get_parent_end(parent);
0188
0189 return parent;
0190 }
0191
0192 static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len,
0193 struct inode *parent)
0194 {
0195 int len = *max_len;
0196 int type = 1;
0197 u64 blkno;
0198 u32 generation;
0199 __le32 *fh = (__force __le32 *) fh_in;
0200
0201 #ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION
0202 #error "You go ahead and fix that mess, then. Somehow"
0203 trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
0204 dentry->d_name.name,
0205 fh, len, connectable);
0206 #endif
0207
0208 if (parent && (len < 6)) {
0209 *max_len = 6;
0210 type = FILEID_INVALID;
0211 goto bail;
0212 } else if (len < 3) {
0213 *max_len = 3;
0214 type = FILEID_INVALID;
0215 goto bail;
0216 }
0217
0218 blkno = OCFS2_I(inode)->ip_blkno;
0219 generation = inode->i_generation;
0220
0221 trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation);
0222
0223 len = 3;
0224 fh[0] = cpu_to_le32((u32)(blkno >> 32));
0225 fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
0226 fh[2] = cpu_to_le32(generation);
0227
0228 if (parent) {
0229 blkno = OCFS2_I(parent)->ip_blkno;
0230 generation = parent->i_generation;
0231
0232 fh[3] = cpu_to_le32((u32)(blkno >> 32));
0233 fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
0234 fh[5] = cpu_to_le32(generation);
0235
0236 len = 6;
0237 type = 2;
0238
0239 trace_ocfs2_encode_fh_parent((unsigned long long)blkno,
0240 generation);
0241 }
0242
0243 *max_len = len;
0244
0245 bail:
0246 trace_ocfs2_encode_fh_type(type);
0247 return type;
0248 }
0249
0250 static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
0251 struct fid *fid, int fh_len, int fh_type)
0252 {
0253 struct ocfs2_inode_handle handle;
0254
0255 if (fh_len < 3 || fh_type > 2)
0256 return NULL;
0257
0258 handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
0259 handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
0260 handle.ih_generation = le32_to_cpu(fid->raw[2]);
0261 return ocfs2_get_dentry(sb, &handle);
0262 }
0263
0264 static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
0265 struct fid *fid, int fh_len, int fh_type)
0266 {
0267 struct ocfs2_inode_handle parent;
0268
0269 if (fh_type != 2 || fh_len < 6)
0270 return NULL;
0271
0272 parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
0273 parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
0274 parent.ih_generation = le32_to_cpu(fid->raw[5]);
0275 return ocfs2_get_dentry(sb, &parent);
0276 }
0277
0278 const struct export_operations ocfs2_export_ops = {
0279 .encode_fh = ocfs2_encode_fh,
0280 .fh_to_dentry = ocfs2_fh_to_dentry,
0281 .fh_to_parent = ocfs2_fh_to_parent,
0282 .get_parent = ocfs2_get_parent,
0283 };