#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/gfs2_ondisk.h>
#include <linux/crc32.h>
#include <linux/lm_interface.h>
#include "glops.h"
#include "inode.h"
#include "ops_dentry.h"
-#include "ops_export.h"
+#include "ops_fstype.h"
#include "rgrp.h"
#include "util.h"
-static struct dentry *gfs2_decode_fh(struct super_block *sb,
- __u32 *p,
- int fh_len,
- int fh_type,
- int (*acceptable)(void *context,
- struct dentry *dentry),
- void *context)
-{
- __be32 *fh = (__force __be32 *)p;
- struct gfs2_fh_obj fh_obj;
- struct gfs2_inum_host *this, parent;
-
- this = &fh_obj.this;
- fh_obj.imode = DT_UNKNOWN;
- memset(&parent, 0, sizeof(struct gfs2_inum));
-
- switch (fh_len) {
- case GFS2_LARGE_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]);
- fh_obj.imode = be32_to_cpu(fh[8]);
- case GFS2_SMALL_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]);
- break;
- default:
- return NULL;
- }
-
- return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent,
- acceptable, context);
-}
+#define GFS2_SMALL_FH_SIZE 4
+#define GFS2_LARGE_FH_SIZE 8
+#define GFS2_OLD_FH_SIZE 10
static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
int connectable)
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);
-
- fh[8] = cpu_to_be32(inode->i_mode);
- fh[9] = 0; /* pad to double word */
*len = GFS2_LARGE_FH_SIZE;
iput(inode);
* have to return that as a(n invalid) pointer to dentry.
*/
if (IS_ERR(inode))
- return ERR_PTR(PTR_ERR(inode));
+ return ERR_CAST(inode);
dentry = d_alloc_anon(inode);
if (!dentry) {
return dentry;
}
-static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+static struct dentry *gfs2_get_dentry(struct super_block *sb,
+ struct gfs2_inum_host *inum)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
- struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj;
- struct gfs2_inum_host *inum = &fh_obj->this;
struct gfs2_holder i_gh, ri_gh, rgd_gh;
struct gfs2_rgrpd *rgd;
struct inode *inode;
gfs2_glock_dq_uninit(&rgd_gh);
gfs2_glock_dq_uninit(&ri_gh);
- inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode);
+ inode = gfs2_inode_lookup(sb, DT_UNKNOWN,
+ inum->no_addr,
+ 0, 0);
if (!inode)
goto fail;
if (IS_ERR(inode)) {
iput(inode);
goto fail;
}
+
+ /* Pick up the works we bypass in gfs2_inode_lookup */
+ if (inode->i_state & I_NEW)
+ gfs2_set_iop(inode);
+
if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
iput(inode);
goto fail;
return ERR_PTR(error);
}
-struct export_operations gfs2_export_ops = {
- .decode_fh = gfs2_decode_fh,
+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;
+ }
+}
+
+const struct export_operations gfs2_export_ops = {
.encode_fh = gfs2_encode_fh,
+ .fh_to_dentry = gfs2_fh_to_dentry,
+ .fh_to_parent = gfs2_fh_to_parent,
.get_name = gfs2_get_name,
.get_parent = gfs2_get_parent,
- .get_dentry = gfs2_get_dentry,
};