[PATCH 43/76] union-mount: Basic infrastructure of __lookup_union()

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

 



From: Valerie Aurora <vaurora@xxxxxxxxxx>

Create a very simple version of union lookup.  This patch only looks
up the target in each layer of the union but does not process it in
any way.  Patches to do whiteouts, etc. follow.
---

 fs/namei.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index ce14b07..8f0b504 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1103,6 +1103,81 @@ static void follow_dotdot(struct nameidata *nd)
 	nd->inode = nd->path.dentry->d_inode;
 }
 
+static struct dentry *__lookup_hash(struct qstr *name, struct dentry *base,
+				    struct nameidata *nd);
+
+/**
+ * __lookup_union - Lookup and build union stack
+ * @nd - nameidata for the parent of @topmost
+ * @name - name of target
+ * @topmost - path of the target on the topmost file system
+ *
+ * Do the "union" part of lookup for @topmost - that is, look it up in the
+ * lower layers of its parent directory's union stack.  If @topmost is a
+ * directory, build its union stack.  @topmost is the path of the target in the
+ * topmost layer of the union file system.  It is either a directory or a
+ * negative (non-whiteout) dentry.
+ *
+ * This function may stomp nd->path with the path of the parent directory of
+ * the lower layers, so the caller must save nd->path and restore it
+ * afterwards.
+ */
+static int __lookup_union(struct nameidata *nd, struct qstr *name,
+			  struct path *topmost)
+{
+	struct path lower, parent = nd->path;
+	struct path *path;
+	unsigned int i, layers = parent.dentry->d_sb->s_union_count;
+	int err = 0;
+
+	if (!topmost->dentry->d_inode) {
+		if (d_is_whiteout(topmost->dentry))
+			return 0;
+		if (IS_OPAQUE(parent.dentry->d_inode) &&
+		    !d_is_fallthru(topmost->dentry))
+			return 0;
+	}
+
+	/* If it's positive and not a dir, no lookup needed */
+	if (topmost->dentry->d_inode &&
+	    !S_ISDIR(topmost->dentry->d_inode->i_mode))
+		return 0;
+
+	/* Note: This loop iterates through the union stack of the parent of
+	 * the target, not the target itself.  This function builds the union
+	 * stack of the target (if any).  The union stack of the root directory
+	 * is built at mount.
+	 */
+	for (i = 0; i < layers; i++) {
+		/* Get the parent directory for this layer and lookup
+		 * the target in it.
+		 */
+		path = union_find_dir(parent.dentry, i);
+		if (!path->mnt)
+			continue;
+
+		nd->path = *path;
+		lower.mnt = mntget(nd->path.mnt);
+		mutex_lock(&nd->path.dentry->d_inode->i_mutex);
+		lower.dentry = __lookup_hash(name, nd->path.dentry, nd);
+		mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
+
+		if (IS_ERR(lower.dentry)) {
+			mntput(lower.mnt);
+			err = PTR_ERR(lower.dentry);
+			goto out_err;
+		}
+		/* XXX - do nothing, lookup rule processing in later patches */
+		path_put(&lower);
+	}
+	return 0;
+
+out_err:
+	d_free_unions(topmost->dentry);
+	path_put(&lower);
+	return err;
+}
+
 /*
  * Allocate a dentry with name and parent, and perform a parent
  * directory ->lookup on it. Returns the new dentry, or ERR_PTR

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux