xref: /openbmc/linux/fs/gfs2/dentry.c (revision da53be12)
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>
1434286d66SNick Piggin #include <linux/namei.h>
15b1e71b06SSteven Whitehouse #include <linux/crc32.h>
16b1e71b06SSteven Whitehouse 
17b1e71b06SSteven Whitehouse #include "gfs2.h"
18b1e71b06SSteven Whitehouse #include "incore.h"
19b1e71b06SSteven Whitehouse #include "dir.h"
20b1e71b06SSteven Whitehouse #include "glock.h"
21b1e71b06SSteven Whitehouse #include "super.h"
22b1e71b06SSteven Whitehouse #include "util.h"
23b1e71b06SSteven Whitehouse #include "inode.h"
24b1e71b06SSteven Whitehouse 
25b1e71b06SSteven Whitehouse /**
26b1e71b06SSteven Whitehouse  * gfs2_drevalidate - Check directory lookup consistency
27b1e71b06SSteven Whitehouse  * @dentry: the mapping to check
280b728e19SAl Viro  * @flags: lookup flags
29b1e71b06SSteven Whitehouse  *
30b1e71b06SSteven Whitehouse  * Check to make sure the lookup necessary to arrive at this inode from its
31b1e71b06SSteven Whitehouse  * parent is still good.
32b1e71b06SSteven Whitehouse  *
33b1e71b06SSteven Whitehouse  * Returns: 1 if the dentry is ok, 0 if it isn't
34b1e71b06SSteven Whitehouse  */
35b1e71b06SSteven Whitehouse 
360b728e19SAl Viro static int gfs2_drevalidate(struct dentry *dentry, unsigned int flags)
37b1e71b06SSteven Whitehouse {
3834286d66SNick Piggin 	struct dentry *parent;
3934286d66SNick Piggin 	struct gfs2_sbd *sdp;
4034286d66SNick Piggin 	struct gfs2_inode *dip;
4134286d66SNick Piggin 	struct inode *inode;
42b1e71b06SSteven Whitehouse 	struct gfs2_holder d_gh;
43b1e71b06SSteven Whitehouse 	struct gfs2_inode *ip = NULL;
44b1e71b06SSteven Whitehouse 	int error;
45b1e71b06SSteven Whitehouse 	int had_lock = 0;
46b1e71b06SSteven Whitehouse 
470b728e19SAl Viro 	if (flags & LOOKUP_RCU)
4834286d66SNick Piggin 		return -ECHILD;
4934286d66SNick Piggin 
5034286d66SNick Piggin 	parent = dget_parent(dentry);
5134286d66SNick Piggin 	sdp = GFS2_SB(parent->d_inode);
5234286d66SNick Piggin 	dip = GFS2_I(parent->d_inode);
5334286d66SNick Piggin 	inode = dentry->d_inode;
5434286d66SNick Piggin 
55b1e71b06SSteven Whitehouse 	if (inode) {
56b1e71b06SSteven Whitehouse 		if (is_bad_inode(inode))
57b1e71b06SSteven Whitehouse 			goto invalid;
58b1e71b06SSteven Whitehouse 		ip = GFS2_I(inode);
59b1e71b06SSteven Whitehouse 	}
60b1e71b06SSteven Whitehouse 
61c2048b00SSteven Whitehouse 	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
62b1e71b06SSteven Whitehouse 		goto valid;
63b1e71b06SSteven Whitehouse 
64b1e71b06SSteven Whitehouse 	had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL);
65b1e71b06SSteven Whitehouse 	if (!had_lock) {
66b1e71b06SSteven Whitehouse 		error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
67b1e71b06SSteven Whitehouse 		if (error)
68b1e71b06SSteven Whitehouse 			goto fail;
69b1e71b06SSteven Whitehouse 	}
70b1e71b06SSteven Whitehouse 
71b1e71b06SSteven Whitehouse 	error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip);
72b1e71b06SSteven Whitehouse 	switch (error) {
73b1e71b06SSteven Whitehouse 	case 0:
74b1e71b06SSteven Whitehouse 		if (!inode)
75b1e71b06SSteven Whitehouse 			goto invalid_gunlock;
76b1e71b06SSteven Whitehouse 		break;
77b1e71b06SSteven Whitehouse 	case -ENOENT:
78b1e71b06SSteven Whitehouse 		if (!inode)
79b1e71b06SSteven Whitehouse 			goto valid_gunlock;
80b1e71b06SSteven Whitehouse 		goto invalid_gunlock;
81b1e71b06SSteven Whitehouse 	default:
82b1e71b06SSteven Whitehouse 		goto fail_gunlock;
83b1e71b06SSteven Whitehouse 	}
84b1e71b06SSteven Whitehouse 
85b1e71b06SSteven Whitehouse valid_gunlock:
86b1e71b06SSteven Whitehouse 	if (!had_lock)
87b1e71b06SSteven Whitehouse 		gfs2_glock_dq_uninit(&d_gh);
88b1e71b06SSteven Whitehouse valid:
89b1e71b06SSteven Whitehouse 	dput(parent);
90b1e71b06SSteven Whitehouse 	return 1;
91b1e71b06SSteven Whitehouse 
92b1e71b06SSteven Whitehouse invalid_gunlock:
93b1e71b06SSteven Whitehouse 	if (!had_lock)
94b1e71b06SSteven Whitehouse 		gfs2_glock_dq_uninit(&d_gh);
95b1e71b06SSteven Whitehouse invalid:
96b1e71b06SSteven Whitehouse 	if (inode && S_ISDIR(inode->i_mode)) {
97b1e71b06SSteven Whitehouse 		if (have_submounts(dentry))
98b1e71b06SSteven Whitehouse 			goto valid;
99b1e71b06SSteven Whitehouse 		shrink_dcache_parent(dentry);
100b1e71b06SSteven Whitehouse 	}
101b1e71b06SSteven Whitehouse 	d_drop(dentry);
102b1e71b06SSteven Whitehouse 	dput(parent);
103b1e71b06SSteven Whitehouse 	return 0;
104b1e71b06SSteven Whitehouse 
105b1e71b06SSteven Whitehouse fail_gunlock:
106b1e71b06SSteven Whitehouse 	gfs2_glock_dq_uninit(&d_gh);
107b1e71b06SSteven Whitehouse fail:
108b1e71b06SSteven Whitehouse 	dput(parent);
109b1e71b06SSteven Whitehouse 	return 0;
110b1e71b06SSteven Whitehouse }
111b1e71b06SSteven Whitehouse 
112da53be12SLinus Torvalds static int gfs2_dhash(const struct dentry *dentry, struct qstr *str)
113b1e71b06SSteven Whitehouse {
114b1e71b06SSteven Whitehouse 	str->hash = gfs2_disk_hash(str->name, str->len);
115b1e71b06SSteven Whitehouse 	return 0;
116b1e71b06SSteven Whitehouse }
117b1e71b06SSteven Whitehouse 
118fe15ce44SNick Piggin static int gfs2_dentry_delete(const struct dentry *dentry)
119970343cdSWengang Wang {
120970343cdSWengang Wang 	struct gfs2_inode *ginode;
121970343cdSWengang Wang 
122970343cdSWengang Wang 	if (!dentry->d_inode)
123970343cdSWengang Wang 		return 0;
124970343cdSWengang Wang 
125970343cdSWengang Wang 	ginode = GFS2_I(dentry->d_inode);
126970343cdSWengang Wang 	if (!ginode->i_iopen_gh.gh_gl)
127970343cdSWengang Wang 		return 0;
128970343cdSWengang Wang 
129970343cdSWengang Wang 	if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags))
130970343cdSWengang Wang 		return 1;
131970343cdSWengang Wang 
132970343cdSWengang Wang 	return 0;
133970343cdSWengang Wang }
134970343cdSWengang Wang 
135b1e71b06SSteven Whitehouse const struct dentry_operations gfs2_dops = {
136b1e71b06SSteven Whitehouse 	.d_revalidate = gfs2_drevalidate,
137b1e71b06SSteven Whitehouse 	.d_hash = gfs2_dhash,
138970343cdSWengang Wang 	.d_delete = gfs2_dentry_delete,
139b1e71b06SSteven Whitehouse };
140b1e71b06SSteven Whitehouse 
141