[PATCH 2/3] Mapping for multiple operations

Alin Dobre alin.dobre at elastichosts.com
Wed Oct 2 10:47:34 EDT 2013


From: Alin Dobre <alinmd at gmail.com>

UID-only mapping is now done properly for stat and read access
functionalities.

Signed-off-by: Alin Dobre <alinmd at gmail.com>
---
 fs/idmapfs/file.c   |  6 ++++++
 fs/idmapfs/inode.c  |  6 ++++++
 fs/idmapfs/lookup.c | 23 +++++++++++++++++++++++
 fs/idmapfs/wrapfs.h |  9 ++++++++-
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/fs/idmapfs/file.c b/fs/idmapfs/file.c
index 9825816..df44994 100644
--- a/fs/idmapfs/file.c
+++ b/fs/idmapfs/file.c
@@ -19,7 +19,9 @@ static ssize_t wrapfs_read(struct file *file, char __user *buf,
 	struct dentry *dentry = file->f_path.dentry;
 
 	lower_file = wrapfs_lower_file(file);
+	lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid);
 	err = vfs_read(lower_file, buf, count, ppos);
+	lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid);
 	/* update our inode atime upon a successful lower read */
 	if (err >= 0)
 		fsstack_copy_attr_atime(dentry->d_inode,
@@ -36,7 +38,9 @@ static ssize_t wrapfs_write(struct file *file, const char __user *buf,
 	struct dentry *dentry = file->f_path.dentry;
 
 	lower_file = wrapfs_lower_file(file);
+	lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid);
 	err = vfs_write(lower_file, buf, count, ppos);
+	lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid);
 	/* update our inode times+sizes upon a successful lower write */
 	if (err >= 0) {
 		fsstack_copy_inode_size(dentry->d_inode,
@@ -55,7 +59,9 @@ static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
 	struct dentry *dentry = file->f_path.dentry;
 
 	lower_file = wrapfs_lower_file(file);
+	lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid);
 	err = vfs_readdir(lower_file, filldir, dirent);
+	lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid);
 	file->f_pos = lower_file->f_pos;
 	if (err >= 0)		/* copy the atime */
 		fsstack_copy_attr_atime(dentry->d_inode,
diff --git a/fs/idmapfs/inode.c b/fs/idmapfs/inode.c
index d7fe145..2b80e00 100644
--- a/fs/idmapfs/inode.c
+++ b/fs/idmapfs/inode.c
@@ -23,8 +23,12 @@ static int wrapfs_create(struct inode *dir, struct dentry *dentry,
 	lower_dentry = lower_path.dentry;
 	lower_parent_dentry = lock_parent(lower_dentry);
 
+	lower_dentry->d_inode->i_uid = map_id(lower_dentry->d_inode->i_uid);
+	lower_parent_dentry->d_inode->i_uid = map_id(lower_parent_dentry->d_inode->i_uid);
 	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
 			 want_excl);
+	lower_dentry->d_inode->i_uid = unmap_id(lower_dentry->d_inode->i_uid);
+	lower_parent_dentry->d_inode->i_uid = unmap_id(lower_parent_dentry->d_inode->i_uid);
 	if (err)
 		goto out;
 	err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
@@ -354,7 +358,9 @@ static int wrapfs_permission(struct inode *inode, int mask)
 	int err;
 
 	lower_inode = wrapfs_lower_inode(inode);
+	lower_inode->i_uid=map_id(lower_inode->i_uid);
 	err = inode_permission(lower_inode, mask);
+	lower_inode->i_uid=unmap_id(lower_inode->i_uid);
 	return err;
 }
 
diff --git a/fs/idmapfs/lookup.c b/fs/idmapfs/lookup.c
index fa6e019..999b227 100644
--- a/fs/idmapfs/lookup.c
+++ b/fs/idmapfs/lookup.c
@@ -103,6 +103,7 @@ struct inode *wrapfs_iget(struct super_block *sb, struct inode *lower_inode)
 	struct inode *inode; /* the new inode to return */
 	int err;
 
+	lower_inode->i_uid=map_id(lower_inode->i_uid);
 	inode = iget5_locked(sb, /* our superblock */
 			     /*
 			      * hashval: we use inode number, but we can
@@ -202,7 +203,9 @@ int wrapfs_interpose(struct dentry *dentry, struct super_block *sb,
 	 */
 
 	/* inherit lower inode number for wrapfs's inode */
+	lower_inode->i_uid=map_id(lower_inode->i_uid);
 	inode = wrapfs_iget(sb, lower_inode);
+	lower_inode->i_uid=unmap_id(lower_inode->i_uid);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto out;
@@ -330,3 +333,23 @@ out:
 	dput(parent);
 	return ret;
 }
+
+/*
+ * Maps the id received as parameter, from 1000 to 1001.
+ * Can be used for both UID and GID mapping.
+ */
+int map_id(int id) {
+	if (id == 1000) return 1001;
+	return id;
+}
+
+/*
+ * Maps back the id received as parameter, from 1001 to 1000.
+ * Can be used for both UID and GID backwards mapping.
+ */
+int unmap_id(int id) {
+	if (id == 1001) return 1000;
+	return id;
+}
+
+
diff --git a/fs/idmapfs/wrapfs.h b/fs/idmapfs/wrapfs.h
index a85b07e..59f46bc 100644
--- a/fs/idmapfs/wrapfs.h
+++ b/fs/idmapfs/wrapfs.h
@@ -60,6 +60,10 @@ extern struct inode *wrapfs_iget(struct super_block *sb,
 extern int wrapfs_interpose(struct dentry *dentry, struct super_block *sb,
 			    struct path *lower_path);
 
+/* UID/GID mapping */
+int map_id(int id);
+int unmap_id(int id);
+
 /* file private data */
 struct wrapfs_file_info {
 	struct file *lower_file;
@@ -92,7 +96,10 @@ struct wrapfs_sb_info {
  */
 static inline struct wrapfs_inode_info *WRAPFS_I(const struct inode *inode)
 {
-	return container_of(inode, struct wrapfs_inode_info, vfs_inode);
+	struct wrapfs_inode_info *i;
+	i = container_of(inode, struct wrapfs_inode_info, vfs_inode);
+	i->vfs_inode.i_uid = map_id(i->vfs_inode.i_uid);
+	return i;
 }
 
 /* dentry to private data */
-- 
1.8.3.2




More information about the Kernelnewbies mailing list