-- ------------------------------------------------------------------------ Andreas Gruenbacher, [EMAIL PROTECTED] Contact information: http://www.infosys.tuwien.ac.at/~agruenba
Move kernel umask handling from VFS to underlying FS (patch is against linux-2.2.13) PROBLEM The current VFS applies the current umask to the mode parameter in the create, mkdir, and mknod syscalls prior to passing the mode parameter to the physical filesystems. Some filesystems (especially Posix ACL support for ext2) need the original mode parameter. SOLUTION Remove umask handling from the VFS, and add it to the physical filesystems. DEPENDENCIES VFS, all filesystems that support inode creation (C) Andreas Gruenbacher and Raymond S. Brand diff -Nur linux-2.2.13/fs/affs/namei.c linux-2.2.13-prep/fs/affs/namei.c --- linux-2.2.13/fs/affs/namei.c Sat Apr 24 06:20:37 1999 +++ linux-2.2.13-prep/fs/affs/namei.c Tue Dec 7 05:52:19 1999 @@ -281,7 +281,7 @@ error = affs_add_entry(dir,NULL,inode,dentry,ST_FILE); if (error) goto out_iput; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode); d_instantiate(dentry,inode); mark_inode_dirty(inode); diff -Nur linux-2.2.13/fs/coda/dir.c linux-2.2.13-prep/fs/coda/dir.c --- linux-2.2.13/fs/coda/dir.c Mon Aug 9 21:05:10 1999 +++ linux-2.2.13-prep/fs/coda/dir.c Tue Dec 7 05:52:19 1999 @@ -235,7 +235,7 @@ dircnp = ITOC(dir); error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length, - 0, mode, 0, &newfid, &attrs); + 0, mode & ~current->fs->umask, 0, &newfid, &attrs); if ( error ) { CDEBUG(D_INODE, "create: %s, result %d\n", @@ -280,7 +280,7 @@ dircnp = ITOC(dir); error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length, - 0, mode, rdev, &newfid, &attrs); + 0, mode & ~current->fs->umask, rdev, &newfid, &attrs); if ( error ) { CDEBUG(D_INODE, "mknod: %s, result %d\n", @@ -323,7 +323,7 @@ CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n", name, len, coda_f2s(&(dircnp->c_fid)), mode); - attr.va_mode = mode; + attr.va_mode = mode & ~current->fs->umask; error = venus_mkdir(dir->i_sb, &(dircnp->c_fid), name, len, &newfid, &attr); diff -Nur linux-2.2.13/fs/ext2/ialloc.c linux-2.2.13-prep/fs/ext2/ialloc.c --- linux-2.2.13/fs/ext2/ialloc.c Tue Oct 20 23:08:14 1998 +++ linux-2.2.13-prep/fs/ext2/ialloc.c Tue Dec 7 05:52:19 1999 @@ -460,7 +460,7 @@ cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1); mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); sb->s_dirt = 1; - inode->i_mode = mode; + /*inode->i_mode = mode;*/ /* done in ext2_{create,mkdir,mknod} */ inode->i_sb = sb; inode->i_nlink = 1; inode->i_dev = sb->s_dev; @@ -469,8 +469,8 @@ inode->i_gid = dir->i_gid; else if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; + /*if (S_ISDIR(mode)) + mode |= S_ISGID;*/ /* wrong field, but done in +ext2_{create,mkdir,mknod} anyway */ } else inode->i_gid = current->fsgid; diff -Nur linux-2.2.13/fs/ext2/namei.c linux-2.2.13-prep/fs/ext2/namei.c --- linux-2.2.13/fs/ext2/namei.c Wed Oct 20 02:14:01 1999 +++ linux-2.2.13-prep/fs/ext2/namei.c Tue Dec 7 05:52:19 1999 @@ -370,7 +370,7 @@ return err; inode->i_op = &ext2_file_inode_operations; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; mark_inode_dirty(inode); bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err); if (!bh) { @@ -406,7 +406,7 @@ goto out; inode->i_uid = current->fsuid; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; inode->i_op = NULL; bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err); if (!bh) diff -Nur linux-2.2.13/fs/hfs/dir.c linux-2.2.13-prep/fs/hfs/dir.c --- linux-2.2.13/fs/hfs/dir.c Mon Apr 12 19:03:45 1999 +++ linux-2.2.13-prep/fs/hfs/dir.c Tue Dec 7 05:52:19 1999 @@ -190,7 +190,7 @@ return -EEXIST; if ((error = hfs_cat_create(entry, &key, - (mode & S_IWUSR) ? 0 : HFS_FIL_LOCK, + (mode & ~current->fs->umask & S_IWUSR) ? 0 : +HFS_FIL_LOCK, HFS_SB(dir->i_sb)->s_type, HFS_SB(dir->i_sb)->s_creator, &new))) return error; diff -Nur linux-2.2.13/fs/minix/namei.c linux-2.2.13-prep/fs/minix/namei.c --- linux-2.2.13/fs/minix/namei.c Fri May 14 08:25:58 1999 +++ linux-2.2.13-prep/fs/minix/namei.c Tue Dec 7 05:52:19 1999 @@ -221,7 +221,7 @@ if (!inode) return -ENOSPC; inode->i_op = &minix_file_inode_operations; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; mark_inode_dirty(inode); error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh ,&de); @@ -249,7 +249,7 @@ if (!inode) return -ENOSPC; inode->i_uid = current->fsuid; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) inode->i_op = &minix_file_inode_operations; diff -Nur linux-2.2.13/fs/namei.c linux-2.2.13-prep/fs/namei.c --- linux-2.2.13/fs/namei.c Wed Oct 20 02:14:02 1999 +++ linux-2.2.13-prep/fs/namei.c Tue Dec 7 05:52:19 1999 @@ -652,7 +652,7 @@ struct inode *inode; struct dentry *dentry; - mode &= S_IALLUGO & ~current->fs->umask; + mode &= S_IALLUGO /*& ~current->fs->umask*/; /* done in the filesystem code */ mode |= S_IFREG; dentry = lookup_dentry(pathname, NULL, lookup_flags(flag)); @@ -792,7 +792,7 @@ struct dentry *dir; struct dentry *dentry, *retval; - mode &= ~current->fs->umask; + /*mode &= ~current->fs->umask;*/ /* done in the filesystem code */ dentry = lookup_dentry(filename, NULL, 0); if (IS_ERR(dentry)) return dentry; @@ -893,7 +893,7 @@ goto exit_lock; DQUOT_INIT(dir->d_inode); - mode &= 0777 & ~current->fs->umask; + mode &= 0777 /*& ~current->fs->umask*/; /* done in the filesystem code */ error = dir->d_inode->i_op->mkdir(dir->d_inode, dentry, mode); exit_lock: diff -Nur linux-2.2.13/fs/nfs/dir.c linux-2.2.13-prep/fs/nfs/dir.c --- linux-2.2.13/fs/nfs/dir.c Wed Oct 20 02:14:02 1999 +++ linux-2.2.13-prep/fs/nfs/dir.c Tue Dec 7 05:52:19 1999 @@ -624,7 +624,7 @@ dfprintk(VFS, "NFS: create(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode; + sattr.mode = mode & ~current->fs->umask; sattr.uid = sattr.gid = sattr.size = (unsigned) -1; sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; @@ -654,7 +654,7 @@ dfprintk(VFS, "NFS: mknod(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode; + sattr.mode = mode & ~current->fs->umask; sattr.uid = sattr.gid = sattr.size = (unsigned) -1; if (S_ISCHR(mode) || S_ISBLK(mode)) sattr.size = rdev; /* get out your barf bag */ @@ -683,7 +683,7 @@ dfprintk(VFS, "NFS: mkdir(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode | S_IFDIR; + sattr.mode = (mode & ~current->fs->umask) | S_IFDIR; sattr.uid = sattr.gid = sattr.size = (unsigned) -1; sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; diff -Nur linux-2.2.13/fs/sysv/namei.c linux-2.2.13-prep/fs/sysv/namei.c --- linux-2.2.13/fs/sysv/namei.c Fri May 14 08:25:58 1999 +++ linux-2.2.13-prep/fs/sysv/namei.c Tue Dec 7 05:52:19 1999 @@ -204,7 +204,7 @@ if (!inode) return -ENOSPC; inode->i_op = &sysv_file_inode_operations; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; mark_inode_dirty(inode); error = sysv_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de); @@ -238,7 +238,7 @@ if (!inode) return -ENOSPC; inode->i_uid = current->fsuid; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) inode->i_op = &sysv_file_inode_operations; diff -Nur linux-2.2.13/fs/ufs/namei.c linux-2.2.13-prep/fs/ufs/namei.c --- linux-2.2.13/fs/ufs/namei.c Mon May 10 23:14:28 1999 +++ linux-2.2.13-prep/fs/ufs/namei.c Tue Dec 7 05:52:19 1999 @@ -420,11 +420,11 @@ */ UFSD(("ENTER\n")) - inode = ufs_new_inode (dir, mode, &err); + inode = ufs_new_inode (dir, mode & ~current->fs->umask, &err); if (!inode) return err; inode->i_op = &ufs_file_inode_operations; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; mark_inode_dirty(inode); bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err); if (!bh) { @@ -462,12 +462,12 @@ flags = sb->u.ufs_sb.s_flags; swab = sb->u.ufs_sb.s_swab; - inode = ufs_new_inode (dir, mode, &err); + inode = ufs_new_inode (dir, mode & ~current->fs->umask, &err); if (!inode) goto out; inode->i_uid = current->fsuid; - inode->i_mode = mode; + inode->i_mode = mode & ~current->fs->umask; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) inode->i_op = &ufs_file_inode_operations; diff -Nur linux-2.2.13/fs/umsdos/namei.c linux-2.2.13-prep/fs/umsdos/namei.c --- linux-2.2.13/fs/umsdos/namei.c Sat Apr 24 06:20:38 1999 +++ linux-2.2.13-prep/fs/umsdos/namei.c Tue Dec 7 16:42:54 1999 @@ -299,7 +299,7 @@ */ int UMSDOS_create (struct inode *dir, struct dentry *dentry, int mode) { - return umsdos_create_any (dir, dentry, mode, 0, 0); + return umsdos_create_any (dir, dentry, mode & ~current->fs->umask, 0, 0); } @@ -759,7 +759,7 @@ if (ret) goto out; - info.entry.mode = mode | S_IFDIR; + info.entry.mode = (mode & ~current->fs->umask) | S_IFDIR; info.entry.rdev = 0; info.entry.uid = current->fsuid; info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; @@ -845,7 +845,7 @@ int UMSDOS_mknod (struct inode *dir, struct dentry *dentry, int mode, int rdev) { - return umsdos_create_any (dir, dentry, mode, rdev, 0); + return umsdos_create_any (dir, dentry, mode & ~current->fs->umask, rdev, 0); } /*