1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * export.c
4   *
5   * Functions to facilitate NFS exporting
6   *
7   * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
8   */
9  
10  #include <linux/fs.h>
11  #include <linux/types.h>
12  
13  #include <cluster/masklog.h>
14  
15  #include "ocfs2.h"
16  
17  #include "alloc.h"
18  #include "dir.h"
19  #include "dlmglue.h"
20  #include "dcache.h"
21  #include "export.h"
22  #include "inode.h"
23  
24  #include "buffer_head_io.h"
25  #include "suballoc.h"
26  #include "ocfs2_trace.h"
27  
28  struct ocfs2_inode_handle
29  {
30  	u64 ih_blkno;
31  	u32 ih_generation;
32  };
33  
ocfs2_get_dentry(struct super_block * sb,struct ocfs2_inode_handle * handle)34  static struct dentry *ocfs2_get_dentry(struct super_block *sb,
35  		struct ocfs2_inode_handle *handle)
36  {
37  	struct inode *inode;
38  	struct ocfs2_super *osb = OCFS2_SB(sb);
39  	u64 blkno = handle->ih_blkno;
40  	int status, set;
41  	struct dentry *result;
42  
43  	trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno);
44  
45  	if (blkno == 0) {
46  		result = ERR_PTR(-ESTALE);
47  		goto bail;
48  	}
49  
50  	inode = ocfs2_ilookup(sb, blkno);
51  	/*
52  	 * If the inode exists in memory, we only need to check it's
53  	 * generation number
54  	 */
55  	if (inode)
56  		goto check_gen;
57  
58  	/*
59  	 * This will synchronize us against ocfs2_delete_inode() on
60  	 * all nodes
61  	 */
62  	status = ocfs2_nfs_sync_lock(osb, 1);
63  	if (status < 0) {
64  		mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
65  		goto check_err;
66  	}
67  
68  	status = ocfs2_test_inode_bit(osb, blkno, &set);
69  	if (status < 0) {
70  		if (status == -EINVAL) {
71  			/*
72  			 * The blkno NFS gave us doesn't even show up
73  			 * as an inode, we return -ESTALE to be
74  			 * nice
75  			 */
76  			status = -ESTALE;
77  		} else
78  			mlog(ML_ERROR, "test inode bit failed %d\n", status);
79  		goto unlock_nfs_sync;
80  	}
81  
82  	trace_ocfs2_get_dentry_test_bit(status, set);
83  	/* If the inode allocator bit is clear, this inode must be stale */
84  	if (!set) {
85  		status = -ESTALE;
86  		goto unlock_nfs_sync;
87  	}
88  
89  	inode = ocfs2_iget(osb, blkno, 0, 0);
90  
91  unlock_nfs_sync:
92  	ocfs2_nfs_sync_unlock(osb, 1);
93  
94  check_err:
95  	if (status < 0) {
96  		if (status == -ESTALE) {
97  			trace_ocfs2_get_dentry_stale((unsigned long long)blkno,
98  						     handle->ih_generation);
99  		}
100  		result = ERR_PTR(status);
101  		goto bail;
102  	}
103  
104  	if (IS_ERR(inode)) {
105  		mlog_errno(PTR_ERR(inode));
106  		result = ERR_CAST(inode);
107  		goto bail;
108  	}
109  
110  check_gen:
111  	if (handle->ih_generation != inode->i_generation) {
112  		trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
113  						  handle->ih_generation,
114  						  inode->i_generation);
115  		iput(inode);
116  		result = ERR_PTR(-ESTALE);
117  		goto bail;
118  	}
119  
120  	result = d_obtain_alias(inode);
121  	if (IS_ERR(result))
122  		mlog_errno(PTR_ERR(result));
123  
124  bail:
125  	trace_ocfs2_get_dentry_end(result);
126  	return result;
127  }
128  
ocfs2_get_parent(struct dentry * child)129  static struct dentry *ocfs2_get_parent(struct dentry *child)
130  {
131  	int status;
132  	u64 blkno;
133  	struct dentry *parent;
134  	struct inode *dir = d_inode(child);
135  	int set;
136  
137  	trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
138  			       (unsigned long long)OCFS2_I(dir)->ip_blkno);
139  
140  	status = ocfs2_nfs_sync_lock(OCFS2_SB(dir->i_sb), 1);
141  	if (status < 0) {
142  		mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
143  		parent = ERR_PTR(status);
144  		goto bail;
145  	}
146  
147  	status = ocfs2_inode_lock(dir, NULL, 0);
148  	if (status < 0) {
149  		if (status != -ENOENT)
150  			mlog_errno(status);
151  		parent = ERR_PTR(status);
152  		goto unlock_nfs_sync;
153  	}
154  
155  	status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
156  	if (status < 0) {
157  		parent = ERR_PTR(-ENOENT);
158  		goto bail_unlock;
159  	}
160  
161  	status = ocfs2_test_inode_bit(OCFS2_SB(dir->i_sb), blkno, &set);
162  	if (status < 0) {
163  		if (status == -EINVAL) {
164  			status = -ESTALE;
165  		} else
166  			mlog(ML_ERROR, "test inode bit failed %d\n", status);
167  		parent = ERR_PTR(status);
168  		goto bail_unlock;
169  	}
170  
171  	trace_ocfs2_get_dentry_test_bit(status, set);
172  	if (!set) {
173  		status = -ESTALE;
174  		parent = ERR_PTR(status);
175  		goto bail_unlock;
176  	}
177  
178  	parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
179  
180  bail_unlock:
181  	ocfs2_inode_unlock(dir, 0);
182  
183  unlock_nfs_sync:
184  	ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
185  
186  bail:
187  	trace_ocfs2_get_parent_end(parent);
188  
189  	return parent;
190  }
191  
ocfs2_encode_fh(struct inode * inode,u32 * fh_in,int * max_len,struct inode * parent)192  static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len,
193  			   struct inode *parent)
194  {
195  	int len = *max_len;
196  	int type = 1;
197  	u64 blkno;
198  	u32 generation;
199  	__le32 *fh = (__force __le32 *) fh_in;
200  
201  #ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION
202  #error "You go ahead and fix that mess, then.  Somehow"
203  	trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
204  				    dentry->d_name.name,
205  				    fh, len, connectable);
206  #endif
207  
208  	if (parent && (len < 6)) {
209  		*max_len = 6;
210  		type = FILEID_INVALID;
211  		goto bail;
212  	} else if (len < 3) {
213  		*max_len = 3;
214  		type = FILEID_INVALID;
215  		goto bail;
216  	}
217  
218  	blkno = OCFS2_I(inode)->ip_blkno;
219  	generation = inode->i_generation;
220  
221  	trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation);
222  
223  	len = 3;
224  	fh[0] = cpu_to_le32((u32)(blkno >> 32));
225  	fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
226  	fh[2] = cpu_to_le32(generation);
227  
228  	if (parent) {
229  		blkno = OCFS2_I(parent)->ip_blkno;
230  		generation = parent->i_generation;
231  
232  		fh[3] = cpu_to_le32((u32)(blkno >> 32));
233  		fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
234  		fh[5] = cpu_to_le32(generation);
235  
236  		len = 6;
237  		type = 2;
238  
239  		trace_ocfs2_encode_fh_parent((unsigned long long)blkno,
240  					     generation);
241  	}
242  
243  	*max_len = len;
244  
245  bail:
246  	trace_ocfs2_encode_fh_type(type);
247  	return type;
248  }
249  
ocfs2_fh_to_dentry(struct super_block * sb,struct fid * fid,int fh_len,int fh_type)250  static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
251  		struct fid *fid, int fh_len, int fh_type)
252  {
253  	struct ocfs2_inode_handle handle;
254  
255  	if (fh_len < 3 || fh_type > 2)
256  		return NULL;
257  
258  	handle.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[0]) << 32;
259  	handle.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[1]);
260  	handle.ih_generation = le32_to_cpu((__force __le32)fid->raw[2]);
261  	return ocfs2_get_dentry(sb, &handle);
262  }
263  
ocfs2_fh_to_parent(struct super_block * sb,struct fid * fid,int fh_len,int fh_type)264  static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
265  		struct fid *fid, int fh_len, int fh_type)
266  {
267  	struct ocfs2_inode_handle parent;
268  
269  	if (fh_type != 2 || fh_len < 6)
270  		return NULL;
271  
272  	parent.ih_blkno = (u64)le32_to_cpu((__force __le32)fid->raw[3]) << 32;
273  	parent.ih_blkno |= (u64)le32_to_cpu((__force __le32)fid->raw[4]);
274  	parent.ih_generation = le32_to_cpu((__force __le32)fid->raw[5]);
275  	return ocfs2_get_dentry(sb, &parent);
276  }
277  
278  const struct export_operations ocfs2_export_ops = {
279  	.encode_fh	= ocfs2_encode_fh,
280  	.fh_to_dentry	= ocfs2_fh_to_dentry,
281  	.fh_to_parent	= ocfs2_fh_to_parent,
282  	.get_parent	= ocfs2_get_parent,
283  	.flags		= EXPORT_OP_ASYNC_LOCK,
284  };
285