Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3e2a520 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds
Browse files

ufs: NFS support



Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Acked-by: default avatarEvgeniy Dushistov <dushistov@mail.ru>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 08049707
Loading
Loading
Loading
Loading
+52 −0
Original line number Original line Diff line number Diff line
@@ -66,6 +66,7 @@
 */
 */




#include <linux/exportfs.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/bitops.h>


@@ -96,6 +97,56 @@
#include "swab.h"
#include "swab.h"
#include "util.h"
#include "util.h"


static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation)
{
	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
	struct inode *inode;

	if (ino < UFS_ROOTINO || ino > uspi->s_ncg * uspi->s_ipg)
		return ERR_PTR(-ESTALE);

	inode = ufs_iget(sb, ino);
	if (IS_ERR(inode))
		return ERR_CAST(inode);
	if (generation && inode->i_generation != generation) {
		iput(inode);
		return ERR_PTR(-ESTALE);
	}
	return inode;
}

static struct dentry *ufs_fh_to_dentry(struct super_block *sb, struct fid *fid,
				       int fh_len, int fh_type)
{
	return generic_fh_to_dentry(sb, fid, fh_len, fh_type, ufs_nfs_get_inode);
}

static struct dentry *ufs_fh_to_parent(struct super_block *sb, struct fid *fid,
				       int fh_len, int fh_type)
{
	return generic_fh_to_parent(sb, fid, fh_len, fh_type, ufs_nfs_get_inode);
}

static struct dentry *ufs_get_parent(struct dentry *child)
{
	struct qstr dot_dot = {
		.name	= "..",
		.len	= 2,
	};
	ino_t ino;

	ino = ufs_inode_by_name(child->d_inode, &dot_dot);
	if (!ino)
		return ERR_PTR(-ENOENT);
	return d_obtain_alias(ufs_iget(child->d_inode->i_sb, ino));
}

static const struct export_operations ufs_export_ops = {
	.fh_to_dentry	= ufs_fh_to_dentry,
	.fh_to_parent	= ufs_fh_to_parent,
	.get_parent	= ufs_get_parent,
};

#ifdef CONFIG_UFS_DEBUG
#ifdef CONFIG_UFS_DEBUG
/*
/*
 * Print contents of ufs_super_block, useful for debugging
 * Print contents of ufs_super_block, useful for debugging
@@ -990,6 +1041,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
	 * Read ufs_super_block into internal data structures
	 * Read ufs_super_block into internal data structures
	 */
	 */
	sb->s_op = &ufs_super_ops;
	sb->s_op = &ufs_super_ops;
	sb->s_export_op = &ufs_export_ops;
	sb->dq_op = NULL; /***/
	sb->dq_op = NULL; /***/
	sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
	sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);