[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