#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_export.h"
#include "xfs_inode.h"
#include "xfs_vfsops.h"
-static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
-
/*
* Note that we only accept fileids which are long enough rather than allow
* the parent generation number to default to zero. XFS considers zero a
int len;
/* Directories don't need their parent encoded, they have ".." */
- if (S_ISDIR(inode->i_mode))
+ if (S_ISDIR(inode->i_mode) || !connectable)
fileid_type = FILEID_INO32_GEN;
else
fileid_type = FILEID_INO32_GEN_PARENT;
if (!ip)
return ERR_PTR(-EIO);
- if (!ip->i_d.di_mode || ip->i_d.di_gen != generation) {
+ if (ip->i_d.di_gen != generation) {
xfs_iput_new(ip, XFS_ILOCK_SHARED);
return ERR_PTR(-ENOENT);
}
xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return ip->i_vnode;
+ return VFS_I(ip);
}
STATIC struct dentry *
{
struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
struct inode *inode = NULL;
- struct dentry *result;
if (fh_len < xfs_fileid_length(fileid_type))
return NULL;
break;
}
- if (!inode)
- return NULL;
- if (IS_ERR(inode))
- return ERR_PTR(PTR_ERR(inode));
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+ return d_obtain_alias(inode);
}
STATIC struct dentry *
{
struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
struct inode *inode = NULL;
- struct dentry *result;
switch (fileid_type) {
case FILEID_INO32_GEN_PARENT:
break;
}
- if (!inode)
- return NULL;
- if (IS_ERR(inode))
- return ERR_PTR(PTR_ERR(inode));
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+ return d_obtain_alias(inode);
}
STATIC struct dentry *
struct dentry *child)
{
int error;
- bhv_vnode_t *cvp;
- struct dentry *parent;
+ struct xfs_inode *cip;
- cvp = NULL;
- error = xfs_lookup(XFS_I(child->d_inode), &dotdot, &cvp);
+ error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
if (unlikely(error))
return ERR_PTR(-error);
- parent = d_alloc_anon(vn_to_inode(cvp));
- if (unlikely(!parent)) {
- VN_RELE(cvp);
- return ERR_PTR(-ENOMEM);
- }
- return parent;
+ return d_obtain_alias(VFS_I(cip));
}
const struct export_operations xfs_export_operations = {