Messages in this thread Patch in this message | | | Subject | [patch] User-space nfsd and quotas | Date | Wed, 03 Mar 1999 11:25:30 +0100 | From | Jan Kasprzak <> |
| |
Hello,
it seems that the user-space NFS-daemon does not honour disk quotas, because quotas are checked against current->euid instead of current->fsuid in include/linux/quotaops.h. The quota system works for knfsd, because of the following (IMHO dirty) hack in fs/nfsd/vfs.c:
#ifdef CONFIG_QUOTA /* This is for disk quota. */ saved_euid = current->euid; current->euid = current->fsuid; err = file.f_op->write(&file, buf, cnt, &file.f_pos); current->euid = saved_euid; #else err = file.f_op->write(&file, buf, cnt, &file.f_pos); #endif
I think not only this is ugly but this allows knfsd to be killed by an ordinary user for some amount of time (the file.f_op->write can block, IIRC). The attached patch removes all the CONFIG_QUOTA stuff from fs/nfsd/vfs.c and modifies include/linux/quotaops.h to check quotas against current->fsuid instead of current->euid.
Am I right there, or there is a better solution of the quota versus user-space nfsd problem on 2.2+ kernels? Please Cc: me in any reply - I may miss the reply otherwise.
-Yenya
--- linux/include/linux/quotaops.h.orig Wed Feb 24 09:39:02 1999 +++ linux/include/linux/quotaops.h Wed Mar 3 11:04:04 1999 @@ -55,7 +55,7 @@ { if (sb->dq_op) { if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), - current->euid, 0) == NO_QUOTA) + current->fsuid, 0) == NO_QUOTA) return 1; } return 0; @@ -65,7 +65,7 @@ { if (sb->dq_op) { if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), - current->euid, 1) == NO_QUOTA) + current->fsuid, 1) == NO_QUOTA) return 1; } return 0; @@ -75,7 +75,7 @@ { if (sb->dq_op) { sb->dq_op->initialize (inode, -1); - if (sb->dq_op->alloc_inode (inode, 1, current->euid)) + if (sb->dq_op->alloc_inode (inode, 1, current->fsuid)) return 1; } inode->i_flags |= S_QUOTA; @@ -101,11 +101,11 @@ if (dentry->d_inode->i_sb->dq_op) { if (IS_QUOTAINIT(dentry->d_inode) == 0) dentry->d_inode->i_sb->dq_op->initialize(dentry->d_inode, -1); - if (dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 0, current->euid)) + if (dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 0, current->fsuid)) goto out; error = notify_change(dentry, iattr); if (error) - dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 1, current->euid); + dentry->d_inode->i_sb->dq_op->transfer(dentry->d_inode, iattr, 1, current->fsuid); } else { error = notify_change(dentry, iattr); } --- linux/fs/nfsd/vfs.c.orig Wed Mar 3 11:13:18 1999 +++ linux/fs/nfsd/vfs.c Wed Mar 3 11:13:43 1999 @@ -508,9 +508,6 @@ struct inode *inode; mm_segment_t oldfs; int err = 0; -#ifdef CONFIG_QUOTA - uid_t saved_euid; -#endif if (!cnt) goto out; @@ -540,15 +537,7 @@ /* Write the data. */ oldfs = get_fs(); set_fs(KERNEL_DS); -#ifdef CONFIG_QUOTA - /* This is for disk quota. */ - saved_euid = current->euid; - current->euid = current->fsuid; err = file.f_op->write(&file, buf, cnt, &file.f_pos); - current->euid = saved_euid; -#else - err = file.f_op->write(&file, buf, cnt, &file.f_pos); -#endif set_fs(oldfs); /* clear setuid/setgid flag after write */ -- \ Jan "Yenya" Kasprzak <kas at fi.muni.cz> http://www.fi.muni.cz/~kas/ \\ PGP: finger kas at aisa.fi.muni.cz 0D99A7FB206605D7 8B35FCDE05B18A5E // \\\ Czech Linux Homepage: http://www.linux.cz/ /// /// Can you say "ignored email" three times quickly while chewing \\\ // on an apple? --Linus Torvalds \\ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |