[PATCH 63/73] union-mount: Implement union-aware writable open() [ver#2]

From: David Howells
Date: Tue Feb 21 2012 - 14:55:37 EST


From: Valerie Aurora <vaurora@xxxxxxxxxx>

Copy up a file when opened with write permissions. Does not copy up
the file data when O_TRUNC is specified.

Original-author: Valerie Aurora <vaurora@xxxxxxxxxx>
Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

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

diff --git a/fs/namei.c b/fs/namei.c
index dad7bef..4fe8f4c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2521,6 +2521,24 @@ static inline int open_to_namei_flags(int flag)
return flag;
}

+static int open_union_copyup(struct nameidata *nd, struct path *path,
+ int open_flag)
+{
+ struct vfsmount *oldmnt = path->mnt;
+ int error;
+
+ if (open_flag & O_TRUNC)
+ error = union_copyup_len(nd, path, 0);
+ else
+ error = union_copyup(nd, path);
+ if (error)
+ return error;
+ if (oldmnt != path->mnt)
+ mntput(nd->path.mnt);
+
+ return error;
+}
+
/*
* Handle the last step of open()
*/
@@ -2586,6 +2604,13 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
if (!nd->inode->i_op->lookup)
goto exit;
}
+
+ if (acc_mode & MAY_WRITE) {
+ error = open_union_copyup(nd, &nd->path, open_flag);
+ if (error)
+ goto exit;
+ }
+
audit_inode(pathname, nd->path.dentry);
goto ok;
}
@@ -2669,6 +2694,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
if (path->dentry->d_inode->i_op->follow_link)
return NULL;

+ if (acc_mode & MAY_WRITE) {
+ error = open_union_copyup(nd, path, open_flag);
+ if (error)
+ goto exit_dput;
+ }
+
path_to_nameidata(path, nd);
nd->inode = path->dentry->d_inode;
/* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */

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