version 1.6.2.1, 2012/02/18 07:35:56 |
version 1.7, 2012/01/29 06:23:20 |
Line 47 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 47 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/mount.h> |
#include <sys/mount.h> |
#include <sys/kauth.h> |
#include <sys/kauth.h> |
|
|
|
#include <quota/quotaprop.h> |
#include <ufs/ufs/quota1.h> |
#include <ufs/ufs/quota1.h> |
#include <ufs/ufs/inode.h> |
#include <ufs/ufs/inode.h> |
#include <ufs/ufs/ufsmount.h> |
#include <ufs/ufs/ufsmount.h> |
|
|
} |
} |
|
|
int |
int |
quota1_handle_cmd_get(struct ufsmount *ump, const struct quotakey *qk, |
quota1_handle_cmd_get(struct ufsmount *ump, int type, int id, |
struct quotaval *qv) |
int defaultq, prop_array_t replies) |
{ |
{ |
struct dquot *dq; |
struct dquot *dq; |
|
struct quotaval qv[QUOTA_NLIMITS]; |
|
prop_dictionary_t dict; |
int error; |
int error; |
struct quotaval blocks, files; |
uint64_t *valuesp[QUOTA_NLIMITS]; |
int idtype; |
valuesp[QUOTA_LIMIT_BLOCK] = &qv[QUOTA_LIMIT_BLOCK].qv_hardlimit; |
id_t id; |
valuesp[QUOTA_LIMIT_FILE] = &qv[QUOTA_LIMIT_FILE].qv_hardlimit; |
|
|
idtype = qk->qk_idtype; |
|
id = qk->qk_id; |
|
|
|
if (ump->um_quotas[idtype] == NULLVP) |
if (ump->um_quotas[type] == NULLVP) |
return ENODEV; |
return ENODEV; |
|
|
if (id == QUOTA_DEFAULTID) { /* we want the grace period of id 0 */ |
if (defaultq) { /* we want the grace period of id 0 */ |
if ((error = dqget(NULLVP, 0, ump, idtype, &dq)) != 0) |
if ((error = dqget(NULLVP, 0, ump, type, &dq)) != 0) |
return error; |
return error; |
|
|
} else { |
} else { |
if ((error = dqget(NULLVP, id, ump, idtype, &dq)) != 0) |
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0) |
return error; |
return error; |
} |
} |
dqblk_to_quotavals(&dq->dq_un.dq1_dqb, &blocks, &files); |
dqblk_to_quotavals(&dq->dq_un.dq1_dqb, |
|
&qv[QUOTA_LIMIT_BLOCK], &qv[QUOTA_LIMIT_FILE]); |
dqrele(NULLVP, dq); |
dqrele(NULLVP, dq); |
if (id == QUOTA_DEFAULTID) { |
if (defaultq) { |
if (blocks.qv_expiretime > 0) |
if (qv[QUOTA_LIMIT_BLOCK].qv_expiretime > 0) |
blocks.qv_grace = blocks.qv_expiretime; |
qv[QUOTA_LIMIT_BLOCK].qv_grace = |
|
qv[QUOTA_LIMIT_BLOCK].qv_expiretime; |
else |
else |
blocks.qv_grace = MAX_DQ_TIME; |
qv[QUOTA_LIMIT_BLOCK].qv_grace = MAX_DQ_TIME; |
if (files.qv_expiretime > 0) |
if (qv[QUOTA_LIMIT_FILE].qv_expiretime > 0) |
files.qv_grace = files.qv_expiretime; |
qv[QUOTA_LIMIT_FILE].qv_grace = |
|
qv[QUOTA_LIMIT_FILE].qv_expiretime; |
else |
else |
files.qv_grace = MAX_DQ_TIME; |
qv[QUOTA_LIMIT_FILE].qv_grace = MAX_DQ_TIME; |
} |
} |
|
dict = quota64toprop(id, defaultq, valuesp, |
switch (qk->qk_objtype) { |
ufs_quota_entry_names, UFS_QUOTA_NENTRIES, |
case QUOTA_OBJTYPE_BLOCKS: |
ufs_quota_limit_names, QUOTA_NLIMITS); |
*qv = blocks; |
if (dict == NULL) |
break; |
return ENOMEM; |
case QUOTA_OBJTYPE_FILES: |
if (!prop_array_add_and_rel(replies, dict)) |
*qv = files; |
return ENOMEM; |
break; |
|
default: |
|
return EINVAL; |
|
} |
|
|
|
return 0; |
return 0; |
} |
} |
|
|
static uint32_t |
|
quota1_encode_limit(uint64_t lim) |
|
{ |
|
if (lim == QUOTA_NOLIMIT || lim >= 0xffffffff) { |
|
return 0; |
|
} |
|
return lim; |
|
} |
|
|
|
int |
int |
quota1_handle_cmd_put(struct ufsmount *ump, const struct quotakey *key, |
quota1_handle_cmd_set(struct ufsmount *ump, int type, int id, |
const struct quotaval *val) |
int defaultq, prop_dictionary_t data) |
{ |
{ |
struct dquot *dq; |
struct dquot *dq; |
struct dqblk dqb; |
struct dqblk dqb; |
int error; |
int error; |
|
uint64_t bval[2]; |
|
uint64_t ival[2]; |
|
const char *val_limitsonly_grace[] = {QUOTADICT_LIMIT_GTIME}; |
|
#define Q1_GTIME 0 |
|
const char *val_limitsonly_softhard[] = |
|
{QUOTADICT_LIMIT_SOFT, QUOTADICT_LIMIT_HARD}; |
|
#define Q1_SOFT 0 |
|
#define Q1_HARD 1 |
|
|
|
uint64_t *valuesp[QUOTA_NLIMITS]; |
|
valuesp[QUOTA_LIMIT_BLOCK] = bval; |
|
valuesp[QUOTA_LIMIT_FILE] = ival; |
|
|
switch (key->qk_idtype) { |
if (ump->um_quotas[type] == NULLVP) |
case QUOTA_IDTYPE_USER: |
|
case QUOTA_IDTYPE_GROUP: |
|
break; |
|
default: |
|
return EINVAL; |
|
} |
|
|
|
switch (key->qk_objtype) { |
|
case QUOTA_OBJTYPE_BLOCKS: |
|
case QUOTA_OBJTYPE_FILES: |
|
break; |
|
default: |
|
return EINVAL; |
|
} |
|
|
|
if (ump->um_quotas[key->qk_idtype] == NULLVP) |
|
return ENODEV; |
return ENODEV; |
|
|
if (key->qk_id == QUOTA_DEFAULTID) { |
if (defaultq) { |
/* just update grace times */ |
/* just update grace times */ |
id_t id = 0; |
error = proptoquota64(data, valuesp, val_limitsonly_grace, 1, |
|
ufs_quota_limit_names, QUOTA_NLIMITS); |
if ((error = dqget(NULLVP, id, ump, key->qk_idtype, &dq)) != 0) |
if (error) |
|
return error; |
|
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0) |
return error; |
return error; |
mutex_enter(&dq->dq_interlock); |
mutex_enter(&dq->dq_interlock); |
if (val->qv_grace != QUOTA_NOTIME) { |
if (bval[Q1_GTIME] > 0) |
if (key->qk_objtype == QUOTA_OBJTYPE_BLOCKS) |
ump->umq1_btime[type] = dq->dq_btime = |
ump->umq1_btime[key->qk_idtype] = dq->dq_btime = |
bval[Q1_GTIME]; |
val->qv_grace; |
if (ival[Q1_GTIME] > 0) |
if (key->qk_objtype == QUOTA_OBJTYPE_FILES) |
ump->umq1_itime[type] = dq->dq_itime = |
ump->umq1_itime[key->qk_idtype] = dq->dq_itime = |
ival[Q1_GTIME]; |
val->qv_grace; |
|
} |
|
dq->dq_flags |= DQ_MOD; |
|
mutex_exit(&dq->dq_interlock); |
mutex_exit(&dq->dq_interlock); |
|
dq->dq_flags |= DQ_MOD; |
dqrele(NULLVP, dq); |
dqrele(NULLVP, dq); |
return 0; |
return 0; |
} |
} |
|
error = proptoquota64(data, valuesp, val_limitsonly_softhard, 2, |
|
ufs_quota_limit_names, QUOTA_NLIMITS); |
|
if (error) |
|
return error; |
|
|
if ((error = dqget(NULLVP, key->qk_id, ump, key->qk_idtype, &dq)) != 0) |
if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0) |
return (error); |
return (error); |
mutex_enter(&dq->dq_interlock); |
mutex_enter(&dq->dq_interlock); |
/* |
/* |
Line 611 quota1_handle_cmd_put(struct ufsmount *u |
|
Line 601 quota1_handle_cmd_put(struct ufsmount *u |
|
dqb.dqb_curinodes = dq->dq_curinodes; |
dqb.dqb_curinodes = dq->dq_curinodes; |
dqb.dqb_btime = dq->dq_btime; |
dqb.dqb_btime = dq->dq_btime; |
dqb.dqb_itime = dq->dq_itime; |
dqb.dqb_itime = dq->dq_itime; |
if (key->qk_objtype == QUOTA_OBJTYPE_BLOCKS) { |
dqb.dqb_bsoftlimit = (bval[Q1_SOFT] == UQUAD_MAX) ? 0 : bval[Q1_SOFT]; |
dqb.dqb_bsoftlimit = quota1_encode_limit(val->qv_softlimit); |
dqb.dqb_bhardlimit = (bval[Q1_HARD] == UQUAD_MAX) ? 0 : bval[Q1_HARD]; |
dqb.dqb_bhardlimit = quota1_encode_limit(val->qv_hardlimit); |
dqb.dqb_isoftlimit = (ival[Q1_SOFT] == UQUAD_MAX) ? 0 : ival[Q1_SOFT]; |
dqb.dqb_isoftlimit = dq->dq_isoftlimit; |
dqb.dqb_ihardlimit = (ival[Q1_HARD] == UQUAD_MAX) ? 0 : ival[Q1_HARD]; |
dqb.dqb_ihardlimit = dq->dq_ihardlimit; |
if (dq->dq_id == 0) { |
} else { |
|
KASSERT(key->qk_objtype == QUOTA_OBJTYPE_FILES); |
|
dqb.dqb_bsoftlimit = dq->dq_bsoftlimit; |
|
dqb.dqb_bhardlimit = dq->dq_bhardlimit; |
|
dqb.dqb_isoftlimit = quota1_encode_limit(val->qv_softlimit); |
|
dqb.dqb_ihardlimit = quota1_encode_limit(val->qv_hardlimit); |
|
} |
|
if (dq->dq_id == 0 && val->qv_grace != QUOTA_NOTIME) { |
|
/* also update grace time if available */ |
/* also update grace time if available */ |
if (key->qk_objtype == QUOTA_OBJTYPE_BLOCKS) { |
if (proptoquota64(data, valuesp, val_limitsonly_grace, 1, |
ump->umq1_btime[key->qk_idtype] = dqb.dqb_btime = |
ufs_quota_limit_names, QUOTA_NLIMITS) == 0) { |
val->qv_grace; |
if (bval[Q1_GTIME] > 0) |
} |
ump->umq1_btime[type] = dqb.dqb_btime = |
if (key->qk_objtype == QUOTA_OBJTYPE_FILES) { |
bval[Q1_GTIME]; |
ump->umq1_itime[key->qk_idtype] = dqb.dqb_itime = |
if (ival[Q1_GTIME] > 0) |
val->qv_grace; |
ump->umq1_itime[type] = dqb.dqb_itime = |
|
ival[Q1_GTIME]; |
} |
} |
} |
} |
if (dqb.dqb_bsoftlimit && |
if (dqb.dqb_bsoftlimit && |
dq->dq_curblocks >= dqb.dqb_bsoftlimit && |
dq->dq_curblocks >= dqb.dqb_bsoftlimit && |
(dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit)) |
(dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit)) |
dqb.dqb_btime = time_second + ump->umq1_btime[key->qk_idtype]; |
dqb.dqb_btime = time_second + ump->umq1_btime[type]; |
if (dqb.dqb_isoftlimit && |
if (dqb.dqb_isoftlimit && |
dq->dq_curinodes >= dqb.dqb_isoftlimit && |
dq->dq_curinodes >= dqb.dqb_isoftlimit && |
(dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit)) |
(dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit)) |
dqb.dqb_itime = time_second + ump->umq1_itime[key->qk_idtype]; |
dqb.dqb_itime = time_second + ump->umq1_itime[type]; |
dq->dq_un.dq1_dqb = dqb; |
dq->dq_un.dq1_dqb = dqb; |
if (dq->dq_curblocks < dq->dq_bsoftlimit) |
if (dq->dq_curblocks < dq->dq_bsoftlimit) |
dq->dq_flags &= ~DQ_WARN(QL_BLOCK); |
dq->dq_flags &= ~DQ_WARN(QL_BLOCK); |