Commit d19c7b9d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] tmpfs 2/7 LTP S_ISGID on directories fix

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.
parent 6b006415
...@@ -412,10 +412,18 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, ...@@ -412,10 +412,18 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
static int hugetlbfs_mknod(struct inode *dir, static int hugetlbfs_mknod(struct inode *dir,
struct dentry *dentry, int mode, dev_t dev) struct dentry *dentry, int mode, dev_t dev)
{ {
struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, struct inode *inode;
current->fsgid, mode, dev);
int error = -ENOSPC; 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) { if (inode) {
dir->i_size += PSEUDO_DIRENT_SIZE; dir->i_size += PSEUDO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME;
...@@ -444,9 +452,15 @@ static int hugetlbfs_symlink(struct inode *dir, ...@@ -444,9 +452,15 @@ static int hugetlbfs_symlink(struct inode *dir,
{ {
struct inode *inode; struct inode *inode;
int error = -ENOSPC; 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, inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
current->fsgid, S_IFLNK|S_IRWXUGO, 0); gid, S_IFLNK|S_IRWXUGO, 0);
if (inode) { if (inode) {
int l = strlen(symname)+1; int l = strlen(symname)+1;
error = page_symlink(inode, symname, l); error = page_symlink(inode, symname, l);
......
...@@ -95,6 +95,11 @@ ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -95,6 +95,11 @@ ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int error = -ENOSPC; int error = -ENOSPC;
if (inode) { 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); d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */ dget(dentry); /* Extra count - pin the dentry in core */
error = 0; error = 0;
...@@ -125,6 +130,8 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * ...@@ -125,6 +130,8 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char *
int l = strlen(symname)+1; int l = strlen(symname)+1;
error = page_symlink(inode, symname, l); error = page_symlink(inode, symname, l);
if (!error) { if (!error) {
if (dir->i_mode & S_ISGID)
inode->i_gid = dir->i_gid;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
dget(dentry); dget(dentry);
} else } else
......
...@@ -1395,6 +1395,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -1395,6 +1395,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int error = -ENOSPC; int error = -ENOSPC;
if (inode) { 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_size += BOGO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
...@@ -1531,6 +1536,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s ...@@ -1531,6 +1536,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
set_page_dirty(page); set_page_dirty(page);
page_cache_release(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_size += BOGO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment