From: Hugh Dickins <hugh@veritas.com>

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);

_