Blame view
fs/gfs2/export.c
4.9 KB
b3b94faa5 [GFS2] The core o... |
1 2 |
/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3a8a9a103 [GFS2] Update cop... |
3 |
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
b3b94faa5 [GFS2] The core o... |
4 5 6 |
* * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions |
e9fc2aa09 [GFS2] Update cop... |
7 |
* of the GNU General Public License version 2. |
b3b94faa5 [GFS2] The core o... |
8 |
*/ |
b3b94faa5 [GFS2] The core o... |
9 10 11 |
#include <linux/spinlock.h> #include <linux/completion.h> #include <linux/buffer_head.h> |
a56942551 knfsd: exportfs: ... |
12 |
#include <linux/exportfs.h> |
5c676f6d3 [GFS2] Macros rem... |
13 |
#include <linux/gfs2_ondisk.h> |
71b86f562 [GFS2] Further up... |
14 |
#include <linux/crc32.h> |
b3b94faa5 [GFS2] The core o... |
15 16 |
#include "gfs2.h" |
5c676f6d3 [GFS2] Macros rem... |
17 |
#include "incore.h" |
b3b94faa5 [GFS2] The core o... |
18 19 20 21 |
#include "dir.h" #include "glock.h" #include "glops.h" #include "inode.h" |
b27605837 GFS2: Rationalise... |
22 |
#include "super.h" |
b3b94faa5 [GFS2] The core o... |
23 |
#include "rgrp.h" |
c752666c1 [GFS2] Fix bug in... |
24 |
#include "util.h" |
b3b94faa5 [GFS2] The core o... |
25 |
|
bb8d8a6f5 [GFS2] Fix sign p... |
26 |
#define GFS2_SMALL_FH_SIZE 4 |
35dcc52e3 [GFS2] Remove i_m... |
27 |
#define GFS2_LARGE_FH_SIZE 8 |
3ebf44902 [GFS2] Accept old... |
28 |
#define GFS2_OLD_FH_SIZE 10 |
bb8d8a6f5 [GFS2] Fix sign p... |
29 |
|
b44b84d76 [GFS2] gfs2 misc ... |
30 |
static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, |
b3b94faa5 [GFS2] The core o... |
31 32 |
int connectable) { |
b44b84d76 [GFS2] gfs2 misc ... |
33 |
__be32 *fh = (__force __be32 *)p; |
b3b94faa5 [GFS2] The core o... |
34 |
struct inode *inode = dentry->d_inode; |
c9fd43078 [GFS2] Tidy up mo... |
35 |
struct super_block *sb = inode->i_sb; |
feaa7bba0 [GFS2] Fix unlink... |
36 |
struct gfs2_inode *ip = GFS2_I(inode); |
b3b94faa5 [GFS2] The core o... |
37 |
|
5fe0c2378 exportfs: Return ... |
38 39 |
if (connectable && (*len < GFS2_LARGE_FH_SIZE)) { *len = GFS2_LARGE_FH_SIZE; |
b3b94faa5 [GFS2] The core o... |
40 |
return 255; |
5fe0c2378 exportfs: Return ... |
41 42 43 44 |
} else if (*len < GFS2_SMALL_FH_SIZE) { *len = GFS2_SMALL_FH_SIZE; return 255; } |
b3b94faa5 [GFS2] The core o... |
45 |
|
dbb7cae2a [GFS2] Clean up i... |
46 47 48 49 |
fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); fh[2] = cpu_to_be32(ip->i_no_addr >> 32); fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
5acd39673 [GFS2] Some furth... |
50 |
*len = GFS2_SMALL_FH_SIZE; |
b3b94faa5 [GFS2] The core o... |
51 |
|
c9fd43078 [GFS2] Tidy up mo... |
52 |
if (!connectable || inode == sb->s_root->d_inode) |
b3b94faa5 [GFS2] The core o... |
53 54 55 56 |
return *len; spin_lock(&dentry->d_lock); inode = dentry->d_parent->d_inode; |
feaa7bba0 [GFS2] Fix unlink... |
57 58 |
ip = GFS2_I(inode); igrab(inode); |
b3b94faa5 [GFS2] The core o... |
59 |
spin_unlock(&dentry->d_lock); |
dbb7cae2a [GFS2] Clean up i... |
60 61 62 63 |
fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); fh[6] = cpu_to_be32(ip->i_no_addr >> 32); fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
5acd39673 [GFS2] Some furth... |
64 |
*len = GFS2_LARGE_FH_SIZE; |
b3b94faa5 [GFS2] The core o... |
65 |
|
feaa7bba0 [GFS2] Fix unlink... |
66 |
iput(inode); |
b3b94faa5 [GFS2] The core o... |
67 68 69 70 71 |
return *len; } struct get_name_filldir { |
629a21e7e [GFS2] split and ... |
72 |
struct gfs2_inum_host inum; |
b3b94faa5 [GFS2] The core o... |
73 74 |
char *name; }; |
3699e3a44 [GFS2] Clean up/s... |
75 76 |
static int get_name_filldir(void *opaque, const char *name, int length, loff_t offset, u64 inum, unsigned int type) |
b3b94faa5 [GFS2] The core o... |
77 |
{ |
3699e3a44 [GFS2] Clean up/s... |
78 |
struct get_name_filldir *gnfd = opaque; |
b3b94faa5 [GFS2] The core o... |
79 |
|
3699e3a44 [GFS2] Clean up/s... |
80 |
if (inum != gnfd->inum.no_addr) |
b3b94faa5 [GFS2] The core o... |
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
return 0; memcpy(gnfd->name, name, length); gnfd->name[length] = 0; return 1; } static int gfs2_get_name(struct dentry *parent, char *name, struct dentry *child) { struct inode *dir = parent->d_inode; struct inode *inode = child->d_inode; struct gfs2_inode *dip, *ip; struct get_name_filldir gnfd; struct gfs2_holder gh; |
cd915493f [GFS2] Change all... |
97 |
u64 offset = 0; |
b3b94faa5 [GFS2] The core o... |
98 |
int error; |
dfe4d34b3 GFS2: Add readahe... |
99 |
struct file_ra_state f_ra = { .start = 0 }; |
b3b94faa5 [GFS2] The core o... |
100 101 102 |
if (!dir) return -EINVAL; |
b3b94faa5 [GFS2] The core o... |
103 104 |
if (!S_ISDIR(dir->i_mode) || !inode) return -EINVAL; |
feaa7bba0 [GFS2] Fix unlink... |
105 106 |
dip = GFS2_I(dir); ip = GFS2_I(inode); |
b3b94faa5 [GFS2] The core o... |
107 108 |
*name = 0; |
dbb7cae2a [GFS2] Clean up i... |
109 110 |
gnfd.inum.no_addr = ip->i_no_addr; gnfd.inum.no_formal_ino = ip->i_no_formal_ino; |
b3b94faa5 [GFS2] The core o... |
111 112 113 114 115 |
gnfd.name = name; error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); if (error) return error; |
dfe4d34b3 GFS2: Add readahe... |
116 |
error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir, &f_ra); |
b3b94faa5 [GFS2] The core o... |
117 118 119 120 121 122 123 124 125 126 127 |
gfs2_glock_dq_uninit(&gh); if (!error && !*name) error = -ENOENT; return error; } static struct dentry *gfs2_get_parent(struct dentry *child) { |
41ced6dcf switch gfs2, clos... |
128 |
return d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1)); |
b3b94faa5 [GFS2] The core o... |
129 |
} |
34c0d1542 gfs2: new export ops |
130 |
static struct dentry *gfs2_get_dentry(struct super_block *sb, |
acf7e2444 GFS2: Be extra ca... |
131 |
struct gfs2_inum_host *inum) |
b3b94faa5 [GFS2] The core o... |
132 |
{ |
5c676f6d3 [GFS2] Macros rem... |
133 |
struct gfs2_sbd *sdp = sb->s_fs_info; |
b3b94faa5 [GFS2] The core o... |
134 |
struct inode *inode; |
b3b94faa5 [GFS2] The core o... |
135 |
|
4667a0ec3 GFS2: Make writeb... |
136 |
inode = gfs2_ilookup(sb, inum->no_addr, 0); |
b3b94faa5 [GFS2] The core o... |
137 |
if (inode) { |
dbb7cae2a [GFS2] Clean up i... |
138 |
if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
b3b94faa5 [GFS2] The core o... |
139 140 141 142 143 |
iput(inode); return ERR_PTR(-ESTALE); } goto out_inode; } |
044b9414c GFS2: Fix inode d... |
144 145 146 147 |
inode = gfs2_lookup_by_inum(sdp, inum->no_addr, &inum->no_formal_ino, GFS2_BLKST_DINODE); if (IS_ERR(inode)) return ERR_CAST(inode); |
b3b94faa5 [GFS2] The core o... |
148 |
|
feaa7bba0 [GFS2] Fix unlink... |
149 |
out_inode: |
41ced6dcf switch gfs2, clos... |
150 |
return d_obtain_alias(inode); |
b3b94faa5 [GFS2] The core o... |
151 |
} |
34c0d1542 gfs2: new export ops |
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { struct gfs2_inum_host this; __be32 *fh = (__force __be32 *)fid->raw; switch (fh_type) { case GFS2_SMALL_FH_SIZE: case GFS2_LARGE_FH_SIZE: case GFS2_OLD_FH_SIZE: this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; this.no_formal_ino |= be32_to_cpu(fh[1]); this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; this.no_addr |= be32_to_cpu(fh[3]); return gfs2_get_dentry(sb, &this); default: return NULL; } } static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { struct gfs2_inum_host parent; __be32 *fh = (__force __be32 *)fid->raw; switch (fh_type) { case GFS2_LARGE_FH_SIZE: case GFS2_OLD_FH_SIZE: parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; parent.no_formal_ino |= be32_to_cpu(fh[5]); parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; parent.no_addr |= be32_to_cpu(fh[7]); return gfs2_get_dentry(sb, &parent); default: return NULL; } } |
396551644 exportfs: make st... |
190 |
const struct export_operations gfs2_export_ops = { |
b3b94faa5 [GFS2] The core o... |
191 |
.encode_fh = gfs2_encode_fh, |
34c0d1542 gfs2: new export ops |
192 193 |
.fh_to_dentry = gfs2_fh_to_dentry, .fh_to_parent = gfs2_fh_to_parent, |
b3b94faa5 [GFS2] The core o... |
194 195 |
.get_name = gfs2_get_name, .get_parent = gfs2_get_parent, |
b3b94faa5 [GFS2] The core o... |
196 |
}; |