0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/types.h>
0012 #include <linux/slab.h>
0013 #include <linux/namei.h>
0014
0015 #include <cluster/masklog.h>
0016
0017 #include "ocfs2.h"
0018
0019 #include "alloc.h"
0020 #include "dcache.h"
0021 #include "dlmglue.h"
0022 #include "file.h"
0023 #include "inode.h"
0024 #include "ocfs2_trace.h"
0025
0026 void ocfs2_dentry_attach_gen(struct dentry *dentry)
0027 {
0028 unsigned long gen =
0029 OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
0030 BUG_ON(d_inode(dentry));
0031 dentry->d_fsdata = (void *)gen;
0032 }
0033
0034
0035 static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags)
0036 {
0037 struct inode *inode;
0038 int ret = 0;
0039 struct ocfs2_super *osb;
0040
0041 if (flags & LOOKUP_RCU)
0042 return -ECHILD;
0043
0044 inode = d_inode(dentry);
0045 osb = OCFS2_SB(dentry->d_sb);
0046
0047 trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
0048 dentry->d_name.name);
0049
0050
0051
0052
0053
0054 if (inode == NULL) {
0055 unsigned long gen = (unsigned long) dentry->d_fsdata;
0056 unsigned long pgen;
0057 spin_lock(&dentry->d_lock);
0058 pgen = OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
0059 spin_unlock(&dentry->d_lock);
0060 trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
0061 dentry->d_name.name,
0062 pgen, gen);
0063 if (gen != pgen)
0064 goto bail;
0065 goto valid;
0066 }
0067
0068 BUG_ON(!osb);
0069
0070 if (inode == osb->root_inode || is_bad_inode(inode))
0071 goto bail;
0072
0073 spin_lock(&OCFS2_I(inode)->ip_lock);
0074
0075 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
0076 spin_unlock(&OCFS2_I(inode)->ip_lock);
0077 trace_ocfs2_dentry_revalidate_delete(
0078 (unsigned long long)OCFS2_I(inode)->ip_blkno);
0079 goto bail;
0080 }
0081 spin_unlock(&OCFS2_I(inode)->ip_lock);
0082
0083
0084
0085
0086
0087 if (inode->i_nlink == 0) {
0088 trace_ocfs2_dentry_revalidate_orphaned(
0089 (unsigned long long)OCFS2_I(inode)->ip_blkno,
0090 S_ISDIR(inode->i_mode));
0091 goto bail;
0092 }
0093
0094
0095
0096
0097
0098 if (!dentry->d_fsdata) {
0099 trace_ocfs2_dentry_revalidate_nofsdata(
0100 (unsigned long long)OCFS2_I(inode)->ip_blkno);
0101 goto bail;
0102 }
0103
0104 valid:
0105 ret = 1;
0106
0107 bail:
0108 trace_ocfs2_dentry_revalidate_ret(ret);
0109 return ret;
0110 }
0111
0112 static int ocfs2_match_dentry(struct dentry *dentry,
0113 u64 parent_blkno,
0114 int skip_unhashed)
0115 {
0116 struct inode *parent;
0117
0118
0119
0120
0121
0122
0123
0124 if (!dentry->d_fsdata)
0125 return 0;
0126
0127 if (!dentry->d_parent)
0128 return 0;
0129
0130 if (skip_unhashed && d_unhashed(dentry))
0131 return 0;
0132
0133 parent = d_inode(dentry->d_parent);
0134
0135 if (!parent)
0136 return 0;
0137
0138
0139 if (OCFS2_I(parent)->ip_blkno != parent_blkno)
0140 return 0;
0141
0142 return 1;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152 struct dentry *ocfs2_find_local_alias(struct inode *inode,
0153 u64 parent_blkno,
0154 int skip_unhashed)
0155 {
0156 struct dentry *dentry;
0157
0158 spin_lock(&inode->i_lock);
0159 hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
0160 spin_lock(&dentry->d_lock);
0161 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
0162 trace_ocfs2_find_local_alias(dentry->d_name.len,
0163 dentry->d_name.name);
0164
0165 dget_dlock(dentry);
0166 spin_unlock(&dentry->d_lock);
0167 spin_unlock(&inode->i_lock);
0168 return dentry;
0169 }
0170 spin_unlock(&dentry->d_lock);
0171 }
0172 spin_unlock(&inode->i_lock);
0173 return NULL;
0174 }
0175
0176 DEFINE_SPINLOCK(dentry_attach_lock);
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 int ocfs2_dentry_attach_lock(struct dentry *dentry,
0211 struct inode *inode,
0212 u64 parent_blkno)
0213 {
0214 int ret;
0215 struct dentry *alias;
0216 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
0217
0218 trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
0219 (unsigned long long)parent_blkno, dl);
0220
0221
0222
0223
0224
0225
0226
0227 if (!inode)
0228 return 0;
0229
0230 if (d_really_is_negative(dentry) && dentry->d_fsdata) {
0231
0232
0233 dentry->d_fsdata = dl = NULL;
0234 }
0235
0236 if (dl) {
0237 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
0238 " \"%pd\": old parent: %llu, new: %llu\n",
0239 dentry,
0240 (unsigned long long)parent_blkno,
0241 (unsigned long long)dl->dl_parent_blkno);
0242 return 0;
0243 }
0244
0245 alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
0246 if (alias) {
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 dl = alias->d_fsdata;
0259 mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
0260 (unsigned long long)parent_blkno,
0261 (unsigned long long)OCFS2_I(inode)->ip_blkno);
0262
0263 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
0264 " \"%pd\": old parent: %llu, new: %llu\n",
0265 dentry,
0266 (unsigned long long)parent_blkno,
0267 (unsigned long long)dl->dl_parent_blkno);
0268
0269 trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
0270 (unsigned long long)parent_blkno,
0271 (unsigned long long)OCFS2_I(inode)->ip_blkno);
0272
0273 goto out_attach;
0274 }
0275
0276
0277
0278
0279 dl = kmalloc(sizeof(*dl), GFP_NOFS);
0280 if (!dl) {
0281 ret = -ENOMEM;
0282 mlog_errno(ret);
0283 return ret;
0284 }
0285
0286 dl->dl_count = 0;
0287
0288
0289
0290
0291 dl->dl_inode = igrab(inode);
0292 dl->dl_parent_blkno = parent_blkno;
0293 ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
0294
0295 out_attach:
0296 spin_lock(&dentry_attach_lock);
0297 if (unlikely(dentry->d_fsdata && !alias)) {
0298
0299
0300
0301
0302 spin_unlock(&dentry_attach_lock);
0303 iput(dl->dl_inode);
0304 ocfs2_lock_res_free(&dl->dl_lockres);
0305 kfree(dl);
0306 return 0;
0307 }
0308
0309 dentry->d_fsdata = dl;
0310 dl->dl_count++;
0311 spin_unlock(&dentry_attach_lock);
0312
0313
0314
0315
0316
0317
0318 ret = ocfs2_dentry_lock(dentry, 0);
0319 if (!ret)
0320 ocfs2_dentry_unlock(dentry, 0);
0321 else
0322 mlog_errno(ret);
0323
0324
0325
0326
0327
0328
0329 if (ret < 0 && !alias) {
0330 ocfs2_lock_res_free(&dl->dl_lockres);
0331 BUG_ON(dl->dl_count != 1);
0332 spin_lock(&dentry_attach_lock);
0333 dentry->d_fsdata = NULL;
0334 spin_unlock(&dentry_attach_lock);
0335 kfree(dl);
0336 iput(inode);
0337 }
0338
0339 dput(alias);
0340
0341 return ret;
0342 }
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365 static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
0366 struct ocfs2_dentry_lock *dl)
0367 {
0368 iput(dl->dl_inode);
0369 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
0370 ocfs2_lock_res_free(&dl->dl_lockres);
0371 kfree(dl);
0372 }
0373
0374 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
0375 struct ocfs2_dentry_lock *dl)
0376 {
0377 int unlock = 0;
0378
0379 BUG_ON(dl->dl_count == 0);
0380
0381 spin_lock(&dentry_attach_lock);
0382 dl->dl_count--;
0383 unlock = !dl->dl_count;
0384 spin_unlock(&dentry_attach_lock);
0385
0386 if (unlock)
0387 ocfs2_drop_dentry_lock(osb, dl);
0388 }
0389
0390 static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
0391 {
0392 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
0393
0394 if (!dl) {
0395
0396
0397
0398
0399 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
0400 !d_unhashed(dentry)) {
0401 unsigned long long ino = 0ULL;
0402 if (inode)
0403 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
0404 mlog(ML_ERROR, "Dentry is missing cluster lock. "
0405 "inode: %llu, d_flags: 0x%x, d_name: %pd\n",
0406 ino, dentry->d_flags, dentry);
0407 }
0408
0409 goto out;
0410 }
0411
0412 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %pd, count: %u\n",
0413 dentry, dl->dl_count);
0414
0415 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
0416
0417 out:
0418 iput(inode);
0419 }
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440 void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
0441 struct inode *old_dir, struct inode *new_dir)
0442 {
0443 int ret;
0444 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
0445 struct inode *inode = d_inode(dentry);
0446
0447
0448
0449
0450
0451
0452
0453 if (old_dir == new_dir)
0454 goto out_move;
0455
0456 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
0457
0458 dentry->d_fsdata = NULL;
0459 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
0460 if (ret)
0461 mlog_errno(ret);
0462
0463 out_move:
0464 d_move(dentry, target);
0465 }
0466
0467 const struct dentry_operations ocfs2_dentry_ops = {
0468 .d_revalidate = ocfs2_dentry_revalidate,
0469 .d_iput = ocfs2_dentry_iput,
0470 };