From d19c7b9daa73f6117d2144c8ac83af468be23345 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Oct 2003 18:19:58 -0700 Subject: [PATCH] [PATCH] tmpfs 2/7 LTP S_ISGID on directories fix From: Hugh Dickins LTP tests the filesystem on /tmp: many failures when tmpfs because it missed the way directories hand down their gid. Also fix ramfs and hugetlbfs. --- fs/hugetlbfs/inode.c | 22 ++++++++++++++++++---- fs/ramfs/inode.c | 7 +++++++ mm/shmem.c | 7 +++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index f3cd58706a8c2..05e63d6dce098 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -412,10 +412,18 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, static int hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { - struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, - current->fsgid, mode, dev); + struct inode *inode; int error = -ENOSPC; - + gid_t gid; + + if (dir->i_mode & S_ISGID) { + gid = dir->i_gid; + if (S_ISDIR(mode)) + mode |= S_ISGID; + } else { + gid = current->fsgid; + } + inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, gid, mode, dev); if (inode) { dir->i_size += PSEUDO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; @@ -444,9 +452,15 @@ static int hugetlbfs_symlink(struct inode *dir, { struct inode *inode; int error = -ENOSPC; + gid_t gid; + + if (dir->i_mode & S_ISGID) + gid = dir->i_gid; + else + gid = current->fsgid; inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, - current->fsgid, S_IFLNK|S_IRWXUGO, 0); + gid, S_IFLNK|S_IRWXUGO, 0); if (inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 267691bb51742..a652b2e39ffa1 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -95,6 +95,11 @@ ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) int error = -ENOSPC; if (inode) { + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + if (S_ISDIR(mode)) + inode->i_mode |= S_ISGID; + } d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ error = 0; @@ -125,6 +130,8 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if (!error) { + if (dir->i_mode & S_ISGID) + inode->i_gid = dir->i_gid; d_instantiate(dentry, inode); dget(dentry); } else diff --git a/mm/shmem.c b/mm/shmem.c index b3add61c21d83..59129a23c29e0 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1395,6 +1395,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) int error = -ENOSPC; if (inode) { + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + if (S_ISDIR(mode)) + inode->i_mode |= S_ISGID; + } dir->i_size += BOGO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; d_instantiate(dentry, inode); @@ -1531,6 +1536,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s set_page_dirty(page); page_cache_release(page); } + if (dir->i_mode & S_ISGID) + inode->i_gid = dir->i_gid; dir->i_size += BOGO_DIRENT_SIZE; dir->i_ctime = dir->i_mtime = CURRENT_TIME; d_instantiate(dentry, inode); -- 2.53.0