Re: [PATCH] namei: root is always mount point

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 28, 2009 at 15:21, Karel Zak <kzak@xxxxxxxxxx> wrote:
> On Tue, Jul 28, 2009 at 01:11:11PM +0200, Sami Kerola wrote:
>> On Mon, Jul 27, 2009 at 14:13, Sami Kerola<kerolasa@xxxxxx> wrote:
>>
>> The only way I could think of making mount point detection work
>> correctly is to stat current inode and and .. in same directory,
>
>  Right.
>
>> compare device numbers and if they differ it's a mount point. In case
>> device number is the same and inode then it must be root. A better
>> patch will follow later, or much later.
>
>  OK, thanks.

I think I got the patch right now.

Now the only question is do you want to keep is_mountpoint as it is
(generic) or will you like to eliminate extra stat by feeding the
function with stat structure as argument. Personally I favor generic
function, but it's not really my call what will end up to be in use.

-- 
   Sami Kerola
   http://www.iki.fi/kerolasa/
From 02739d576ee7a79913225bc8ab31eb0d4b33524a Mon Sep 17 00:00:00 2001
From: Sami Kerola <kerolasa@xxxxxx>
Date: Sun, 4 Oct 2009 13:07:10 +0200
Subject: [PATCH] namei: mount points
Cc: kerolasa@xxxxxx

Signed-off-by: Sami Kerola <kerolasa@xxxxxx>
---
 misc-utils/namei.c |   42 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/misc-utils/namei.c b/misc-utils/namei.c
index b8930cd..9cb5b2d 100644
--- a/misc-utils/namei.c
+++ b/misc-utils/namei.c
@@ -61,6 +61,7 @@ struct namei {
 	int		relstart;	/* offset of relative path in 'abslink' */
 	struct namei	*next;		/* next item */
 	int		level;
+	int		mountpoint;	/* is mount point */
 };
 
 struct idcache {
@@ -208,6 +209,41 @@ readlink_to_namei(struct namei *nm, const char *path)
 	nm->abslink[sz] = '\0';
 }
 
+int is_mountpoint(const char *input_path)
+{
+	struct stat input_stat;
+	struct stat dotdot_stat;
+	char *dotdot_path;
+	/* Good default; most are not. */
+	int return_value = 0;
+
+	lstat(input_path, &input_stat);
+	if (!(S_ISDIR(input_stat.st_mode))) {
+		/* Only directories can be mount points. */
+		return(return_value);
+	}
+
+	/* Append to original directory /.. and stat that.
+	 * Assumptation that you could chop last directory and
+	 * stat that one works only if paths are always absolute. */
+	dotdot_path = malloc(strlen(input_path) + 4);
+	dotdot_path[0] = '\0';
+	strcat(dotdot_path, input_path);
+	strcat(dotdot_path, "/..");
+	stat(dotdot_path, &dotdot_stat);
+
+	if (input_stat.st_dev != dotdot_stat.st_dev) {
+		/* Different device; must be mount point. */
+		return_value = 1;
+	} else if (input_stat.st_ino == dotdot_stat.st_ino) {
+		/* Same device, same inode; must be root */
+		return_value = 1;
+	}
+
+	free(dotdot_path);
+	return(return_value);
+}
+
 static struct namei *
 new_namei(struct namei *parent, const char *path, const char *fname, int lev)
 {
@@ -227,6 +263,8 @@ new_namei(struct namei *parent, const char *path, const char *fname, int lev)
 		err(EXIT_FAILURE, _("out of memory?"));
 	if (lstat(path, &nm->st) == -1)
 		err(EXIT_FAILURE, _("could not stat '%s'"), path);
+	if (flags & NAMEI_MNTS)
+		nm->mountpoint = is_mountpoint(path);
 	return nm;
 }
 
@@ -365,9 +403,7 @@ print_namei(struct namei *nm, char *path)
 
 		strmode(nm->st.st_mode, md);
 
-		if ((flags & NAMEI_MNTS) && prev &&
-		    S_ISDIR(nm->st.st_mode) && S_ISDIR(prev->st.st_mode) &&
-		    prev->st.st_dev != nm->st.st_dev)
+		if ((flags & NAMEI_MNTS) && nm->mountpoint)
 			md[0] = 'D';
 
 		if (!(flags & NAMEI_VERTICAL)) {
-- 
1.6.4.4


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux