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. 25-akpm/fs/hugetlbfs/inode.c | 20 +++++++++++++++++--- 25-akpm/fs/ramfs/inode.c | 7 +++++++ 25-akpm/mm/shmem.c | 7 +++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff -puN fs/hugetlbfs/inode.c~tmpfs-02-gid-fix fs/hugetlbfs/inode.c --- 25/fs/hugetlbfs/inode.c~tmpfs-02-gid-fix Wed Oct 15 12:16:23 2003 +++ 25-akpm/fs/hugetlbfs/inode.c Wed Oct 15 12:16:23 2003 @@ -412,10 +412,18 @@ static struct inode *hugetlbfs_get_inode 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 inod { 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 -puN fs/ramfs/inode.c~tmpfs-02-gid-fix fs/ramfs/inode.c --- 25/fs/ramfs/inode.c~tmpfs-02-gid-fix Wed Oct 15 12:16:23 2003 +++ 25-akpm/fs/ramfs/inode.c Wed Oct 15 12:16:23 2003 @@ -95,6 +95,11 @@ ramfs_mknod(struct inode *dir, struct de 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 * 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 -puN mm/shmem.c~tmpfs-02-gid-fix mm/shmem.c --- 25/mm/shmem.c~tmpfs-02-gid-fix Wed Oct 15 12:16:23 2003 +++ 25-akpm/mm/shmem.c Wed Oct 15 12:16:23 2003 @@ -1395,6 +1395,11 @@ shmem_mknod(struct inode *dir, struct de 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 *d 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); _