diff mbox series

[v2] fs/exfat: add NFS export support

Message ID 20240821125137.36304-1-andrii.polianytsia@globallogic.com (mailing list archive)
State New
Headers show
Series [v2] fs/exfat: add NFS export support | expand

Commit Message

andrii.polianytsia@globallogic.com Aug. 21, 2024, 12:51 p.m. UTC
From: Andrii Polianytsia <andrii.polianytsia@globallogic.com>

Add NFS export support to the exFAT filesystem by implementing
the necessary export operations in fs/exfat/super.c. Enable
exFAT filesystems to be exported and accessed over NFS, enhancing
their utility in networked environments.

Introduce the exfat_export_ops structure, which includes
functions to handle file handles and inode lookups necessary for NFS
operations.

Given the similarities between exFAT and FAT filesystems, and that FAT
supports exporting via NFS, this implementation is based on the existing logic
in the FAT filesystem's NFS export code (fs/fat/nfs.c).

Signed-off-by: Andrii Polianytsia <andrii.polianytsia@globallogic.com>
Signed-off-by: Sergii Boryshchenko <sergii.boryshchenko@globallogic.com>
---
v2
Add information about similar implementation logic
from fs/fat/nfs.c to the commit message.

 fs/exfat/super.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

Comments

Chuck Lever Aug. 21, 2024, 2:08 p.m. UTC | #1
On Wed, Aug 21, 2024 at 03:51:37PM +0300, andrii.polianytsia@globallogic.com wrote:
> From: Andrii Polianytsia <andrii.polianytsia@globallogic.com>
> 
> Add NFS export support to the exFAT filesystem by implementing
> the necessary export operations in fs/exfat/super.c. Enable
> exFAT filesystems to be exported and accessed over NFS, enhancing
> their utility in networked environments.
> 
> Introduce the exfat_export_ops structure, which includes
> functions to handle file handles and inode lookups necessary for NFS
> operations.
> 
> Given the similarities between exFAT and FAT filesystems, and that FAT
> supports exporting via NFS, this implementation is based on the existing logic
> in the FAT filesystem's NFS export code (fs/fat/nfs.c).
> 
> Signed-off-by: Andrii Polianytsia <andrii.polianytsia@globallogic.com>
> Signed-off-by: Sergii Boryshchenko <sergii.boryshchenko@globallogic.com>
> ---
> v2
> Add information about similar implementation logic
> from fs/fat/nfs.c to the commit message.
> 
>  fs/exfat/super.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
> 
> diff --git a/fs/exfat/super.c b/fs/exfat/super.c
> index 323ecebe6f0e..cb6dcafc3007 100644
> --- a/fs/exfat/super.c
> +++ b/fs/exfat/super.c
> @@ -18,6 +18,7 @@
>  #include <linux/nls.h>
>  #include <linux/buffer_head.h>
>  #include <linux/magic.h>
> +#include <linux/exportfs.h>
>  
>  #include "exfat_raw.h"
>  #include "exfat_fs.h"
> @@ -195,6 +196,69 @@ static const struct super_operations exfat_sops = {
>  	.show_options	= exfat_show_options,
>  };
>  
> +/**
> + * exfat_export_get_inode - Get inode for export operations
> + * @sb: Superblock pointer
> + * @ino: Inode number
> + * @generation: Generation number
> + *
> + * Returns pointer to inode or error pointer in case of an error.
> + */
> +static struct inode *exfat_export_get_inode(struct super_block *sb, u64 ino,
> +	u32 generation)
> +{
> +	struct inode *inode = NULL;
> +
> +	if (ino == 0)
> +		return ERR_PTR(-ESTALE);
> +
> +	inode = ilookup(sb, ino);
> +	if (inode && generation && inode->i_generation != generation) {
> +		iput(inode);
> +		return ERR_PTR(-ESTALE);
> +	}
> +
> +	return inode;
> +}
> +
> +/**
> + * exfat_fh_to_dentry - Convert file handle to dentry
> + * @sb: Superblock pointer
> + * @fid: File identifier
> + * @fh_len: Length of the file handle
> + * @fh_type: Type of the file handle
> + *
> + * Returns dentry corresponding to the file handle.
> + */
> +static struct dentry *exfat_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,
> +		exfat_export_get_inode);
> +}
> +
> +/**
> + * exfat_fh_to_parent - Convert file handle to parent dentry
> + * @sb: Superblock pointer
> + * @fid: File identifier
> + * @fh_len: Length of the file handle
> + * @fh_type: Type of the file handle
> + *
> + * Returns parent dentry corresponding to the file handle.
> + */
> +static struct dentry *exfat_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,
> +		exfat_export_get_inode);
> +}
> +
> +static const struct export_operations exfat_export_ops = {
> +	.encode_fh = generic_encode_ino32_fh,
> +	.fh_to_dentry = exfat_fh_to_dentry,
> +	.fh_to_parent = exfat_fh_to_parent,
> +};
> +
>  enum {
>  	Opt_uid,
>  	Opt_gid,
> @@ -633,6 +697,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
>  	sb->s_flags |= SB_NODIRATIME;
>  	sb->s_magic = EXFAT_SUPER_MAGIC;
>  	sb->s_op = &exfat_sops;
> +	sb->s_export_op = &exfat_export_ops;
>  
>  	sb->s_time_gran = 10 * NSEC_PER_MSEC;
>  	sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;
> -- 
> 2.25.1
> 
> 

If NamJae is interested in taking this patch --

Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
diff mbox series

Patch

diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 323ecebe6f0e..cb6dcafc3007 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -18,6 +18,7 @@ 
 #include <linux/nls.h>
 #include <linux/buffer_head.h>
 #include <linux/magic.h>
+#include <linux/exportfs.h>
 
 #include "exfat_raw.h"
 #include "exfat_fs.h"
@@ -195,6 +196,69 @@  static const struct super_operations exfat_sops = {
 	.show_options	= exfat_show_options,
 };
 
+/**
+ * exfat_export_get_inode - Get inode for export operations
+ * @sb: Superblock pointer
+ * @ino: Inode number
+ * @generation: Generation number
+ *
+ * Returns pointer to inode or error pointer in case of an error.
+ */
+static struct inode *exfat_export_get_inode(struct super_block *sb, u64 ino,
+	u32 generation)
+{
+	struct inode *inode = NULL;
+
+	if (ino == 0)
+		return ERR_PTR(-ESTALE);
+
+	inode = ilookup(sb, ino);
+	if (inode && generation && inode->i_generation != generation) {
+		iput(inode);
+		return ERR_PTR(-ESTALE);
+	}
+
+	return inode;
+}
+
+/**
+ * exfat_fh_to_dentry - Convert file handle to dentry
+ * @sb: Superblock pointer
+ * @fid: File identifier
+ * @fh_len: Length of the file handle
+ * @fh_type: Type of the file handle
+ *
+ * Returns dentry corresponding to the file handle.
+ */
+static struct dentry *exfat_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,
+		exfat_export_get_inode);
+}
+
+/**
+ * exfat_fh_to_parent - Convert file handle to parent dentry
+ * @sb: Superblock pointer
+ * @fid: File identifier
+ * @fh_len: Length of the file handle
+ * @fh_type: Type of the file handle
+ *
+ * Returns parent dentry corresponding to the file handle.
+ */
+static struct dentry *exfat_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,
+		exfat_export_get_inode);
+}
+
+static const struct export_operations exfat_export_ops = {
+	.encode_fh = generic_encode_ino32_fh,
+	.fh_to_dentry = exfat_fh_to_dentry,
+	.fh_to_parent = exfat_fh_to_parent,
+};
+
 enum {
 	Opt_uid,
 	Opt_gid,
@@ -633,6 +697,7 @@  static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 	sb->s_flags |= SB_NODIRATIME;
 	sb->s_magic = EXFAT_SUPER_MAGIC;
 	sb->s_op = &exfat_sops;
+	sb->s_export_op = &exfat_export_ops;
 
 	sb->s_time_gran = 10 * NSEC_PER_MSEC;
 	sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;