Messages in this thread Patches in this message | | | Date | Sun, 5 Dec 1999 15:48:56 +0100 | From | Jan Kara <> | Subject | Re: Quotas cleanup in 2.3.29 |
| |
> Hello. > > I've done a cleanup in quota code in 2.3.29.. There were some parts from ancient > ages (like testing uid against 0, passing ttys through functions when we can get > them from 'current' and so on..). > I'm also attaching patch which fixes testing of quotafile size and also fixes > testing whether user has rights to get some quota information. Please apply them. I'm sorry. I forgot to attach the files...
Honza. --- linux/kernel/sysctl.c Wed Nov 17 22:22:39 1999 +++ linux/kernel/sysctl.c Wed Nov 17 22:25:03 1999 @@ -351,7 +351,7 @@ } /* Like in_group_p, but testing against egid, not fsgid */ -static int in_egroup_p(gid_t grp) +int in_egroup_p(gid_t grp) { if (grp != current->egid) { int i = current->ngroups; --- linux/include/linux/sched.h Wed Nov 17 22:03:53 1999 +++ linux/include/linux/sched.h Wed Nov 17 22:24:34 1999 @@ -510,6 +510,7 @@ #define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE) extern int in_group_p(gid_t); +extern int in_egroup_p(gid_t); extern void flush_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *); --- linux/fs/dquot.c Wed Nov 17 22:03:04 1999 +++ linux/fs/dquot.c Wed Nov 17 23:06:16 1999 @@ -1458,9 +1458,9 @@ static inline int check_quotafile_size(loff_t size) { ulong blocks = size >> BLOCK_SIZE_BITS; - size_t off = size & ~(BLOCK_SIZE - 1); + size_t off = size & (BLOCK_SIZE - 1); - return !((blocks % sizeof(struct dqblk) + off % sizeof(struct dqblk)) % sizeof(struct dqblk)); + return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk)); } int quota_on(kdev_t dev, short type, char *path) @@ -1555,7 +1555,7 @@ break; case Q_GETQUOTA: if (((type == USRQUOTA && current->euid != id) || - (type == GRPQUOTA && in_group_p(id))) && + (type == GRPQUOTA && in_egroup_p(id))) && !capable(CAP_SYS_RESOURCE)) goto out; break;--- linux/include/linux/quota.h Thu Nov 18 19:12:08 1999 +++ linux/include/linux/quota.h Fri Dec 3 21:59:38 1999 @@ -44,8 +44,8 @@ /* * Convert diskblocks to blocks and the other way around. */ -#define dbtob(num) (num << 10) -#define btodb(num) (num >> 10) +#define dbtob(num) (num << BLOCK_SIZE_BITS) +#define btodb(num) (num >> BLOCK_SIZE_BITS) /* * Convert count of filesystem blocks to diskquota blocks, meant --- linux/include/linux/quotaops.h Thu Nov 18 19:12:09 1999 +++ linux/include/linux/quotaops.h Fri Dec 3 22:49:45 1999 @@ -23,16 +23,13 @@ extern int quota_off(kdev_t dev, short type); extern int sync_dquots(kdev_t dev, short type); -extern int dquot_alloc_block(const struct inode *inode, unsigned long number, - uid_t initiator, char warn); -extern int dquot_alloc_inode(const struct inode *inode, unsigned long number, - uid_t initiator); +extern int dquot_alloc_block(const struct inode *inode, unsigned long number, char prealloc); +extern int dquot_alloc_inode(const struct inode *inode, unsigned long number); extern void dquot_free_block(const struct inode *inode, unsigned long number); extern void dquot_free_inode(const struct inode *inode, unsigned long number); -extern int dquot_transfer(struct dentry *dentry, struct iattr *iattr, - uid_t initiator); +extern int dquot_transfer(struct dentry *dentry, struct iattr *iattr); /* * Operations supported for diskquotas. @@ -54,8 +51,7 @@ extern __inline__ int DQUOT_PREALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr) { if (sb->dq_op) { - if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), - current->fsuid, 0) == NO_QUOTA) + if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 1) == NO_QUOTA) return 1; } return 0; @@ -64,8 +60,7 @@ extern __inline__ int DQUOT_ALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr) { if (sb->dq_op) { - if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), - current->fsuid, 1) == NO_QUOTA) + if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 0) == NO_QUOTA) return 1; } return 0; @@ -75,7 +70,7 @@ { if (sb->dq_op) { sb->dq_op->initialize (inode, -1); - if (sb->dq_op->alloc_inode (inode, 1, current->fsuid)) + if (sb->dq_op->alloc_inode (inode, 1)) return 1; } inode->i_flags |= S_QUOTA; @@ -100,7 +95,7 @@ if (dentry->d_inode->i_sb->dq_op) { dentry->d_inode->i_sb->dq_op->initialize(dentry->d_inode, -1); - error = dentry->d_inode->i_sb->dq_op->transfer(dentry, iattr, current->fsuid); + error = dentry->d_inode->i_sb->dq_op->transfer(dentry, iattr); } else { error = notify_change(dentry, iattr); } --- linux/include/linux/fs.h Fri Dec 3 22:39:44 1999 +++ linux/include/linux/fs.h Fri Dec 3 22:45:05 1999 @@ -678,11 +678,11 @@ struct dquot_operations { void (*initialize) (struct inode *, short); void (*drop) (struct inode *); - int (*alloc_block) (const struct inode *, unsigned long, uid_t, char); - int (*alloc_inode) (const struct inode *, unsigned long, uid_t); + int (*alloc_block) (const struct inode *, unsigned long, char); + int (*alloc_inode) (const struct inode *, unsigned long); void (*free_block) (const struct inode *, unsigned long); void (*free_inode) (const struct inode *, unsigned long); - int (*transfer) (struct dentry *, struct iattr *, uid_t); + int (*transfer) (struct dentry *, struct iattr *); }; struct file_system_type { --- linux/fs/dquot.c Fri Dec 3 22:39:03 1999 +++ linux/fs/dquot.c Fri Dec 3 22:58:29 1999 @@ -786,110 +786,113 @@ dquot->dq_flags |= DQ_MOD; } -static inline char need_print_warning(short type, uid_t initiator, struct dquot *dquot) +static inline int need_print_warning(struct dquot *dquot, int flag) { - switch (type) { + switch (dquot->dq_type) { case USRQUOTA: - return(initiator == dquot->dq_id); + return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag); case GRPQUOTA: - return(initiator == dquot->dq_id); + return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag); } - return(0); + return 0; +} + +static void print_warning(struct dquot *dquot, int flag, char *fmtstr, ...) +{ + va_list args; + + if (!need_print_warning(dquot, flag)) + return; + va_start(args, fmtstr); + vsprintf(quotamessage, fmtstr, args); + va_end(args); + tty_write_message(current->tty, quotamessage); + dquot->dq_flags |= flag; } -static inline char ignore_hardlimit(struct dquot *dquot, uid_t initiator) +static inline char ignore_hardlimit(struct dquot *dquot) { - return(initiator == 0 && dquot->dq_mnt->mnt_dquot.rsquash[dquot->dq_type] == 0); + return capable(CAP_SYS_RESOURCE) && !dquot->dq_mnt->mnt_dquot.rsquash[dquot->dq_type]; } -static int check_idq(struct dquot *dquot, short type, u_long inodes, uid_t initiator, - struct tty_struct *tty) +static int check_idq(struct dquot *dquot, u_long inodes) { + short type = dquot->dq_type; + if (inodes <= 0 || dquot->dq_flags & DQ_FAKE) - return(QUOTA_OK); + return QUOTA_OK; if (dquot->dq_ihardlimit && (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit && - !ignore_hardlimit(dquot, initiator)) { - if ((dquot->dq_flags & DQ_INODES) == 0 && - need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: write failed, %s file limit reached\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); - dquot->dq_flags |= DQ_INODES; - } - return(NO_QUOTA); + !ignore_hardlimit(dquot)) { + print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); + return NO_QUOTA; } if (dquot->dq_isoftlimit && (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit && dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime && - !ignore_hardlimit(dquot, initiator)) { - if (need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: warning, %s file quota exceeded too long.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); - } - return(NO_QUOTA); + !ignore_hardlimit(dquot)) { + print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); + return NO_QUOTA; } if (dquot->dq_isoftlimit && (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit && dquot->dq_itime == 0) { - if (need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: warning, %s file quota exceeded\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); - } + print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[type]; } - return(QUOTA_OK); + return QUOTA_OK; } -static int check_bdq(struct dquot *dquot, short type, u_long blocks, uid_t initiator, - struct tty_struct *tty, char warn) +static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc) { + short type = dquot->dq_type; + if (blocks <= 0 || dquot->dq_flags & DQ_FAKE) - return(QUOTA_OK); + return QUOTA_OK; if (dquot->dq_bhardlimit && (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit && - !ignore_hardlimit(dquot, initiator)) { - if (warn && (dquot->dq_flags & DQ_BLKS) == 0 && - need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: write failed, %s disk limit reached.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); - dquot->dq_flags |= DQ_BLKS; - } - return(NO_QUOTA); + !ignore_hardlimit(dquot)) { + if (!prealloc) + print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); + return NO_QUOTA; } if (dquot->dq_bsoftlimit && (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit && dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime && - !ignore_hardlimit(dquot, initiator)) { - if (warn && need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: write failed, %s disk quota exceeded too long.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); - } - return(NO_QUOTA); + !ignore_hardlimit(dquot)) { + if (!prealloc) + print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); + return NO_QUOTA; } if (dquot->dq_bsoftlimit && (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit && dquot->dq_btime == 0) { - if (warn && need_print_warning(type, initiator, dquot)) { - sprintf(quotamessage, "%s: warning, %s disk quota exceeded\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - tty_write_message(tty, quotamessage); + if (!prealloc) { + print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n", + dquot->dq_mnt->mnt_dirname, quotatypes[type]); + dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type]; } - dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type]; + else + /* + * We don't allow preallocation to exceed softlimit so exceeding will + * be always printed + */ + return NO_QUOTA; } - return(QUOTA_OK); + return QUOTA_OK; } /* @@ -1102,11 +1105,9 @@ /* * Note: this is a blocking operation. */ -int dquot_alloc_block(const struct inode *inode, unsigned long number, uid_t initiator, - char warn) +int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn) { int cnt; - struct tty_struct *tty = current->tty; struct dquot *dquot[MAXQUOTAS]; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1114,7 +1115,7 @@ if (dquot[cnt] == NODQUOT) continue; lock_dquot(dquot[cnt]); - if (check_bdq(dquot[cnt], cnt, number, initiator, tty, warn)) + if (check_bdq(dquot[cnt], number, warn)) goto put_all; } @@ -1140,10 +1141,9 @@ /* * Note: this is a blocking operation. */ -int dquot_alloc_inode(const struct inode *inode, unsigned long number, uid_t initiator) +int dquot_alloc_inode(const struct inode *inode, unsigned long number) { int cnt; - struct tty_struct *tty = current->tty; struct dquot *dquot[MAXQUOTAS]; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1151,7 +1151,7 @@ if (dquot[cnt] == NODQUOT) continue; lock_dquot(dquot[cnt]); - if (check_idq(dquot[cnt], cnt, number, initiator, tty)) + if (check_idq(dquot[cnt], number)) goto put_all; } @@ -1213,13 +1213,12 @@ * * Note: this is a blocking operation. */ -int dquot_transfer(struct dentry *dentry, struct iattr *iattr, uid_t initiator) +int dquot_transfer(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = dentry -> d_inode; unsigned long blocks; struct dquot *transfer_from[MAXQUOTAS]; struct dquot *transfer_to[MAXQUOTAS]; - struct tty_struct *tty = current->tty; short cnt, disc; int error = -EDQUOT; @@ -1293,8 +1292,8 @@ * invalidated or locked... */ if (!transfer_to[cnt]->dq_mnt || !transfer_from[cnt]->dq_mnt || - check_idq(transfer_to[cnt], cnt, 1, initiator, tty) == NO_QUOTA || - check_bdq(transfer_to[cnt], cnt, blocks, initiator, tty, 0) == NO_QUOTA) { + check_idq(transfer_to[cnt], 1) == NO_QUOTA || + check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) { cnt++; goto put_all; } | |