mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Hyunchul Lee <hyc.lee@gmail.com>
To: Namjae Jeon <linkinjeon@kernel.org>
Cc: Hyunchul Lee <hyc.lee@gmail.com>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 4/7] ntfs: add native_symlink mount option
Date: Fri, 12 Jun 2026 16:33:34 +0900	[thread overview]
Message-ID: <20260612-topic-symlink-v1-4-cc1ebf9528e1@gmail.com> (raw)
In-Reply-To: <20260612-topic-symlink-v1-0-cc1ebf9528e1@gmail.com>

Because bind-mounted subtrees of the volume may resolve to unexpected
locations, change converting junctions and non-relative symbolic links
into paths relative to the NTFS volume to be allowed only if the
native_symlink=rel mount option is specified.

Add the native_symlink=<value> mount option to configure how absolute
symbolic links and mount points (junctions) are handled.
The option accepts "raw" or "rel", with "raw" being the default.

Under "raw", the absolute target path (ni->target) is returned as-is
without translation. Under "rel", ntfs_translate_junction() is called
to rewrite the absolute path as a relative path anchored at the volume
root.

Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
---
 fs/ntfs/file.c   | 14 ++++++++------
 fs/ntfs/inode.c  |  4 ++++
 fs/ntfs/super.c  | 19 +++++++++++++++++++
 fs/ntfs/volume.h |  3 +++
 4 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 6b0dfc56577b..6a7b638e523d 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -22,6 +22,7 @@
 #include "ea.h"
 #include "iomap.h"
 #include "bitmap.h"
+#include "volume.h"
 
 #include <linux/filelock.h>
 
@@ -688,12 +689,13 @@ static const char *ntfs_get_link(struct dentry *dentry, struct inode *inode,
 	if (ni->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT ||
 	    (ni->reparse_tag == IO_REPARSE_TAG_SYMLINK &&
 	     !(ni->reparse_flags & cpu_to_le32(SYMLINK_FLAG_RELATIVE)))) {
-		err = ntfs_translate_symlink_path(dentry, ni->target, &target);
-		if (err < 0)
-			return ERR_PTR(err);
-
-		set_delayed_call(done, kfree_link, target);
-		return target;
+		if (NVolNativeSymlinkRel(ni->vol)) {
+			err = ntfs_translate_symlink_path(dentry, ni->target, &target);
+			if (err < 0)
+				return ERR_PTR(err);
+			set_delayed_call(done, kfree_link, target);
+			return target;
+		}
 	}
 
 	return ni->target;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 07ca799a8f9a..76595f2e30ff 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2378,6 +2378,10 @@ int ntfs_show_options(struct seq_file *sf, struct dentry *root)
 		seq_puts(sf, ",discard");
 	if (NVolDisableSparse(vol))
 		seq_puts(sf, ",disable_sparse");
+	if (NVolNativeSymlinkRel(vol))
+		seq_puts(sf, ",native_symlink=rel");
+	else
+		seq_puts(sf, ",native_symlink=raw");
 	if (vol->sb->s_flags & SB_POSIXACL)
 		seq_puts(sf, ",acl");
 	return 0;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index ca882e946a22..e032a247455c 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -43,6 +43,17 @@ static const struct constant_table ntfs_param_enums[] = {
 	{}
 };
 
+enum {
+	NATIVE_SYMLINK_RAW,
+	NATIVE_SYMLINK_REL,
+};
+
+static const struct constant_table ntfs_native_symlink_enums[] = {
+	{ "raw",		NATIVE_SYMLINK_RAW },
+	{ "rel",		NATIVE_SYMLINK_REL },
+	{}
+};
+
 enum {
 	Opt_uid,
 	Opt_gid,
@@ -66,6 +77,7 @@ enum {
 	Opt_acl,
 	Opt_discard,
 	Opt_nocase,
+	Opt_native_symlink,
 };
 
 static const struct fs_parameter_spec ntfs_parameters[] = {
@@ -91,6 +103,7 @@ static const struct fs_parameter_spec ntfs_parameters[] = {
 	fsparam_flag("discard",			Opt_discard),
 	fsparam_flag("sparse",			Opt_sparse),
 	fsparam_flag("nocase",			Opt_nocase),
+	fsparam_enum("native_symlink",		Opt_native_symlink, ntfs_native_symlink_enums),
 	{}
 };
 
@@ -215,6 +228,12 @@ static int ntfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 		else
 			NVolClearDisableSparse(vol);
 		break;
+	case Opt_native_symlink:
+		if (result.uint_32 == NATIVE_SYMLINK_REL)
+			NVolSetNativeSymlinkRel(vol);
+		else
+			NVolClearNativeSymlinkRel(vol);
+		break;
 	case Opt_sparse:
 		break;
 	default:
diff --git a/fs/ntfs/volume.h b/fs/ntfs/volume.h
index 3348394dbc0d..55298689a7bb 100644
--- a/fs/ntfs/volume.h
+++ b/fs/ntfs/volume.h
@@ -177,6 +177,7 @@ struct ntfs_volume {
  *
  * NV_Discard			Issue discard/TRIM commands for freed clusters.
  * NV_DisableSparse		Disable creation of sparse regions.
+ * NV_NativeSymlinkRel		Translate absolute Windows reparse targets (native_symlink=rel).
  */
 enum {
 	NV_Errors,
@@ -194,6 +195,7 @@ enum {
 	NV_CheckWindowsNames,
 	NV_Discard,
 	NV_DisableSparse,
+	NV_NativeSymlinkRel,
 };
 
 /*
@@ -230,6 +232,7 @@ DEFINE_NVOL_BIT_OPS(HideDotFiles)
 DEFINE_NVOL_BIT_OPS(CheckWindowsNames)
 DEFINE_NVOL_BIT_OPS(Discard)
 DEFINE_NVOL_BIT_OPS(DisableSparse)
+DEFINE_NVOL_BIT_OPS(NativeSymlinkRel)
 
 static inline void ntfs_inc_free_clusters(struct ntfs_volume *vol, s64 nr)
 {

-- 
2.43.0


  parent reply	other threads:[~2026-06-12  7:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-12  7:33 [PATCH 0/7] ntfs: Support Windows native symbolic links Hyunchul Lee
2026-06-12  7:33 ` [PATCH 1/7] ntfs: fix incorrect size of symbolic link Hyunchul Lee
2026-06-12  7:33 ` [PATCH 2/7] ntfs: support following Windows native symlink with relative paths Hyunchul Lee
2026-06-12 16:20   ` CharSyam
2026-06-12  7:33 ` [PATCH 3/7] ntfs: support following Windows native symlink with absolute paths Hyunchul Lee
2026-06-12  7:33 ` Hyunchul Lee [this message]
2026-06-12  7:33 ` [PATCH 5/7] ntfs: clean up target name conversion for WSL symlinks Hyunchul Lee
2026-06-12  7:33 ` [PATCH 6/7] ntfs: support creating Windows native symlinks Hyunchul Lee
2026-06-12 16:28   ` CharSyam
2026-06-12  7:33 ` [PATCH 7/7] docs/fs/ntfs: add mount options to support Windows native symbolic links Hyunchul Lee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260612-topic-symlink-v1-4-cc1ebf9528e1@gmail.com \
    --to=hyc.lee@gmail.com \
    --cc=linkinjeon@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®