OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [ocfs2/] [export.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* -*- mode: c; c-basic-offset: 8; -*-
2
 * vim: noexpandtab sw=8 ts=8 sts=0:
3
 *
4
 * export.c
5
 *
6
 * Functions to facilitate NFS exporting
7
 *
8
 * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2 of the License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public
21
 * License along with this program; if not, write to the
22
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
 * Boston, MA 021110-1307, USA.
24
 */
25
 
26
#include <linux/fs.h>
27
#include <linux/types.h>
28
 
29
#define MLOG_MASK_PREFIX ML_EXPORT
30
#include <cluster/masklog.h>
31
 
32
#include "ocfs2.h"
33
 
34
#include "dir.h"
35
#include "dlmglue.h"
36
#include "dcache.h"
37
#include "export.h"
38
#include "inode.h"
39
 
40
#include "buffer_head_io.h"
41
 
42
struct ocfs2_inode_handle
43
{
44
        u64 ih_blkno;
45
        u32 ih_generation;
46
};
47
 
48
static struct dentry *ocfs2_get_dentry(struct super_block *sb,
49
                struct ocfs2_inode_handle *handle)
50
{
51
        struct inode *inode;
52
        struct dentry *result;
53
 
54
        mlog_entry("(0x%p, 0x%p)\n", sb, handle);
55
 
56
        if (handle->ih_blkno == 0) {
57
                mlog_errno(-ESTALE);
58
                return ERR_PTR(-ESTALE);
59
        }
60
 
61
        inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0);
62
 
63
        if (IS_ERR(inode))
64
                return (void *)inode;
65
 
66
        if (handle->ih_generation != inode->i_generation) {
67
                iput(inode);
68
                return ERR_PTR(-ESTALE);
69
        }
70
 
71
        result = d_alloc_anon(inode);
72
 
73
        if (!result) {
74
                iput(inode);
75
                mlog_errno(-ENOMEM);
76
                return ERR_PTR(-ENOMEM);
77
        }
78
        result->d_op = &ocfs2_dentry_ops;
79
 
80
        mlog_exit_ptr(result);
81
        return result;
82
}
83
 
84
static struct dentry *ocfs2_get_parent(struct dentry *child)
85
{
86
        int status;
87
        u64 blkno;
88
        struct dentry *parent;
89
        struct inode *inode;
90
        struct inode *dir = child->d_inode;
91
 
92
        mlog_entry("(0x%p, '%.*s')\n", child,
93
                   child->d_name.len, child->d_name.name);
94
 
95
        mlog(0, "find parent of directory %llu\n",
96
             (unsigned long long)OCFS2_I(dir)->ip_blkno);
97
 
98
        status = ocfs2_meta_lock(dir, NULL, 0);
99
        if (status < 0) {
100
                if (status != -ENOENT)
101
                        mlog_errno(status);
102
                parent = ERR_PTR(status);
103
                goto bail;
104
        }
105
 
106
        status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
107
        if (status < 0) {
108
                parent = ERR_PTR(-ENOENT);
109
                goto bail_unlock;
110
        }
111
 
112
        inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0);
113
        if (IS_ERR(inode)) {
114
                mlog(ML_ERROR, "Unable to create inode %llu\n",
115
                     (unsigned long long)blkno);
116
                parent = ERR_PTR(-EACCES);
117
                goto bail_unlock;
118
        }
119
 
120
        parent = d_alloc_anon(inode);
121
        if (!parent) {
122
                iput(inode);
123
                parent = ERR_PTR(-ENOMEM);
124
        }
125
 
126
        parent->d_op = &ocfs2_dentry_ops;
127
 
128
bail_unlock:
129
        ocfs2_meta_unlock(dir, 0);
130
 
131
bail:
132
        mlog_exit_ptr(parent);
133
 
134
        return parent;
135
}
136
 
137
static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
138
                           int connectable)
139
{
140
        struct inode *inode = dentry->d_inode;
141
        int len = *max_len;
142
        int type = 1;
143
        u64 blkno;
144
        u32 generation;
145
        __le32 *fh = (__force __le32 *) fh_in;
146
 
147
        mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry,
148
                   dentry->d_name.len, dentry->d_name.name,
149
                   fh, len, connectable);
150
 
151
        if (len < 3 || (connectable && len < 6)) {
152
                mlog(ML_ERROR, "fh buffer is too small for encoding\n");
153
                type = 255;
154
                goto bail;
155
        }
156
 
157
        blkno = OCFS2_I(inode)->ip_blkno;
158
        generation = inode->i_generation;
159
 
160
        mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
161
             (unsigned long long)blkno, generation);
162
 
163
        len = 3;
164
        fh[0] = cpu_to_le32((u32)(blkno >> 32));
165
        fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
166
        fh[2] = cpu_to_le32(generation);
167
 
168
        if (connectable && !S_ISDIR(inode->i_mode)) {
169
                struct inode *parent;
170
 
171
                spin_lock(&dentry->d_lock);
172
 
173
                parent = dentry->d_parent->d_inode;
174
                blkno = OCFS2_I(parent)->ip_blkno;
175
                generation = parent->i_generation;
176
 
177
                fh[3] = cpu_to_le32((u32)(blkno >> 32));
178
                fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
179
                fh[5] = cpu_to_le32(generation);
180
 
181
                spin_unlock(&dentry->d_lock);
182
 
183
                len = 6;
184
                type = 2;
185
 
186
                mlog(0, "Encoding parent: blkno: %llu, generation: %u\n",
187
                     (unsigned long long)blkno, generation);
188
        }
189
 
190
        *max_len = len;
191
 
192
bail:
193
        mlog_exit(type);
194
        return type;
195
}
196
 
197
static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
198
                struct fid *fid, int fh_len, int fh_type)
199
{
200
        struct ocfs2_inode_handle handle;
201
 
202
        if (fh_len < 3 || fh_type > 2)
203
                return NULL;
204
 
205
        handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
206
        handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
207
        handle.ih_generation = le32_to_cpu(fid->raw[2]);
208
        return ocfs2_get_dentry(sb, &handle);
209
}
210
 
211
static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
212
                struct fid *fid, int fh_len, int fh_type)
213
{
214
        struct ocfs2_inode_handle parent;
215
 
216
        if (fh_type != 2 || fh_len < 6)
217
                return NULL;
218
 
219
        parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
220
        parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
221
        parent.ih_generation = le32_to_cpu(fid->raw[5]);
222
        return ocfs2_get_dentry(sb, &parent);
223
}
224
 
225
const struct export_operations ocfs2_export_ops = {
226
        .encode_fh      = ocfs2_encode_fh,
227
        .fh_to_dentry   = ocfs2_fh_to_dentry,
228
        .fh_to_parent   = ocfs2_fh_to_parent,
229
        .get_parent     = ocfs2_get_parent,
230
};

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.