Blame view
fs/ocfs2/export.c
6.25 KB
ccd979bdb [PATCH] OCFS2: Th... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* -*- mode: c; c-basic-offset: 8; -*- * vim: noexpandtab sw=8 ts=8 sts=0: * * export.c * * Functions to facilitate NFS exporting * * Copyright (C) 2002, 2005 Oracle. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 021110-1307, USA. */ #include <linux/fs.h> #include <linux/types.h> |
ccd979bdb [PATCH] OCFS2: Th... |
28 29 30 |
#include <cluster/masklog.h> #include "ocfs2.h" |
6ca497a83 ocfs2: fix rare s... |
31 |
#include "alloc.h" |
ccd979bdb [PATCH] OCFS2: Th... |
32 33 |
#include "dir.h" #include "dlmglue.h" |
379dfe9d0 ocfs2: Hook rest ... |
34 |
#include "dcache.h" |
ccd979bdb [PATCH] OCFS2: Th... |
35 36 37 38 |
#include "export.h" #include "inode.h" #include "buffer_head_io.h" |
6ca497a83 ocfs2: fix rare s... |
39 |
#include "suballoc.h" |
781f200cb ocfs2: Remove mas... |
40 |
#include "ocfs2_trace.h" |
ccd979bdb [PATCH] OCFS2: Th... |
41 42 43 44 45 46 |
struct ocfs2_inode_handle { u64 ih_blkno; u32 ih_generation; }; |
644f9ab3b ocfs2: new export... |
47 48 |
static struct dentry *ocfs2_get_dentry(struct super_block *sb, struct ocfs2_inode_handle *handle) |
ccd979bdb [PATCH] OCFS2: Th... |
49 |
{ |
ccd979bdb [PATCH] OCFS2: Th... |
50 |
struct inode *inode; |
6ca497a83 ocfs2: fix rare s... |
51 52 53 |
struct ocfs2_super *osb = OCFS2_SB(sb); u64 blkno = handle->ih_blkno; int status, set; |
ccd979bdb [PATCH] OCFS2: Th... |
54 |
struct dentry *result; |
781f200cb ocfs2: Remove mas... |
55 |
trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno); |
ccd979bdb [PATCH] OCFS2: Th... |
56 |
|
6ca497a83 ocfs2: fix rare s... |
57 |
if (blkno == 0) { |
6ca497a83 ocfs2: fix rare s... |
58 59 |
result = ERR_PTR(-ESTALE); goto bail; |
ccd979bdb [PATCH] OCFS2: Th... |
60 |
} |
6ca497a83 ocfs2: fix rare s... |
61 62 63 64 65 66 67 |
inode = ocfs2_ilookup(sb, blkno); /* * If the inode exists in memory, we only need to check it's * generation number */ if (inode) goto check_gen; |
ccd979bdb [PATCH] OCFS2: Th... |
68 |
|
6ca497a83 ocfs2: fix rare s... |
69 70 71 72 73 74 75 76 77 78 79 80 |
/* * This will synchronize us against ocfs2_delete_inode() on * all nodes */ status = ocfs2_nfs_sync_lock(osb, 1); if (status < 0) { mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d ", status); goto check_err; } status = ocfs2_test_inode_bit(osb, blkno, &set); |
781f200cb ocfs2: Remove mas... |
81 |
trace_ocfs2_get_dentry_test_bit(status, set); |
6ca497a83 ocfs2: fix rare s... |
82 83 84 85 86 87 88 |
if (status < 0) { if (status == -EINVAL) { /* * The blkno NFS gave us doesn't even show up * as an inode, we return -ESTALE to be * nice */ |
6ca497a83 ocfs2: fix rare s... |
89 |
status = -ESTALE; |
781f200cb ocfs2: Remove mas... |
90 |
} else |
6ca497a83 ocfs2: fix rare s... |
91 92 |
mlog(ML_ERROR, "test inode bit failed %d ", status); |
6ca497a83 ocfs2: fix rare s... |
93 94 95 96 97 |
goto unlock_nfs_sync; } /* If the inode allocator bit is clear, this inode must be stale */ if (!set) { |
6ca497a83 ocfs2: fix rare s... |
98 99 100 101 102 103 104 105 106 107 108 109 |
status = -ESTALE; goto unlock_nfs_sync; } inode = ocfs2_iget(osb, blkno, 0, 0); unlock_nfs_sync: ocfs2_nfs_sync_unlock(osb, 1); check_err: if (status < 0) { if (status == -ESTALE) { |
781f200cb ocfs2: Remove mas... |
110 111 |
trace_ocfs2_get_dentry_stale((unsigned long long)blkno, handle->ih_generation); |
6ca497a83 ocfs2: fix rare s... |
112 113 114 115 116 117 118 119 120 121 |
} result = ERR_PTR(status); goto bail; } if (IS_ERR(inode)) { mlog_errno(PTR_ERR(inode)); result = (void *)inode; goto bail; } |
ccd979bdb [PATCH] OCFS2: Th... |
122 |
|
6ca497a83 ocfs2: fix rare s... |
123 |
check_gen: |
ccd979bdb [PATCH] OCFS2: Th... |
124 125 |
if (handle->ih_generation != inode->i_generation) { iput(inode); |
781f200cb ocfs2: Remove mas... |
126 127 128 |
trace_ocfs2_get_dentry_generation((unsigned long long)blkno, handle->ih_generation, inode->i_generation); |
6ca497a83 ocfs2: fix rare s... |
129 130 |
result = ERR_PTR(-ESTALE); goto bail; |
ccd979bdb [PATCH] OCFS2: Th... |
131 |
} |
440037287 [PATCH] switch al... |
132 |
result = d_obtain_alias(inode); |
ba87167c0 switch ocfs2, clo... |
133 |
if (IS_ERR(result)) |
6ca497a83 ocfs2: fix rare s... |
134 |
mlog_errno(PTR_ERR(result)); |
ccd979bdb [PATCH] OCFS2: Th... |
135 |
|
6ca497a83 ocfs2: fix rare s... |
136 |
bail: |
781f200cb ocfs2: Remove mas... |
137 |
trace_ocfs2_get_dentry_end(result); |
ccd979bdb [PATCH] OCFS2: Th... |
138 139 140 141 142 143 144 145 |
return result; } static struct dentry *ocfs2_get_parent(struct dentry *child) { int status; u64 blkno; struct dentry *parent; |
ccd979bdb [PATCH] OCFS2: Th... |
146 |
struct inode *dir = child->d_inode; |
ccd979bdb [PATCH] OCFS2: Th... |
147 |
|
781f200cb ocfs2: Remove mas... |
148 149 |
trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); |
ccd979bdb [PATCH] OCFS2: Th... |
150 |
|
e63aecb65 ocfs2: Rename ocf... |
151 |
status = ocfs2_inode_lock(dir, NULL, 0); |
ccd979bdb [PATCH] OCFS2: Th... |
152 153 154 155 156 157 |
if (status < 0) { if (status != -ENOENT) mlog_errno(status); parent = ERR_PTR(status); goto bail; } |
be94d1170 ocfs2: Provide co... |
158 |
status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno); |
ccd979bdb [PATCH] OCFS2: Th... |
159 160 161 162 |
if (status < 0) { parent = ERR_PTR(-ENOENT); goto bail_unlock; } |
440037287 [PATCH] switch al... |
163 |
parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0)); |
379dfe9d0 ocfs2: Hook rest ... |
164 |
|
ccd979bdb [PATCH] OCFS2: Th... |
165 |
bail_unlock: |
e63aecb65 ocfs2: Rename ocf... |
166 |
ocfs2_inode_unlock(dir, 0); |
ccd979bdb [PATCH] OCFS2: Th... |
167 |
|
ccd979bdb [PATCH] OCFS2: Th... |
168 |
bail: |
781f200cb ocfs2: Remove mas... |
169 |
trace_ocfs2_get_parent_end(parent); |
ccd979bdb [PATCH] OCFS2: Th... |
170 171 172 |
return parent; } |
1ca1a111b ocfs2: fix sparse... |
173 |
static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, |
ccd979bdb [PATCH] OCFS2: Th... |
174 175 176 177 178 179 180 |
int connectable) { struct inode *inode = dentry->d_inode; int len = *max_len; int type = 1; u64 blkno; u32 generation; |
1ca1a111b ocfs2: fix sparse... |
181 |
__le32 *fh = (__force __le32 *) fh_in; |
ccd979bdb [PATCH] OCFS2: Th... |
182 |
|
781f200cb ocfs2: Remove mas... |
183 184 185 |
trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, dentry->d_name.name, fh, len, connectable); |
ccd979bdb [PATCH] OCFS2: Th... |
186 |
|
5fe0c2378 exportfs: Return ... |
187 188 189 190 191 192 |
if (connectable && (len < 6)) { *max_len = 6; type = 255; goto bail; } else if (len < 3) { *max_len = 3; |
ccd979bdb [PATCH] OCFS2: Th... |
193 194 195 196 197 198 |
type = 255; goto bail; } blkno = OCFS2_I(inode)->ip_blkno; generation = inode->i_generation; |
781f200cb ocfs2: Remove mas... |
199 |
trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation); |
ccd979bdb [PATCH] OCFS2: Th... |
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
len = 3; fh[0] = cpu_to_le32((u32)(blkno >> 32)); fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff)); fh[2] = cpu_to_le32(generation); if (connectable && !S_ISDIR(inode->i_mode)) { struct inode *parent; spin_lock(&dentry->d_lock); parent = dentry->d_parent->d_inode; blkno = OCFS2_I(parent)->ip_blkno; generation = parent->i_generation; fh[3] = cpu_to_le32((u32)(blkno >> 32)); fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff)); fh[5] = cpu_to_le32(generation); spin_unlock(&dentry->d_lock); len = 6; type = 2; |
781f200cb ocfs2: Remove mas... |
223 224 |
trace_ocfs2_encode_fh_parent((unsigned long long)blkno, generation); |
ccd979bdb [PATCH] OCFS2: Th... |
225 |
} |
2bd632165 ocfs2/trivial: Re... |
226 |
|
ccd979bdb [PATCH] OCFS2: Th... |
227 228 229 |
*max_len = len; bail: |
781f200cb ocfs2: Remove mas... |
230 |
trace_ocfs2_encode_fh_type(type); |
ccd979bdb [PATCH] OCFS2: Th... |
231 232 |
return type; } |
644f9ab3b ocfs2: new export... |
233 234 |
static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) |
ccd979bdb [PATCH] OCFS2: Th... |
235 |
{ |
644f9ab3b ocfs2: new export... |
236 |
struct ocfs2_inode_handle handle; |
ccd979bdb [PATCH] OCFS2: Th... |
237 |
|
644f9ab3b ocfs2: new export... |
238 239 |
if (fh_len < 3 || fh_type > 2) return NULL; |
ccd979bdb [PATCH] OCFS2: Th... |
240 |
|
644f9ab3b ocfs2: new export... |
241 242 243 244 245 |
handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32; handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]); handle.ih_generation = le32_to_cpu(fid->raw[2]); return ocfs2_get_dentry(sb, &handle); } |
ccd979bdb [PATCH] OCFS2: Th... |
246 |
|
644f9ab3b ocfs2: new export... |
247 248 249 250 |
static struct dentry *ocfs2_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { struct ocfs2_inode_handle parent; |
ccd979bdb [PATCH] OCFS2: Th... |
251 |
|
644f9ab3b ocfs2: new export... |
252 253 |
if (fh_type != 2 || fh_len < 6) return NULL; |
ccd979bdb [PATCH] OCFS2: Th... |
254 |
|
644f9ab3b ocfs2: new export... |
255 256 257 258 |
parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32; parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]); parent.ih_generation = le32_to_cpu(fid->raw[5]); return ocfs2_get_dentry(sb, &parent); |
ccd979bdb [PATCH] OCFS2: Th... |
259 |
} |
396551644 exportfs: make st... |
260 |
const struct export_operations ocfs2_export_ops = { |
ccd979bdb [PATCH] OCFS2: Th... |
261 |
.encode_fh = ocfs2_encode_fh, |
644f9ab3b ocfs2: new export... |
262 263 |
.fh_to_dentry = ocfs2_fh_to_dentry, .fh_to_parent = ocfs2_fh_to_parent, |
ccd979bdb [PATCH] OCFS2: Th... |
264 |
.get_parent = ocfs2_get_parent, |
ccd979bdb [PATCH] OCFS2: Th... |
265 |
}; |