blob: eaa8c80ace3cdaf683fc0b4eaf50c250e708f66b [file] [log] [blame]
Thomas Gleixner328970d2019-05-24 12:04:05 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Masahiro Yamadafa60ce22021-05-06 18:06:44 -07002/*
Mark Fashehccd979b2005-12-15 14:31:24 -08003 * export.c
4 *
5 * Functions to facilitate NFS exporting
6 *
7 * Copyright (C) 2002, 2005 Oracle. All rights reserved.
Mark Fashehccd979b2005-12-15 14:31:24 -08008 */
9
10#include <linux/fs.h>
11#include <linux/types.h>
12
Mark Fashehccd979b2005-12-15 14:31:24 -080013#include <cluster/masklog.h>
14
15#include "ocfs2.h"
16
wengang wang6ca497a2009-03-06 21:29:10 +080017#include "alloc.h"
Mark Fashehccd979b2005-12-15 14:31:24 -080018#include "dir.h"
19#include "dlmglue.h"
Mark Fasheh379dfe92006-09-08 14:21:03 -070020#include "dcache.h"
Mark Fashehccd979b2005-12-15 14:31:24 -080021#include "export.h"
22#include "inode.h"
23
24#include "buffer_head_io.h"
wengang wang6ca497a2009-03-06 21:29:10 +080025#include "suballoc.h"
Tao Ma781f2002011-02-24 13:50:19 +080026#include "ocfs2_trace.h"
Mark Fashehccd979b2005-12-15 14:31:24 -080027
28struct ocfs2_inode_handle
29{
30 u64 ih_blkno;
31 u32 ih_generation;
32};
33
Christoph Hellwig644f9ab2007-10-21 16:42:15 -070034static struct dentry *ocfs2_get_dentry(struct super_block *sb,
35 struct ocfs2_inode_handle *handle)
Mark Fashehccd979b2005-12-15 14:31:24 -080036{
Mark Fashehccd979b2005-12-15 14:31:24 -080037 struct inode *inode;
wengang wang6ca497a2009-03-06 21:29:10 +080038 struct ocfs2_super *osb = OCFS2_SB(sb);
39 u64 blkno = handle->ih_blkno;
40 int status, set;
Mark Fashehccd979b2005-12-15 14:31:24 -080041 struct dentry *result;
42
Tao Ma781f2002011-02-24 13:50:19 +080043 trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno);
Mark Fashehccd979b2005-12-15 14:31:24 -080044
wengang wang6ca497a2009-03-06 21:29:10 +080045 if (blkno == 0) {
wengang wang6ca497a2009-03-06 21:29:10 +080046 result = ERR_PTR(-ESTALE);
47 goto bail;
Mark Fashehccd979b2005-12-15 14:31:24 -080048 }
49
wengang wang6ca497a2009-03-06 21:29:10 +080050 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;
Mark Fashehccd979b2005-12-15 14:31:24 -080057
wengang wang6ca497a2009-03-06 21:29:10 +080058 /*
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 }
Mark Fashehccd979b2005-12-15 14:31:24 -080067
wengang wang6ca497a2009-03-06 21:29:10 +080068 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 */
wengang wang6ca497a2009-03-06 21:29:10 +080076 status = -ESTALE;
Tao Ma781f2002011-02-24 13:50:19 +080077 } else
wengang wang6ca497a2009-03-06 21:29:10 +080078 mlog(ML_ERROR, "test inode bit failed %d\n", status);
wengang wang6ca497a2009-03-06 21:29:10 +080079 goto unlock_nfs_sync;
80 }
81
Joseph Qi023d4ea2015-04-14 15:43:33 -070082 trace_ocfs2_get_dentry_test_bit(status, set);
wengang wang6ca497a2009-03-06 21:29:10 +080083 /* If the inode allocator bit is clear, this inode must be stale */
84 if (!set) {
wengang wang6ca497a2009-03-06 21:29:10 +080085 status = -ESTALE;
86 goto unlock_nfs_sync;
87 }
88
89 inode = ocfs2_iget(osb, blkno, 0, 0);
90
91unlock_nfs_sync:
92 ocfs2_nfs_sync_unlock(osb, 1);
93
94check_err:
95 if (status < 0) {
96 if (status == -ESTALE) {
Tao Ma781f2002011-02-24 13:50:19 +080097 trace_ocfs2_get_dentry_stale((unsigned long long)blkno,
98 handle->ih_generation);
wengang wang6ca497a2009-03-06 21:29:10 +080099 }
100 result = ERR_PTR(status);
101 goto bail;
102 }
103
104 if (IS_ERR(inode)) {
105 mlog_errno(PTR_ERR(inode));
Kees Cook7585d122017-05-08 14:49:27 -0700106 result = ERR_CAST(inode);
wengang wang6ca497a2009-03-06 21:29:10 +0800107 goto bail;
108 }
109
110check_gen:
Mark Fashehccd979b2005-12-15 14:31:24 -0800111 if (handle->ih_generation != inode->i_generation) {
Tao Ma781f2002011-02-24 13:50:19 +0800112 trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
113 handle->ih_generation,
114 inode->i_generation);
Pan Bian164f7e52018-11-30 14:10:54 -0800115 iput(inode);
wengang wang6ca497a2009-03-06 21:29:10 +0800116 result = ERR_PTR(-ESTALE);
117 goto bail;
Mark Fashehccd979b2005-12-15 14:31:24 -0800118 }
119
Christoph Hellwig44003722008-08-11 15:49:04 +0200120 result = d_obtain_alias(inode);
Al Viroba871672010-12-18 12:10:00 -0500121 if (IS_ERR(result))
wengang wang6ca497a2009-03-06 21:29:10 +0800122 mlog_errno(PTR_ERR(result));
Mark Fashehccd979b2005-12-15 14:31:24 -0800123
wengang wang6ca497a2009-03-06 21:29:10 +0800124bail:
Tao Ma781f2002011-02-24 13:50:19 +0800125 trace_ocfs2_get_dentry_end(result);
Mark Fashehccd979b2005-12-15 14:31:24 -0800126 return result;
127}
128
129static struct dentry *ocfs2_get_parent(struct dentry *child)
130{
131 int status;
132 u64 blkno;
133 struct dentry *parent;
David Howells2b0143b2015-03-17 22:25:59 +0000134 struct inode *dir = d_inode(child);
Shuning Zhange091eab2019-05-13 17:15:56 -0700135 int set;
Mark Fashehccd979b2005-12-15 14:31:24 -0800136
Tao Ma781f2002011-02-24 13:50:19 +0800137 trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
138 (unsigned long long)OCFS2_I(dir)->ip_blkno);
Mark Fashehccd979b2005-12-15 14:31:24 -0800139
Shuning Zhange091eab2019-05-13 17:15:56 -0700140 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
Mark Fashehe63aecb62007-10-18 15:30:42 -0700147 status = ocfs2_inode_lock(dir, NULL, 0);
Mark Fashehccd979b2005-12-15 14:31:24 -0800148 if (status < 0) {
149 if (status != -ENOENT)
150 mlog_errno(status);
151 parent = ERR_PTR(status);
Shuning Zhange091eab2019-05-13 17:15:56 -0700152 goto unlock_nfs_sync;
Mark Fashehccd979b2005-12-15 14:31:24 -0800153 }
154
Mark Fashehbe94d112007-09-11 15:22:06 -0700155 status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
Mark Fashehccd979b2005-12-15 14:31:24 -0800156 if (status < 0) {
157 parent = ERR_PTR(-ENOENT);
158 goto bail_unlock;
159 }
160
Shuning Zhange091eab2019-05-13 17:15:56 -0700161 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
Christoph Hellwig44003722008-08-11 15:49:04 +0200178 parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
Mark Fasheh379dfe92006-09-08 14:21:03 -0700179
Mark Fashehccd979b2005-12-15 14:31:24 -0800180bail_unlock:
Mark Fashehe63aecb62007-10-18 15:30:42 -0700181 ocfs2_inode_unlock(dir, 0);
Mark Fashehccd979b2005-12-15 14:31:24 -0800182
Shuning Zhange091eab2019-05-13 17:15:56 -0700183unlock_nfs_sync:
184 ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
185
Mark Fashehccd979b2005-12-15 14:31:24 -0800186bail:
Tao Ma781f2002011-02-24 13:50:19 +0800187 trace_ocfs2_get_parent_end(parent);
Mark Fashehccd979b2005-12-15 14:31:24 -0800188
189 return parent;
190}
191
Al Virob0b03822012-04-02 14:34:06 -0400192static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len,
193 struct inode *parent)
Mark Fashehccd979b2005-12-15 14:31:24 -0800194{
Mark Fashehccd979b2005-12-15 14:31:24 -0800195 int len = *max_len;
196 int type = 1;
197 u64 blkno;
198 u32 generation;
Mark Fasheh1ca1a112007-04-27 16:01:25 -0700199 __le32 *fh = (__force __le32 *) fh_in;
Mark Fashehccd979b2005-12-15 14:31:24 -0800200
Al Virob0b03822012-04-02 14:34:06 -0400201#ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION
202#error "You go ahead and fix that mess, then. Somehow"
Tao Ma781f2002011-02-24 13:50:19 +0800203 trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
204 dentry->d_name.name,
205 fh, len, connectable);
Al Virob0b03822012-04-02 14:34:06 -0400206#endif
Mark Fashehccd979b2005-12-15 14:31:24 -0800207
Al Virob0b03822012-04-02 14:34:06 -0400208 if (parent && (len < 6)) {
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530209 *max_len = 6;
Namjae Jeon94e07a752013-02-17 15:48:11 +0900210 type = FILEID_INVALID;
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530211 goto bail;
212 } else if (len < 3) {
213 *max_len = 3;
Namjae Jeon94e07a752013-02-17 15:48:11 +0900214 type = FILEID_INVALID;
Mark Fashehccd979b2005-12-15 14:31:24 -0800215 goto bail;
216 }
217
218 blkno = OCFS2_I(inode)->ip_blkno;
219 generation = inode->i_generation;
220
Tao Ma781f2002011-02-24 13:50:19 +0800221 trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation);
Mark Fashehccd979b2005-12-15 14:31:24 -0800222
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
Al Virob0b03822012-04-02 14:34:06 -0400228 if (parent) {
Mark Fashehccd979b2005-12-15 14:31:24 -0800229 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
Mark Fashehccd979b2005-12-15 14:31:24 -0800236 len = 6;
237 type = 2;
238
Tao Ma781f2002011-02-24 13:50:19 +0800239 trace_ocfs2_encode_fh_parent((unsigned long long)blkno,
240 generation);
Mark Fashehccd979b2005-12-15 14:31:24 -0800241 }
Sunil Mushran2bd63212010-01-25 16:57:38 -0800242
Mark Fashehccd979b2005-12-15 14:31:24 -0800243 *max_len = len;
244
245bail:
Tao Ma781f2002011-02-24 13:50:19 +0800246 trace_ocfs2_encode_fh_type(type);
Mark Fashehccd979b2005-12-15 14:31:24 -0800247 return type;
248}
249
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700250static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
251 struct fid *fid, int fh_len, int fh_type)
Mark Fashehccd979b2005-12-15 14:31:24 -0800252{
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700253 struct ocfs2_inode_handle handle;
Mark Fashehccd979b2005-12-15 14:31:24 -0800254
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700255 if (fh_len < 3 || fh_type > 2)
256 return NULL;
Mark Fashehccd979b2005-12-15 14:31:24 -0800257
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700258 handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
259 handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
260 handle.ih_generation = le32_to_cpu(fid->raw[2]);
261 return ocfs2_get_dentry(sb, &handle);
262}
Mark Fashehccd979b2005-12-15 14:31:24 -0800263
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700264static 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;
Mark Fashehccd979b2005-12-15 14:31:24 -0800268
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700269 if (fh_type != 2 || fh_len < 6)
270 return NULL;
Mark Fashehccd979b2005-12-15 14:31:24 -0800271
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700272 parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
273 parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
274 parent.ih_generation = le32_to_cpu(fid->raw[5]);
275 return ocfs2_get_dentry(sb, &parent);
Mark Fashehccd979b2005-12-15 14:31:24 -0800276}
277
Christoph Hellwig39655162007-10-21 16:42:17 -0700278const struct export_operations ocfs2_export_ops = {
Mark Fashehccd979b2005-12-15 14:31:24 -0800279 .encode_fh = ocfs2_encode_fh,
Christoph Hellwig644f9ab2007-10-21 16:42:15 -0700280 .fh_to_dentry = ocfs2_fh_to_dentry,
281 .fh_to_parent = ocfs2_fh_to_parent,
Mark Fashehccd979b2005-12-15 14:31:24 -0800282 .get_parent = ocfs2_get_parent,
Mark Fashehccd979b2005-12-15 14:31:24 -0800283};