CINXE.COM
LKML: Miklos Szeredi: [PATCH] private mounts
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>LKML: Miklos Szeredi: [PATCH] private mounts</title><link href="/css/message.css" rel="stylesheet" type="text/css" /><link href="/css/wrap.css" rel="alternate stylesheet" type="text/css" title="wrap" /><link href="/css/nowrap.css" rel="stylesheet" type="text/css" title="nowrap" /><link href="/favicon.ico" rel="shortcut icon" /><script src="/js/simple-calendar.js" type="text/javascript"></script><script src="/js/styleswitcher.js" type="text/javascript"></script><link rel="alternate" type="application/rss+xml" title="lkml.org : last 100 messages" href="/rss.php" /><link rel="alternate" type="application/rss+xml" title="lkml.org : last messages by Miklos Szeredi" href="/groupie.php?aid=1702" /><!--Matomo--><script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(["setDoNotTrack", true]); _paq.push(["disableCookies"]); _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="//m.lkml.org/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '1']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script><!--End Matomo Code--></head><body onload="es.jasper.simpleCalendar.init();" itemscope="itemscope" itemtype="http://schema.org/BlogPosting"><table border="0" cellpadding="0" cellspacing="0"><tr><td width="180" align="center"><a href="/"><img style="border:0;width:135px;height:32px" src="/images/toprowlk.gif" alt="lkml.org" /></a></td><td width="32">聽</td><td class="nb"><div><a class="nb" href="/lkml"> [lkml]</a> 聽 <a class="nb" href="/lkml/2005"> [2005]</a> 聽 <a class="nb" href="/lkml/2005/4"> [Apr]</a> 聽 <a class="nb" href="/lkml/2005/4/24"> [24]</a> 聽 <a class="nb" href="/lkml/last100"> [last100]</a> 聽 <a href="/rss.php"><img src="/images/rss-or.gif" border="0" alt="RSS Feed" /></a></div><div>Views: <a href="#" class="nowrap" onclick="setActiveStyleSheet('wrap');return false;">[wrap]</a><a href="#" class="wrap" onclick="setActiveStyleSheet('nowrap');return false;">[no wrap]</a> 聽 <a class="nb" href="/lkml/mheaders/2005/4/24/76" onclick="this.href='/lkml/headers'+'/2005/4/24/76';">[headers]</a>聽 <a href="/lkml/bounce/2005/4/24/76">[forward]</a>聽 </div></td><td width="32">聽</td></tr><tr><td valign="top"><div class="es-jasper-simpleCalendar" baseurl="/lkml/"></div><div class="threadlist">Messages in this thread</div><ul class="threadlist"><li class="root"><a href="/lkml/2005/4/24/76">First message in thread</a></li><li class="origin"><a href="/lkml/2005/4/24/77">Miklos Szeredi</a><ul><li><a href="/lkml/2005/4/24/77">Al Viro</a><ul><li><a href="/lkml/2005/4/24/86">Miklos Szeredi</a></li></ul></li><li><a href="/lkml/2005/4/24/79">Christoph Hellwig</a><ul><li><a href="/lkml/2005/4/24/87">Miklos Szeredi</a><ul><li><a href="/lkml/2005/4/24/88">Al Viro</a><ul><li><a href="/lkml/2005/4/24/89">Miklos Szeredi</a></li></ul></li></ul></li></ul></li></ul></li></ul><div class="threadlist">Patch in this message</div><ul class="threadlist"><li><a href="/lkml/diff/2005/4/24/76/1">Get diff 1</a></li></ul></td><td width="32" rowspan="2" class="c" valign="top"><img src="/images/icornerl.gif" width="32" height="32" alt="/" /></td><td class="c" rowspan="2" valign="top" style="padding-top: 1em"><table><tr><td><table><tr><td class="lp">Subject</td><td class="rp" itemprop="name">[PATCH] private mounts</td></tr><tr><td class="lp">From</td><td class="rp" itemprop="author">Miklos Szeredi <></td></tr><tr><td class="lp">Date</td><td class="rp" itemprop="datePublished">Sun, 24 Apr 2005 22:08:13 +0200</td></tr></table></td><td></td></tr></table><pre itemprop="articleBody">This simple patch adds support for private (or invisible) mounts. The<br />rationale is to allow mounts to be private for a user but still in the<br />global namespace.<br /><br />An immediate user of this would be FUSE, which currently achieves the<br />hiding of data with inode->permission(), which is less elegant.<br /><br />Christoph, I'm specially interested in your opinion, since you were so<br />strongly opposed to the current solution in FUSE.<br /><br />Performance measurements indicate that the overhead is about 2% of the<br />time spent following mounts, or 6ns per-mount on a 533 Celeron.<br /><br />This patch does:<br /><br /> - add new mount flag: MS_PRIVATE / MNT_PRIVATE<br /> - add new member in struct vfsmount: mnt_uid<br /> - if MNT_PRIVATE is set, set mnt_uid to current->fsuid in<br /> do_add_mount() and do_remount()<br /> - in clone_mnt() copy mnt_uid to the new mount<br /> - in lookup_mnt() while looping through the hash chain for the<br /> mountpoint, check if the mount is "visible" for this process, and<br /> skip it if not<br /><br />Comments are appreciated. If there are no vetoes agains the patch, I<br />think it's suitable for -mm.<br /><br />Thanks,<br />Miklos<br /><br />Signed-off-by: Miklos Szeredi <miklos@szeredi.hu><br /><br />diff -rup orig/linux-2.6.11/fs/namespace.c linux-2.6.11/fs/namespace.c<br />--- orig/linux-2.6.11/fs/namespace.c 2005-03-04 23:18:48.000000000 +0100<br />+++ linux-2.6.11/fs/namespace.c 2005-04-24 12:44:41.000000000 +0200<br />@@ -81,6 +81,15 @@ void free_vfsmnt(struct vfsmount *mnt)<br /> }<br /> <br /> /*<br />+ * Check if this mount should be skipped or not<br />+ */<br />+static inline int mnt_visible(struct vfsmount *mnt)<br />+{<br />+ return !(mnt->mnt_flags & MNT_PRIVATE) ||<br />+ mnt->mnt_uid == current->fsuid;<br />+}<br />+<br />+/*<br /> * Now, lookup_mnt increments the ref count before returning<br /> * the vfsmount struct.<br /> */<br />@@ -97,7 +106,8 @@ struct vfsmount *lookup_mnt(struct vfsmo<br /> if (tmp == head)<br /> break;<br /> p = list_entry(tmp, struct vfsmount, mnt_hash);<br />- if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) {<br />+ if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry &&<br />+ mnt_visible(p)) {<br /> found = mntget(p);<br /> break;<br /> }<br />@@ -155,6 +165,7 @@ clone_mnt(struct vfsmount *old, struct d<br /> <br /> if (mnt) {<br /> mnt->mnt_flags = old->mnt_flags;<br />+ mnt->mnt_uid = old->mnt_uid;<br /> atomic_inc(&sb->s_active);<br /> mnt->mnt_sb = sb;<br /> mnt->mnt_root = dget(root);<br />@@ -234,6 +245,7 @@ static int show_vfsmnt(struct seq_file *<br /> { MNT_NOSUID, ",nosuid" },<br /> { MNT_NODEV, ",nodev" },<br /> { MNT_NOEXEC, ",noexec" },<br />+ { MNT_PRIVATE, ",private" },<br /> { 0, NULL }<br /> };<br /> struct proc_fs_info *fs_infop;<br />@@ -252,6 +264,8 @@ static int show_vfsmnt(struct seq_file *<br /> if (mnt->mnt_flags & fs_infop->flag)<br /> seq_puts(m, fs_infop->str);<br /> }<br />+ if (mnt->mnt_flags & MNT_PRIVATE)<br />+ seq_printf(m, ",mnt_uid=%u", mnt->mnt_uid);<br /> if (mnt->mnt_sb->s_op->show_options)<br /> err = mnt->mnt_sb->s_op->show_options(m, mnt);<br /> seq_puts(m, " 0 0\n");<br />@@ -684,8 +698,11 @@ static int do_remount(struct nameidata *<br /> <br /> down_write(&sb->s_umount);<br /> err = do_remount_sb(sb, flags, data, 0);<br />- if (!err)<br />+ if (!err) {<br /> nd->mnt->mnt_flags=mnt_flags;<br />+ if (mnt_flags & MNT_PRIVATE)<br />+ nd->mnt->mnt_uid = current->fsuid;<br />+ }<br /> up_write(&sb->s_umount);<br /> if (!err)<br /> security_sb_post_remount(nd->mnt, flags, data);<br />@@ -807,6 +824,8 @@ int do_add_mount(struct vfsmount *newmnt<br /> goto unlock;<br /> <br /> newmnt->mnt_flags = mnt_flags;<br />+ if (mnt_flags & MNT_PRIVATE)<br />+ newmnt->mnt_uid = current->fsuid;<br /> err = graft_tree(newmnt, nd);<br /> <br /> if (err == 0 && fslist) {<br />@@ -1033,7 +1052,9 @@ long do_mount(char * dev_name, char * di<br /> mnt_flags |= MNT_NODEV;<br /> if (flags & MS_NOEXEC)<br /> mnt_flags |= MNT_NOEXEC;<br />- flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE);<br />+ if (flags & MS_PRIVATE)<br />+ mnt_flags |= MNT_PRIVATE;<br />+ flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_PRIVATE|MS_ACTIVE);<br /> <br /> /* ... and get the mountpoint */<br /> retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);<br />diff -rup orig/linux-2.6.11/include/linux/fs.h linux-2.6.11/include/linux/fs.h<br />--- orig/linux-2.6.11/include/linux/fs.h 2005-03-04 23:19:05.000000000 +0100<br />+++ linux-2.6.11/include/linux/fs.h 2005-04-24 10:23:33.000000000 +0200<br />@@ -96,6 +96,7 @@ extern int dir_notify_enable;<br /> #define MS_REMOUNT 32 /* Alter flags of a mounted FS */<br /> #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */<br /> #define MS_DIRSYNC 128 /* Directory modifications are synchronous */<br />+#define MS_PRIVATE 256 /* Make this mount invisible to other users */<br /> #define MS_NOATIME 1024 /* Do not update access times. */<br /> #define MS_NODIRATIME 2048 /* Do not update directory access times */<br /> #define MS_BIND 4096<br />diff -rup orig/linux-2.6.11/include/linux/mount.h linux-2.6.11/include/linux/mount.h<br />--- orig/linux-2.6.11/include/linux/mount.h 2004-12-25 11:52:55.000000000 +0100<br />+++ linux-2.6.11/include/linux/mount.h 2005-04-24 10:24:29.000000000 +0200<br />@@ -19,6 +19,7 @@<br /> #define MNT_NOSUID 1<br /> #define MNT_NODEV 2<br /> #define MNT_NOEXEC 4<br />+#define MNT_PRIVATE 8<br /> <br /> struct vfsmount<br /> {<br />@@ -31,6 +32,7 @@ struct vfsmount<br /> struct list_head mnt_child; /* and going through their mnt_child */<br /> atomic_t mnt_count;<br /> int mnt_flags;<br />+ uid_t mnt_uid;<br /> int mnt_expiry_mark; /* true if marked for expiry */<br /> char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */<br /> struct list_head mnt_list;<br />-<br />To unsubscribe from this list: send the line "unsubscribe linux-kernel" in<br />the body of a message to majordomo@vger.kernel.org<br />More majordomo info at <a href="http://vger.kernel.org/majordomo-info.html">http://vger.kernel.org/majordomo-info.html</a><br />Please read the FAQ at <a href="http://www.tux.org/lkml/">http://www.tux.org/lkml/</a><br /></pre></td><td width="32" rowspan="2" class="c" valign="top"><img src="/images/icornerr.gif" width="32" height="32" alt="\" /></td></tr><tr><td align="right" valign="bottom"> 聽 </td></tr><tr><td align="right" valign="bottom">聽</td><td class="c" valign="bottom" style="padding-bottom: 0px"><img src="/images/bcornerl.gif" width="32" height="32" alt="\" /></td><td class="c">聽</td><td class="c" valign="bottom" style="padding-bottom: 0px"><img src="/images/bcornerr.gif" width="32" height="32" alt="/" /></td></tr><tr><td align="right" valign="top" colspan="2"> 聽 </td><td class="lm">Last update: 2005-04-24 22:12 聽聽 [from the cache]<br />漏2003-2020 <a href="http://blog.jasper.es/"><span itemprop="editor">Jasper Spaans</span></a>|hosted at <a href="https://www.digitalocean.com/?refcode=9a8e99d24cf9">Digital Ocean</a> and my Meterkast|<a href="http://blog.jasper.es/categories.html#lkml-ref">Read the blog</a></td><td>聽</td></tr></table><script language="javascript" src="/js/styleswitcher.js" type="text/javascript"></script></body></html>