--- quota-fs.c.bak 2006-06-22 21:34:44.000000000 -0400 +++ quota-fs.c 2006-06-22 23:57:40.000000000 -0400 @@ -166,7 +166,11 @@ static const char *const * fs_quota_root_get_resources(struct quota_root *root __attr_unused__) { - static const char *resources[] = { QUOTA_NAME_STORAGE, NULL }; + static const char *resources[] = { + QUOTA_NAME_STORAGE, + QUOTA_NAME_MESSAGES, + NULL + }; return resources; } @@ -180,72 +184,99 @@ #ifdef HAVE_Q_QUOTACTL struct quotctl ctl; #endif + int value_r_t, limit_r_t, value_r_c=0, limit_r_c=0; + char args[] = {USRQUOTA , GRPQUOTA }; + short i; *value_r = 0; *limit_r = 0; - if (strcasecmp(name, QUOTA_NAME_STORAGE) != 0 || root->mount == NULL) + if (root->mount == NULL) return 0; + + for (i = 0; i < 2; i++) { + #if defined (HAVE_QUOTACTL) && defined(HAVE_SYS_QUOTA_H) - /* Linux */ + /* Linux */ #ifdef HAVE_LINUX_DQBLK_XFS_H - if (strcmp(root->mount->type, "xfs") == 0) { - /* XFS */ - struct fs_disk_quota xdqblk; + if (strcmp(root->mount->type, "xfs") == 0) { + /* XFS */ + struct fs_disk_quota xdqblk; - if (quotactl(QCMD(Q_XGETQUOTA, USRQUOTA), - root->mount->device_path, - root->uid, (void *)&xdqblk) < 0) { - i_error("quotactl(Q_XGETQUOTA, %s) failed: %m", - root->mount->device_path); - quota_set_error(_root->setup->quota, - "Internal quota error"); - return -1; - } - dqblk.dqb_curblocks = xdqblk.d_bcount << 9; - dqblk.dqb_bsoftlimit = xdqblk.d_blk_softlimit >> 1; - } else + if (quotactl(QCMD(Q_XGETQUOTA, args[i]), + root->mount->device_path, + root->uid, (void *)&xdqblk) < 0) { + i_error("quotactl(Q_XGETQUOTA, %s) failed: %m", + root->mount->device_path); + quota_set_error(_root->setup->quota, + "Internal quota error"); + return -1; + } + dqblk.dqb_curblocks = xdqblk.d_bcount << 9; + dqblk.dqb_curinodes = xdqblk.d_icount << 9; + dqblk.dqb_bsoftlimit = xdqblk.d_blk_softlimit >> 1; + dqblk.dqb_isoftlimit = xdqblk.d_ino_softlimit >> 1; + } else #endif - { - /* ext2, ext3 */ - if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), - root->mount->device_path, + { + /* ext2, ext3 */ + if (quotactl(QCMD(Q_GETQUOTA, args[i]), + root->mount->device_path, + root->uid, (void *)&dqblk) < 0) { + i_error("quotactl(Q_GETQUOTA, %s) failed: %m", + root->mount->device_path); + quota_set_error(_root->setup->quota, + "Internal quota error"); + return -1; + } + } +#elif defined(HAVE_QUOTACTL) + /* BSD, AIX */ + if (quotactl(root->mount->device_path, QCMD(Q_GETQUOTA, args[i]), root->uid, (void *)&dqblk) < 0) { i_error("quotactl(Q_GETQUOTA, %s) failed: %m", root->mount->device_path); - quota_set_error(_root->setup->quota, - "Internal quota error"); + quota_set_error(_root->setup->quota, "Internal quota error"); return -1; } - } -#elif defined(HAVE_QUOTACTL) - /* BSD, AIX */ - if (quotactl(root->mount->device_path, QCMD(Q_GETQUOTA, USRQUOTA), - root->uid, (void *)&dqblk) < 0) { - i_error("quotactl(Q_GETQUOTA, %s) failed: %m", - root->mount->device_path); - quota_set_error(_root->setup->quota, "Internal quota error"); - return -1; - } #else - /* Solaris */ - if (root->mount->fd == -1) - return 0; + /* Solaris */ + if (root->mount->fd == -1) + return 0; - ctl.op = Q_GETQUOTA; - ctl.uid = root->uid; - ctl.addr = (caddr_t)&dqblk; - if (ioctl(root->mount->fd, Q_QUOTACTL, &ctl) < 0) { - i_error("ioctl(%s, Q_QUOTACTL) failed: %m", root->mount->path); - quota_set_error(_root->setup->quota, "Internal quota error"); - return -1; - } + ctl.op = Q_GETQUOTA; + ctl.uid = root->uid; + ctl.addr = (caddr_t)&dqblk; + if (ioctl(root->mount->fd, Q_QUOTACTL, &ctl) < 0) { + i_error("ioctl(%s, Q_QUOTACTL) failed: %m", root->mount->path); + quota_set_error(_root->setup->quota, "Internal quota error"); + return -1; + } #endif - *value_r = (uint64_t)dqblk.dqb_curblocks * - (uint64_t)root->mount->blk_size / 1024; - *limit_r = (uint64_t)dqblk.dqb_bsoftlimit * - (uint64_t)root->mount->blk_size / 1024; + if (strcmp(name, QUOTA_NAME_STORAGE) == 0) { + value_r_t = (uint64_t)dqblk.dqb_curblocks * + (uint64_t)root->mount->blk_size / 1024 / 4096; + limit_r_t = (uint64_t)dqblk.dqb_bsoftlimit * + (uint64_t)root->mount->blk_size / 1024 / 4; + } else if (strcmp(name, QUOTA_NAME_MESSAGES) == 0) { + value_r_t = (uint64_t)dqblk.dqb_curinodes; + limit_r_t = (uint64_t)dqblk.dqb_isoftlimit; + } else { + return 0; + } + + if ((limit_r_c == 0 && limit_r_t >= 0) || + (limit_r_t - value_r_t) < (limit_r_c - value_r_c)) { + limit_r_c = limit_r_t; + value_r_c = value_r_t; + } + + } + + *limit_r = limit_r_c; + *value_r = value_r_c; + return 1; }