1b1e71b06SSteven Whitehouse /* 2b1e71b06SSteven Whitehouse * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3b1e71b06SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4b1e71b06SSteven Whitehouse * 5b1e71b06SSteven Whitehouse * This copyrighted material is made available to anyone wishing to use, 6b1e71b06SSteven Whitehouse * modify, copy, or redistribute it subject to the terms and conditions 7b1e71b06SSteven Whitehouse * of the GNU General Public License version 2. 8b1e71b06SSteven Whitehouse */ 9b1e71b06SSteven Whitehouse 10b1e71b06SSteven Whitehouse #include <linux/spinlock.h> 11b1e71b06SSteven Whitehouse #include <linux/completion.h> 12b1e71b06SSteven Whitehouse #include <linux/buffer_head.h> 13b1e71b06SSteven Whitehouse #include <linux/gfs2_ondisk.h> 14b1e71b06SSteven Whitehouse #include <linux/crc32.h> 15b1e71b06SSteven Whitehouse 16b1e71b06SSteven Whitehouse #include "gfs2.h" 17b1e71b06SSteven Whitehouse #include "incore.h" 18b1e71b06SSteven Whitehouse #include "dir.h" 19b1e71b06SSteven Whitehouse #include "glock.h" 20b1e71b06SSteven Whitehouse #include "super.h" 21b1e71b06SSteven Whitehouse #include "util.h" 22b1e71b06SSteven Whitehouse #include "inode.h" 23b1e71b06SSteven Whitehouse 24b1e71b06SSteven Whitehouse /** 25b1e71b06SSteven Whitehouse * gfs2_drevalidate - Check directory lookup consistency 26b1e71b06SSteven Whitehouse * @dentry: the mapping to check 27b1e71b06SSteven Whitehouse * @nd: 28b1e71b06SSteven Whitehouse * 29b1e71b06SSteven Whitehouse * Check to make sure the lookup necessary to arrive at this inode from its 30b1e71b06SSteven Whitehouse * parent is still good. 31b1e71b06SSteven Whitehouse * 32b1e71b06SSteven Whitehouse * Returns: 1 if the dentry is ok, 0 if it isn't 33b1e71b06SSteven Whitehouse */ 34b1e71b06SSteven Whitehouse 35b1e71b06SSteven Whitehouse static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) 36b1e71b06SSteven Whitehouse { 37b1e71b06SSteven Whitehouse struct dentry *parent = dget_parent(dentry); 38b1e71b06SSteven Whitehouse struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode); 39b1e71b06SSteven Whitehouse struct gfs2_inode *dip = GFS2_I(parent->d_inode); 40b1e71b06SSteven Whitehouse struct inode *inode = dentry->d_inode; 41b1e71b06SSteven Whitehouse struct gfs2_holder d_gh; 42b1e71b06SSteven Whitehouse struct gfs2_inode *ip = NULL; 43b1e71b06SSteven Whitehouse int error; 44b1e71b06SSteven Whitehouse int had_lock = 0; 45b1e71b06SSteven Whitehouse 46b1e71b06SSteven Whitehouse if (inode) { 47b1e71b06SSteven Whitehouse if (is_bad_inode(inode)) 48b1e71b06SSteven Whitehouse goto invalid; 49b1e71b06SSteven Whitehouse ip = GFS2_I(inode); 50b1e71b06SSteven Whitehouse } 51b1e71b06SSteven Whitehouse 52c2048b00SSteven Whitehouse if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) 53b1e71b06SSteven Whitehouse goto valid; 54b1e71b06SSteven Whitehouse 55b1e71b06SSteven Whitehouse had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL); 56b1e71b06SSteven Whitehouse if (!had_lock) { 57b1e71b06SSteven Whitehouse error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); 58b1e71b06SSteven Whitehouse if (error) 59b1e71b06SSteven Whitehouse goto fail; 60b1e71b06SSteven Whitehouse } 61b1e71b06SSteven Whitehouse 62b1e71b06SSteven Whitehouse error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip); 63b1e71b06SSteven Whitehouse switch (error) { 64b1e71b06SSteven Whitehouse case 0: 65b1e71b06SSteven Whitehouse if (!inode) 66b1e71b06SSteven Whitehouse goto invalid_gunlock; 67b1e71b06SSteven Whitehouse break; 68b1e71b06SSteven Whitehouse case -ENOENT: 69b1e71b06SSteven Whitehouse if (!inode) 70b1e71b06SSteven Whitehouse goto valid_gunlock; 71b1e71b06SSteven Whitehouse goto invalid_gunlock; 72b1e71b06SSteven Whitehouse default: 73b1e71b06SSteven Whitehouse goto fail_gunlock; 74b1e71b06SSteven Whitehouse } 75b1e71b06SSteven Whitehouse 76b1e71b06SSteven Whitehouse valid_gunlock: 77b1e71b06SSteven Whitehouse if (!had_lock) 78b1e71b06SSteven Whitehouse gfs2_glock_dq_uninit(&d_gh); 79b1e71b06SSteven Whitehouse valid: 80b1e71b06SSteven Whitehouse dput(parent); 81b1e71b06SSteven Whitehouse return 1; 82b1e71b06SSteven Whitehouse 83b1e71b06SSteven Whitehouse invalid_gunlock: 84b1e71b06SSteven Whitehouse if (!had_lock) 85b1e71b06SSteven Whitehouse gfs2_glock_dq_uninit(&d_gh); 86b1e71b06SSteven Whitehouse invalid: 87b1e71b06SSteven Whitehouse if (inode && S_ISDIR(inode->i_mode)) { 88b1e71b06SSteven Whitehouse if (have_submounts(dentry)) 89b1e71b06SSteven Whitehouse goto valid; 90b1e71b06SSteven Whitehouse shrink_dcache_parent(dentry); 91b1e71b06SSteven Whitehouse } 92b1e71b06SSteven Whitehouse d_drop(dentry); 93b1e71b06SSteven Whitehouse dput(parent); 94b1e71b06SSteven Whitehouse return 0; 95b1e71b06SSteven Whitehouse 96b1e71b06SSteven Whitehouse fail_gunlock: 97b1e71b06SSteven Whitehouse gfs2_glock_dq_uninit(&d_gh); 98b1e71b06SSteven Whitehouse fail: 99b1e71b06SSteven Whitehouse dput(parent); 100b1e71b06SSteven Whitehouse return 0; 101b1e71b06SSteven Whitehouse } 102b1e71b06SSteven Whitehouse 103b1e71b06SSteven Whitehouse static int gfs2_dhash(struct dentry *dentry, struct qstr *str) 104b1e71b06SSteven Whitehouse { 105b1e71b06SSteven Whitehouse str->hash = gfs2_disk_hash(str->name, str->len); 106b1e71b06SSteven Whitehouse return 0; 107b1e71b06SSteven Whitehouse } 108b1e71b06SSteven Whitehouse 109fe15ce44SNick Piggin static int gfs2_dentry_delete(const struct dentry *dentry) 110970343cdSWengang Wang { 111970343cdSWengang Wang struct gfs2_inode *ginode; 112970343cdSWengang Wang 113970343cdSWengang Wang if (!dentry->d_inode) 114970343cdSWengang Wang return 0; 115970343cdSWengang Wang 116970343cdSWengang Wang ginode = GFS2_I(dentry->d_inode); 117970343cdSWengang Wang if (!ginode->i_iopen_gh.gh_gl) 118970343cdSWengang Wang return 0; 119970343cdSWengang Wang 120970343cdSWengang Wang if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags)) 121970343cdSWengang Wang return 1; 122970343cdSWengang Wang 123970343cdSWengang Wang return 0; 124970343cdSWengang Wang } 125970343cdSWengang Wang 126b1e71b06SSteven Whitehouse const struct dentry_operations gfs2_dops = { 127b1e71b06SSteven Whitehouse .d_revalidate = gfs2_drevalidate, 128b1e71b06SSteven Whitehouse .d_hash = gfs2_dhash, 129970343cdSWengang Wang .d_delete = gfs2_dentry_delete, 130b1e71b06SSteven Whitehouse }; 131b1e71b06SSteven Whitehouse 132