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/spinlock.h> 11 #include <linux/completion.h> 12 #include <linux/buffer_head.h> 13 #include <linux/gfs2_ondisk.h> 14 #include <linux/crc32.h> 15 16 #include "gfs2.h" 17 #include "incore.h" 18 #include "dir.h" 19 #include "glock.h" 20 #include "super.h" 21 #include "util.h" 22 #include "inode.h" 23 24 /** 25 * gfs2_drevalidate - Check directory lookup consistency 26 * @dentry: the mapping to check 27 * @nd: 28 * 29 * Check to make sure the lookup necessary to arrive at this inode from its 30 * parent is still good. 31 * 32 * Returns: 1 if the dentry is ok, 0 if it isn't 33 */ 34 35 static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) 36 { 37 struct dentry *parent = dget_parent(dentry); 38 struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode); 39 struct gfs2_inode *dip = GFS2_I(parent->d_inode); 40 struct inode *inode = dentry->d_inode; 41 struct gfs2_holder d_gh; 42 struct gfs2_inode *ip = NULL; 43 int error; 44 int had_lock = 0; 45 46 if (inode) { 47 if (is_bad_inode(inode)) 48 goto invalid; 49 ip = GFS2_I(inode); 50 } 51 52 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) 53 goto valid; 54 55 had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL); 56 if (!had_lock) { 57 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); 58 if (error) 59 goto fail; 60 } 61 62 error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip); 63 switch (error) { 64 case 0: 65 if (!inode) 66 goto invalid_gunlock; 67 break; 68 case -ENOENT: 69 if (!inode) 70 goto valid_gunlock; 71 goto invalid_gunlock; 72 default: 73 goto fail_gunlock; 74 } 75 76 valid_gunlock: 77 if (!had_lock) 78 gfs2_glock_dq_uninit(&d_gh); 79 valid: 80 dput(parent); 81 return 1; 82 83 invalid_gunlock: 84 if (!had_lock) 85 gfs2_glock_dq_uninit(&d_gh); 86 invalid: 87 if (inode && S_ISDIR(inode->i_mode)) { 88 if (have_submounts(dentry)) 89 goto valid; 90 shrink_dcache_parent(dentry); 91 } 92 d_drop(dentry); 93 dput(parent); 94 return 0; 95 96 fail_gunlock: 97 gfs2_glock_dq_uninit(&d_gh); 98 fail: 99 dput(parent); 100 return 0; 101 } 102 103 static int gfs2_dhash(struct dentry *dentry, struct qstr *str) 104 { 105 str->hash = gfs2_disk_hash(str->name, str->len); 106 return 0; 107 } 108 109 static int gfs2_dentry_delete(struct dentry *dentry) 110 { 111 struct gfs2_inode *ginode; 112 113 if (!dentry->d_inode) 114 return 0; 115 116 ginode = GFS2_I(dentry->d_inode); 117 if (!ginode->i_iopen_gh.gh_gl) 118 return 0; 119 120 if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags)) 121 return 1; 122 123 return 0; 124 } 125 126 const struct dentry_operations gfs2_dops = { 127 .d_revalidate = gfs2_drevalidate, 128 .d_hash = gfs2_dhash, 129 .d_delete = gfs2_dentry_delete, 130 }; 131 132