xref: /linux/fs/gfs2/dentry.c (revision 5be1fa8abd7b049f51e6e98e75a37eef5ae2c296)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
4  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
5  */
6 
7 #include <linux/spinlock.h>
8 #include <linux/completion.h>
9 #include <linux/buffer_head.h>
10 #include <linux/gfs2_ondisk.h>
11 #include <linux/namei.h>
12 #include <linux/crc32.h>
13 
14 #include "gfs2.h"
15 #include "incore.h"
16 #include "dir.h"
17 #include "glock.h"
18 #include "super.h"
19 #include "util.h"
20 #include "inode.h"
21 
22 /**
23  * gfs2_drevalidate - Check directory lookup consistency
24  * @dir: expected parent directory inode
25  * @name: expexted name
26  * @dentry: dentry to check
27  * @flags: lookup flags
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 inode *dir, const struct qstr *name,
36 			    struct dentry *dentry, unsigned int flags)
37 {
38 	struct dentry *parent;
39 	struct gfs2_sbd *sdp;
40 	struct gfs2_inode *dip;
41 	struct inode *inode;
42 	struct gfs2_holder d_gh;
43 	struct gfs2_inode *ip = NULL;
44 	int error, valid = 0;
45 	int had_lock = 0;
46 
47 	if (flags & LOOKUP_RCU)
48 		return -ECHILD;
49 
50 	parent = dget_parent(dentry);
51 	sdp = GFS2_SB(d_inode(parent));
52 	dip = GFS2_I(d_inode(parent));
53 	inode = d_inode(dentry);
54 
55 	if (inode) {
56 		if (is_bad_inode(inode))
57 			goto out;
58 		ip = GFS2_I(inode);
59 	}
60 
61 	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) {
62 		valid = 1;
63 		goto out;
64 	}
65 
66 	had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL);
67 	if (!had_lock) {
68 		error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
69 		if (error)
70 			goto out;
71 	}
72 
73 	error = gfs2_dir_check(d_inode(parent), &dentry->d_name, ip);
74 	valid = inode ? !error : (error == -ENOENT);
75 
76 	if (!had_lock)
77 		gfs2_glock_dq_uninit(&d_gh);
78 out:
79 	dput(parent);
80 	return valid;
81 }
82 
83 static int gfs2_dhash(const struct dentry *dentry, struct qstr *str)
84 {
85 	str->hash = gfs2_disk_hash(str->name, str->len);
86 	return 0;
87 }
88 
89 static int gfs2_dentry_delete(const struct dentry *dentry)
90 {
91 	struct gfs2_inode *ginode;
92 
93 	if (d_really_is_negative(dentry))
94 		return 0;
95 
96 	ginode = GFS2_I(d_inode(dentry));
97 	if (!gfs2_holder_initialized(&ginode->i_iopen_gh))
98 		return 0;
99 
100 	if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags))
101 		return 1;
102 
103 	return 0;
104 }
105 
106 const struct dentry_operations gfs2_dops = {
107 	.d_revalidate = gfs2_drevalidate,
108 	.d_hash = gfs2_dhash,
109 	.d_delete = gfs2_dentry_delete,
110 };
111 
112