17336d0e6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2b1e71b06SSteven Whitehouse /* 3b1e71b06SSteven Whitehouse * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4b1e71b06SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 5b1e71b06SSteven Whitehouse */ 6b1e71b06SSteven Whitehouse 7b1e71b06SSteven Whitehouse #include <linux/spinlock.h> 8b1e71b06SSteven Whitehouse #include <linux/completion.h> 9b1e71b06SSteven Whitehouse #include <linux/buffer_head.h> 10b1e71b06SSteven Whitehouse #include <linux/gfs2_ondisk.h> 1134286d66SNick Piggin #include <linux/namei.h> 12b1e71b06SSteven Whitehouse #include <linux/crc32.h> 13b1e71b06SSteven Whitehouse 14b1e71b06SSteven Whitehouse #include "gfs2.h" 15b1e71b06SSteven Whitehouse #include "incore.h" 16b1e71b06SSteven Whitehouse #include "dir.h" 17b1e71b06SSteven Whitehouse #include "glock.h" 18b1e71b06SSteven Whitehouse #include "super.h" 19b1e71b06SSteven Whitehouse #include "util.h" 20b1e71b06SSteven Whitehouse #include "inode.h" 21b1e71b06SSteven Whitehouse 22b1e71b06SSteven Whitehouse /** 23b1e71b06SSteven Whitehouse * gfs2_drevalidate - Check directory lookup consistency 24b1e71b06SSteven Whitehouse * @dentry: the mapping to check 250b728e19SAl Viro * @flags: lookup flags 26b1e71b06SSteven Whitehouse * 27b1e71b06SSteven Whitehouse * Check to make sure the lookup necessary to arrive at this inode from its 28b1e71b06SSteven Whitehouse * parent is still good. 29b1e71b06SSteven Whitehouse * 30b1e71b06SSteven Whitehouse * Returns: 1 if the dentry is ok, 0 if it isn't 31b1e71b06SSteven Whitehouse */ 32b1e71b06SSteven Whitehouse 330b728e19SAl Viro static int gfs2_drevalidate(struct dentry *dentry, unsigned int flags) 34b1e71b06SSteven Whitehouse { 3534286d66SNick Piggin struct dentry *parent; 3634286d66SNick Piggin struct gfs2_sbd *sdp; 3734286d66SNick Piggin struct gfs2_inode *dip; 3834286d66SNick Piggin struct inode *inode; 39b1e71b06SSteven Whitehouse struct gfs2_holder d_gh; 40b1e71b06SSteven Whitehouse struct gfs2_inode *ip = NULL; 418c5ca117SBob Peterson int error, valid = 0; 42b1e71b06SSteven Whitehouse int had_lock = 0; 43b1e71b06SSteven Whitehouse 440b728e19SAl Viro if (flags & LOOKUP_RCU) 4534286d66SNick Piggin return -ECHILD; 4634286d66SNick Piggin 4734286d66SNick Piggin parent = dget_parent(dentry); 482b0143b5SDavid Howells sdp = GFS2_SB(d_inode(parent)); 492b0143b5SDavid Howells dip = GFS2_I(d_inode(parent)); 502b0143b5SDavid Howells inode = d_inode(dentry); 5134286d66SNick Piggin 52b1e71b06SSteven Whitehouse if (inode) { 53b1e71b06SSteven Whitehouse if (is_bad_inode(inode)) 548c5ca117SBob Peterson goto out; 55b1e71b06SSteven Whitehouse ip = GFS2_I(inode); 56b1e71b06SSteven Whitehouse } 57b1e71b06SSteven Whitehouse 588c5ca117SBob Peterson if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) { 598c5ca117SBob Peterson valid = 1; 608c5ca117SBob Peterson goto out; 618c5ca117SBob Peterson } 62b1e71b06SSteven Whitehouse 63b1e71b06SSteven Whitehouse had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL); 64b1e71b06SSteven Whitehouse if (!had_lock) { 65b1e71b06SSteven Whitehouse error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); 66b1e71b06SSteven Whitehouse if (error) 678c5ca117SBob Peterson goto out; 68b1e71b06SSteven Whitehouse } 69b1e71b06SSteven Whitehouse 702b0143b5SDavid Howells error = gfs2_dir_check(d_inode(parent), &dentry->d_name, ip); 718c5ca117SBob Peterson valid = inode ? !error : (error == -ENOENT); 72b1e71b06SSteven Whitehouse 73b1e71b06SSteven Whitehouse if (!had_lock) 74b1e71b06SSteven Whitehouse gfs2_glock_dq_uninit(&d_gh); 758c5ca117SBob Peterson out: 76b1e71b06SSteven Whitehouse dput(parent); 778c5ca117SBob Peterson return valid; 78b1e71b06SSteven Whitehouse } 79b1e71b06SSteven Whitehouse 80da53be12SLinus Torvalds static int gfs2_dhash(const struct dentry *dentry, struct qstr *str) 81b1e71b06SSteven Whitehouse { 82b1e71b06SSteven Whitehouse str->hash = gfs2_disk_hash(str->name, str->len); 83b1e71b06SSteven Whitehouse return 0; 84b1e71b06SSteven Whitehouse } 85b1e71b06SSteven Whitehouse 86fe15ce44SNick Piggin static int gfs2_dentry_delete(const struct dentry *dentry) 87970343cdSWengang Wang { 88970343cdSWengang Wang struct gfs2_inode *ginode; 89970343cdSWengang Wang 902b0143b5SDavid Howells if (d_really_is_negative(dentry)) 91970343cdSWengang Wang return 0; 92970343cdSWengang Wang 932b0143b5SDavid Howells ginode = GFS2_I(d_inode(dentry)); 946df9f9a2SAndreas Gruenbacher if (!gfs2_holder_initialized(&ginode->i_iopen_gh)) 95970343cdSWengang Wang return 0; 96970343cdSWengang Wang 97970343cdSWengang Wang if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags)) 98970343cdSWengang Wang return 1; 99970343cdSWengang Wang 100970343cdSWengang Wang return 0; 101970343cdSWengang Wang } 102970343cdSWengang Wang 103b1e71b06SSteven Whitehouse const struct dentry_operations gfs2_dops = { 104b1e71b06SSteven Whitehouse .d_revalidate = gfs2_drevalidate, 105b1e71b06SSteven Whitehouse .d_hash = gfs2_dhash, 106970343cdSWengang Wang .d_delete = gfs2_dentry_delete, 107b1e71b06SSteven Whitehouse }; 108b1e71b06SSteven Whitehouse 109