]> git.hungrycats.org Git - linux/commitdiff
[PATCH] tmpfs 2/7 LTP S_ISGID on directories fix
authorAndrew Morton <akpm@osdl.org>
Wed, 22 Oct 2003 01:19:58 +0000 (18:19 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 22 Oct 2003 01:19:58 +0000 (18:19 -0700)
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.

fs/hugetlbfs/inode.c
fs/ramfs/inode.c
mm/shmem.c

index f3cd58706a8c24371b8642323039eca1e907cae7..05e63d6dce0982183092a6b3a4e3b51d9597c283 100644 (file)
@@ -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);
index 267691bb517423a01a245305875df410ca38bffd..a652b2e39ffa177f7bca4eef7227940b0cc31362 100644 (file)
@@ -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
index b3add61c21d83e77396799cc95d9deda8f31fc6a..59129a23c29e022e2a5601da376eb68a83513571 100644 (file)
@@ -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);