Пример #1
0
/*
 * Consult current disk space consumed by a given identifier.
 *
 * \param env   - the environment passed by the caller
 * \param qqi   - is the pointer to the qsd_qtype_info structure associated
 *                with the identifier.
 * \param lqe   - is the quota entry associated with the identifier
 */
int qsd_refresh_usage(const struct lu_env *env, struct lquota_entry *lqe)
{
	struct qsd_thread_info	*qti = qsd_info(env);
	struct lquota_acct_rec	*rec = &qti->qti_acct_rec;
	struct qsd_qtype_info	*qqi = lqe2qqi(lqe);
	int			 rc = 0;
	ENTRY;

	LASSERT(qqi->qqi_acct_obj);

	/* read disk usage */
	rc = lquota_disk_read(env, qqi->qqi_acct_obj, &lqe->lqe_id,
			      (struct dt_rec *)rec);
	switch(rc) {
	case -ENOENT:
		lqe->lqe_usage = 0;
		rc = 0;
		break;
	case 0:
		if (qqi->qqi_qsd->qsd_is_md)
			lqe->lqe_usage = rec->ispace;
		else
			lqe->lqe_usage = toqb(rec->bspace);
		break;
	default:
		LQUOTA_ERROR(lqe, "failed to read disk usage, rc:%d", rc);
		RETURN(rc);
	}

	LQUOTA_DEBUG(lqe, "disk usage: "LPU64, lqe->lqe_usage);
	RETURN(0);
}
Пример #2
0
/*
 * Convert a dquot list to an ASCII file.
 */
int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype)
{
	struct dquot *q;
	FILE *fd;

	ftruncate(outfd, 0);
	lseek(outfd, 0, SEEK_SET);
	if (!(fd = fdopen(dup(outfd), "w")))
		die(1, _("Cannot duplicate descriptor of file to write to: %s\n"), strerror(errno));

	fprintf(fd, _("Disk quotas for %s %s (%cid %d):\n"),
		_(type2name(quotatype)), name, *type2name(quotatype), qlist->dq_id);

	fprintf(fd,
		_("  Filesystem                   blocks       soft       hard     inodes     soft     hard\n"));

	for (q = qlist; q; q = q->dq_next) {
		fprintf(fd, "  %-24s %10llu %10llu %10llu %10llu %8llu %8llu\n",
			q->dq_h->qh_quotadev,
			(long long)toqb(q->dq_dqb.dqb_curspace),
			(long long)q->dq_dqb.dqb_bsoftlimit,
			(long long)q->dq_dqb.dqb_bhardlimit,
			(long long)q->dq_dqb.dqb_curinodes,
			(long long)q->dq_dqb.dqb_isoftlimit, (long long)q->dq_dqb.dqb_ihardlimit);
	}
	fclose(fd);
	return 0;
}
Пример #3
0
static int v1_get_dqblk(struct super_block *sb, int type, qid_t id, struct v1c_mem_dqblk *mdq)
{
    struct if_dqblk idq;
    int ret;

    if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)) < 0)
        return ret;
    mdq->dqb_ihardlimit = idq.dqb_ihardlimit;
    mdq->dqb_isoftlimit = idq.dqb_isoftlimit;
    mdq->dqb_curinodes = idq.dqb_curinodes;
    mdq->dqb_bhardlimit = idq.dqb_bhardlimit;
    mdq->dqb_bsoftlimit = idq.dqb_bsoftlimit;
    mdq->dqb_curblocks = toqb(idq.dqb_curspace);
    mdq->dqb_itime = idq.dqb_itime;
    mdq->dqb_btime = idq.dqb_btime;
    if (id == 0) {	/* Times for id 0 are in fact grace times */
        struct if_dqinfo info;

        if ((ret = sb->s_qcop->get_info(sb, type, &info)) < 0)
            return ret;
        mdq->dqb_btime = info.dqi_bgrace;
        mdq->dqb_itime = info.dqi_igrace;
    }
    return 0;
}
Пример #4
0
static int check_offence(struct dquot *dquot, char *name)
{
	if ((dquot->dq_dqb.dqb_bsoftlimit && toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bsoftlimit)
	    || (dquot->dq_dqb.dqb_isoftlimit && dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_isoftlimit)) {
		if(deliverable(dquot))
			add_offence(dquot, name);
	}
	return 0;
}
Пример #5
0
static void v1_mem2disk_dqblk(struct v1_disk_dqblk *d, struct mem_dqblk *m)
{
	d->dqb_ihardlimit = m->dqb_ihardlimit;
	d->dqb_isoftlimit = m->dqb_isoftlimit;
	d->dqb_curinodes = m->dqb_curinodes;
	d->dqb_bhardlimit = m->dqb_bhardlimit;
	d->dqb_bsoftlimit = m->dqb_bsoftlimit;
	d->dqb_curblocks = toqb(m->dqb_curspace);
	d->dqb_itime = m->dqb_itime;
	d->dqb_btime = m->dqb_btime;
}
Пример #6
0
/* Convert network format of quotas to utils one */
static inline void clinet2utildqblk(struct util_dqblk *u, struct rquota *n)
{
	time_t now;
	
	/* Copy the quota */
	u->dqb_bhardlimit = toqb(((qsize_t)n->rq_bhardlimit) * n->rq_bsize);
	u->dqb_bsoftlimit = toqb(((qsize_t)n->rq_bsoftlimit) * n->rq_bsize);
	u->dqb_ihardlimit = n->rq_fhardlimit;
	u->dqb_isoftlimit = n->rq_fsoftlimit;
	u->dqb_curinodes = n->rq_curfiles;
	u->dqb_curspace = ((qsize_t)n->rq_curblocks) * n->rq_bsize;
	time(&now);
	if (n->rq_btimeleft)
		u->dqb_btime = (int32_t)n->rq_btimeleft + now;
	else
		u->dqb_btime = 0;
	if (n->rq_ftimeleft)
		u->dqb_itime = (int32_t)n->rq_ftimeleft + now;
	else
		u->dqb_itime = 0;
}
Пример #7
0
/*
 * Set grace time if needed
 */
void update_grace_times(struct dquot *q)
{
	time_t now;

	time(&now);
	if (q->dq_dqb.dqb_bsoftlimit && toqb(q->dq_dqb.dqb_curspace) > q->dq_dqb.dqb_bsoftlimit) {
		if (!q->dq_dqb.dqb_btime)
			q->dq_dqb.dqb_btime = now + q->dq_h->qh_info.dqi_bgrace;
	}
	else
		q->dq_dqb.dqb_btime = 0;
	if (q->dq_dqb.dqb_isoftlimit && q->dq_dqb.dqb_curinodes > q->dq_dqb.dqb_isoftlimit) {
		if (!q->dq_dqb.dqb_itime)
			q->dq_dqb.dqb_itime = now + q->dq_h->qh_info.dqi_igrace;
	}
	else
		q->dq_dqb.dqb_itime = 0;
}
Пример #8
0
/* Convert utils format of quotas to network one */
static inline void cliutil2netdqblk(struct sq_dqblk *n, struct util_dqblk *u)
{
	time_t now;

	time(&now);
	n->rq_bhardlimit = u->dqb_bhardlimit;
	n->rq_bsoftlimit = u->dqb_bsoftlimit;
	n->rq_fhardlimit = u->dqb_ihardlimit;
	n->rq_fsoftlimit = u->dqb_isoftlimit;
	n->rq_curblocks = toqb(u->dqb_curspace);
	n->rq_curfiles = u->dqb_curinodes;
	if (u->dqb_btime)
		n->rq_btimeleft = difftime2net(u->dqb_btime, now);
	else
		n->rq_btimeleft = 0;
	if (u->dqb_itime)
		n->rq_ftimeleft = difftime2net(u->dqb_itime, now);
	else
		n->rq_ftimeleft = 0;
}
Пример #9
0
static int should_cc(struct offenderlist *offender, struct configparams *config)
{
	struct usage *lptr;
	struct util_dqblk *dqb;
	time_t atime;

	/* Noone to send CC to? */
	if (!strcmp(config->cc_to, ""))
		return 0;

	if (config->cc_before == -1)
		return 1;
	time(&atime);
	for (lptr = offender->usage; lptr; lptr = lptr->next) {
		dqb = &lptr->dq_dqb;
		if (dqb->dqb_bsoftlimit && dqb->dqb_bsoftlimit <= toqb(dqb->dqb_curspace) && dqb->dqb_btime-config->cc_before <= atime)
			return 1;
		if (dqb->dqb_isoftlimit && dqb->dqb_isoftlimit <= dqb->dqb_curinodes && dqb->dqb_itime-config->cc_before <= atime)
			return 1;
	}
	return 0;
}
Пример #10
0
/* Merge changes on one dev to proper structure in the list */
static void merge_limits_to_list(struct dquot *qlist, char *dev, u_int64_t blocks, u_int64_t bsoft,
			  u_int64_t bhard, u_int64_t inodes, u_int64_t isoft, u_int64_t ihard)
{
	struct dquot *q;

	for (q = qlist; q; q = q->dq_next) {
		if (!devcmp_handle(dev, q->dq_h))
			continue;

		q->dq_dqb.dqb_bsoftlimit = bsoft;
		q->dq_dqb.dqb_bhardlimit = bhard;
		q->dq_dqb.dqb_isoftlimit = isoft;
		q->dq_dqb.dqb_ihardlimit = ihard;
		q->dq_flags |= DQ_FOUND;
		update_grace_times(q);

		if (blocks != toqb(q->dq_dqb.dqb_curspace))
			errstr(_("WARNING - %s: cannot change current block allocation\n"),
				q->dq_h->qh_quotadev);
		if (inodes != q->dq_dqb.dqb_curinodes)
			errstr(_("WARNING - %s: cannot change current inode allocation\n"),
				q->dq_h->qh_quotadev);
	}
}
Пример #11
0
static int osd_declare_attr_set(const struct lu_env *env,
				struct dt_object *dt,
				const struct lu_attr *attr,
				struct thandle *handle)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	char			*buf = osd_oti_get(env)->oti_str;
	struct osd_object	*obj = osd_dt_obj(dt);
	struct osd_device	*osd = osd_obj2dev(obj);
	struct osd_thandle	*oh;
	uint64_t		 bspace;
	uint32_t		 blksize;
	int			 rc;
	ENTRY;

	if (!dt_object_exists(dt)) {
		/* XXX: sanity check that object creation is declared */
		RETURN(0);
	}

	LASSERT(handle != NULL);
	LASSERT(osd_invariant(obj));

	oh = container_of0(handle, struct osd_thandle, ot_super);

	LASSERT(obj->oo_sa_hdl != NULL);
	dmu_tx_hold_sa(oh->ot_tx, obj->oo_sa_hdl, 0);

	sa_object_size(obj->oo_sa_hdl, &blksize, &bspace);
	bspace = toqb(bspace * blksize);

	if (attr && attr->la_valid & LA_UID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid);
		dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, TRUE, buf);

		/* quota enforcement for user */
		if (attr->la_uid != obj->oo_attr.la_uid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, USRQUOTA,
					  obj->oo_attr.la_uid, attr->la_uid,
					  bspace, &info->oti_qi);
			if (rc)
				RETURN(rc);
		}
	}
	if (attr && attr->la_valid & LA_GID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_bonus(oh->ot_tx, osd->od_igrp_oid);
		dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, TRUE, buf);

		/* quota enforcement for group */
		if (attr->la_gid != obj->oo_attr.la_gid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, GRPQUOTA,
					  obj->oo_attr.la_gid, attr->la_gid,
					  bspace, &info->oti_qi);
			if (rc)
				RETURN(rc);
		}
	}

	RETURN(0);
}
Пример #12
0
static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
{
        struct obd_device_target *obt = &obd->u.obt;
        struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
        int err, cnt, rc = 0;
        struct obd_quotactl *oqctl;
        ENTRY;

        if (!ll_sb_any_quota_active(obt->obt_sb))
                RETURN(0);

        OBD_ALLOC_PTR(oqctl);
        if (!oqctl)
                RETURN(-ENOMEM);

        /* set over quota flags for a uid/gid */
        oa->o_valid |= OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA;
        oa->o_flags &= ~(OBD_FL_NO_USRQUOTA | OBD_FL_NO_GRPQUOTA);

        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                struct lustre_qunit_size *lqs = NULL;

                lqs = quota_search_lqs(LQS_KEY(cnt, GET_OA_ID(cnt, oa)),
                                       qctxt, 0);
                if (lqs == NULL || IS_ERR(lqs)) {
                        rc = PTR_ERR(lqs);
                        if (rc)
                                CDEBUG(D_QUOTA, "search lqs for %s %d failed, "
                                       "(rc = %d)\n",
                                       cnt == USRQUOTA ? "user" : "group",
                                       cnt == USRQUOTA ? oa->o_uid : oa->o_gid,
                                       rc);
                        break;
                } else {
                        cfs_spin_lock(&lqs->lqs_lock);
                        if (lqs->lqs_bunit_sz <= qctxt->lqc_sync_blk) {
                                oa->o_flags |= (cnt == USRQUOTA) ?
                                        OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA;
                                cfs_spin_unlock(&lqs->lqs_lock);
                                CDEBUG(D_QUOTA, "set sync flag: bunit(%lu), "
                                       "sync_blk(%d)\n", lqs->lqs_bunit_sz,
                                       qctxt->lqc_sync_blk);
                                /* this is for quota_search_lqs */
                                lqs_putref(lqs);
                                continue;
                        }
                        cfs_spin_unlock(&lqs->lqs_lock);
                        /* this is for quota_search_lqs */
                        lqs_putref(lqs);
                }

                memset(oqctl, 0, sizeof(*oqctl));

                oqctl->qc_cmd = Q_GETQUOTA;
                oqctl->qc_type = cnt;
                oqctl->qc_id = (cnt == USRQUOTA) ? oa->o_uid : oa->o_gid;
                err = fsfilt_quotactl(obd, obt->obt_sb, oqctl);
                if (err) {
                        if (!rc)
                                rc = err;
                        oa->o_valid &= ~((cnt == USRQUOTA) ? OBD_MD_FLUSRQUOTA :
                                                             OBD_MD_FLGRPQUOTA);
                        CDEBUG(D_QUOTA, "fsfilt getquota for %s %d failed, "
                               "(rc = %d)\n",
                               cnt == USRQUOTA ? "user" : "group",
                               cnt == USRQUOTA ? oa->o_uid : oa->o_gid, err);
                        continue;
                }

                if (oqctl->qc_dqblk.dqb_bhardlimit &&
                   (toqb(oqctl->qc_dqblk.dqb_curspace) >=
                    oqctl->qc_dqblk.dqb_bhardlimit)) {
                        oa->o_flags |= (cnt == USRQUOTA) ?
                                OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA;
                        CDEBUG(D_QUOTA, "out of quota for %s %d\n",
                               cnt == USRQUOTA ? "user" : "group",
                               cnt == USRQUOTA ? oa->o_uid : oa->o_gid);
                }
        }
        OBD_FREE_PTR(oqctl);
        RETURN(rc);
}
Пример #13
0
static int mail_user(struct offenderlist *offender, struct configparams *config)
{
	struct usage *lptr;
	FILE *fp;
	int cnt, status;
	char timebuf[MAXTIMELEN];
	char numbuf[3][MAXNUMLEN];
	struct util_dqblk *dqb;
	char *to = NULL;

	if (offender->offender_type == USRQUOTA) {
		to = lookup_user(config, offender->offender_name);
		if (!to)
			return -1;
	} else {
		struct adminstable *admin;

		if (!(admin = bsearch(offender->offender_name, adminstable, adminscnt, sizeof(struct adminstable), admin_name_cmp))) {
			errstr(_("Administrator for a group %s not found. Cancelling mail.\n"), offender->offender_name);
			return -1;
		}
		to = sstrdup(admin->adminname);
	}
	if (!(fp = run_mailer(config->mail_cmd))) {
		if (to)
			free(to);
		return -1;
	}
	fprintf(fp, "From: %s\n", config->from);
	fprintf(fp, "Reply-To: %s\n", config->support);
	fprintf(fp, "Subject: %s\n", config->subject);
	fprintf(fp, "To: %s\n", to);
	if (should_cc(offender, config)) {
		char *cc_to = lookup_user(config, config->cc_to);

		if (cc_to) {
			fprintf(fp, "Cc: %s\n", config->cc_to);
			free(cc_to);
		}
	}
	if ((config->charset)[0] != '\0') { /* are we supposed to set the encoding */
		fprintf(fp, "MIME-Version: 1.0\n");
		fprintf(fp, "Content-Type: text/plain; charset=%s\n", config->charset);
		fprintf(fp, "Content-Disposition: inline\n");
		fprintf(fp, "Content-Transfer-Encoding: 8bit\n");
	}
	fprintf(fp, "\n");
	free(to);

	if (offender->offender_type == USRQUOTA)
		if (config->user_message)
			format_print(fp, config->user_message, offender->offender_name);
		else
			fputs(DEF_USER_MESSAGE, fp);
	else
		if (config->group_message)
			format_print(fp, config->group_message, offender->offender_name);
		else
			fprintf(fp, DEF_GROUP_MESSAGE, offender->offender_name);

	if (!(flags & FL_NODETAILS)) {
		for (lptr = offender->usage; lptr; lptr = lptr->next) {
			dqb = &lptr->dq_dqb;
			for (cnt = 0; cnt < qtab_i; cnt++)
				if (!strcmp(quotatable[cnt].devname, lptr->devicename)) {
					fprintf(fp, "\n%s (%s)\n", quotatable[cnt].devdesc, quotatable[cnt].devname);
					break;
				}
			if (cnt == qtab_i)	/* Description not found? */
				fprintf(fp, "\n%s\n", lptr->devicename);
			fprintf(fp, _("\n                        Block limits               File limits\n"));
			fprintf(fp, _("Filesystem           used    soft    hard  grace    used  soft  hard  grace\n"));
			if (strlen(lptr->devicename) > 15)
				fprintf(fp, "%s\n%15s", lptr->devicename, "");
			else
				fprintf(fp, "%-15s", lptr->devicename);
			if (dqb->dqb_bsoftlimit && dqb->dqb_bsoftlimit <= toqb(dqb->dqb_curspace))
				difftime2str(dqb->dqb_btime, timebuf);
			else
				timebuf[0] = '\0';
			space2str(toqb(dqb->dqb_curspace), numbuf[0], flags & FL_SHORTNUMS);
			space2str(dqb->dqb_bsoftlimit, numbuf[1], flags & FL_SHORTNUMS);
			space2str(dqb->dqb_bhardlimit, numbuf[2], flags & FL_SHORTNUMS);
			fprintf(fp, "%c%c %7s %7s %7s %6s",
			        dqb->dqb_bsoftlimit && toqb(dqb->dqb_curspace) >= dqb->dqb_bsoftlimit ? '+' : '-',
				dqb->dqb_isoftlimit && dqb->dqb_curinodes >= dqb->dqb_isoftlimit ? '+' : '-',
				numbuf[0], numbuf[1], numbuf[2], timebuf);
			if (dqb->dqb_isoftlimit && dqb->dqb_isoftlimit <= dqb->dqb_curinodes)
				difftime2str(dqb->dqb_itime, timebuf);
			else
				timebuf[0] = '\0';
			number2str(dqb->dqb_curinodes, numbuf[0], flags & FL_SHORTNUMS);
			number2str(dqb->dqb_isoftlimit, numbuf[1], flags & FL_SHORTNUMS);
			number2str(dqb->dqb_ihardlimit, numbuf[2], flags & FL_SHORTNUMS);
			fprintf(fp, " %7s %5s %5s %6s\n\n", numbuf[0], numbuf[1], numbuf[2], timebuf);
		}
	}


	if (offender->offender_type == USRQUOTA)
		if (config->user_signature)
			format_print(fp, config->user_signature, offender->offender_name);
		else
			fprintf(fp, DEF_USER_SIGNATURE, config->support, config->phone);
	else
		if (config->group_signature)
			format_print(fp, config->group_signature, offender->offender_name);
		else
			fprintf(fp, DEF_GROUP_SIGNATURE, config->support, config->phone);
	fclose(fp);
	if (wait(&status) < 0)	/* Wait for mailer */
		errstr(_("Cannot wait for mailer: %s\n"), strerror(errno));
	else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
		errstr(_("Warning: Mailer exitted abnormally.\n"));

	return 0;
}
Пример #14
0
static int setup_ldap(struct configparams *config)
{
	int ret;
	struct berval cred = { .bv_val = config->ldap_bindpw,
			       .bv_len = strlen(config->ldap_bindpw) };

	ret = ldap_initialize(&ldapconn, config->ldap_uri);

	if (ret != LDAP_SUCCESS) {
		errstr(_("ldap_initialize() failed: %s\n"), ldap_err2string(ret));
		return -1;
	}

	ret = ldap_sasl_bind_s(ldapconn, config->ldap_binddn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
	if(ret < 0) {
		errstr(_("ldap_sasl_bind_s() failed: %s\n"), ldap_err2string(ret));
		return -1;
	}
	return 0;
}
		
#endif

static struct offenderlist *add_offender(int type, int id, char *name)
{
	struct offenderlist *offender;
	char namebuf[MAXNAMELEN];
	
	if (!name) {
		if (id2name(id, type, namebuf)) {
			errstr(_("Cannot get name for uid/gid %u.\n"), id);
			return NULL;
		}
		name = namebuf;
	}
	offender = (struct offenderlist *)smalloc(sizeof(struct offenderlist));
	offender->offender_type = type;
	offender->offender_id = id;
	offender->offender_name = sstrdup(name);
	offender->usage = (struct usage *)NULL;
	offender->next = offenders;
	offenders = offender;
	return offender;
}

static void add_offence(struct dquot *dquot, char *name)
{
	struct offenderlist *lptr;
	struct usage *usage;

	for (lptr = offenders; lptr; lptr = lptr->next)
		if (dquot->dq_h->qh_type == lptr->offender_type && lptr->offender_id == dquot->dq_id)
			break;

	if (!lptr)
		if (!(lptr = add_offender(dquot->dq_h->qh_type, dquot->dq_id, name)))
			return;

	usage = (struct usage *)smalloc(sizeof(struct usage));
	memcpy(&usage->dq_dqb, &dquot->dq_dqb, sizeof(struct util_dqblk));

	usage->devicename = sstrdup(dquot->dq_h->qh_quotadev);
	/*
	 * Stuff it in front
	 */
	usage->next = lptr->usage;
	lptr->usage = usage;
}

static int deliverable(struct dquot *dquot)
{
	time_t now;
	struct dquot *mdquot;
	
	if (!maildev[0])
		return 1;

	time(&now);
	
	if (!strcasecmp(maildev, "any") && 
	   ((dquot->dq_dqb.dqb_bhardlimit && toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bhardlimit)
	   || ((dquot->dq_dqb.dqb_bsoftlimit && toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bsoftlimit)
	   && (dquot->dq_dqb.dqb_btime && dquot->dq_dqb.dqb_btime <= now))))
		return 0;
	if (!maildev_handle)
		return 1;
	mdquot = maildev_handle->qh_ops->read_dquot(maildev_handle, dquot->dq_id);
	if (mdquot &&
	   ((mdquot->dq_dqb.dqb_bhardlimit && toqb(mdquot->dq_dqb.dqb_curspace) >= mdquot->dq_dqb.dqb_bhardlimit)
	   || ((mdquot->dq_dqb.dqb_bsoftlimit && toqb(mdquot->dq_dqb.dqb_curspace) >= mdquot->dq_dqb.dqb_bsoftlimit)
	   && (mdquot->dq_dqb.dqb_btime && mdquot->dq_dqb.dqb_btime <= now)))) {
		free(mdquot);
		return 0;
	}
	free(mdquot);
	return 1;
}
Пример #15
0
static int osd_declare_attr_set(const struct lu_env *env,
				struct dt_object *dt,
				const struct lu_attr *attr,
				struct thandle *handle)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	struct osd_object	*obj = osd_dt_obj(dt);
	struct osd_device	*osd = osd_obj2dev(obj);
	dmu_tx_hold_t		*txh;
	struct osd_thandle	*oh;
	uint64_t		 bspace;
	uint32_t		 blksize;
	int			 rc = 0;
	bool			 found;
	ENTRY;


	LASSERT(handle != NULL);
	LASSERT(osd_invariant(obj));

	oh = container_of0(handle, struct osd_thandle, ot_super);

	down_read(&obj->oo_guard);
	if (unlikely(!dt_object_exists(dt) || obj->oo_destroyed))
		GOTO(out, rc = 0);

	LASSERT(obj->oo_sa_hdl != NULL);
	LASSERT(oh->ot_tx != NULL);
	/* regular attributes are part of the bonus buffer */
	/* let's check whether this object is already part of
	 * transaction.. */
	found = false;
	for (txh = list_head(&oh->ot_tx->tx_holds); txh;
	     txh = list_next(&oh->ot_tx->tx_holds, txh)) {
		if (txh->txh_dnode == NULL)
			continue;
		if (txh->txh_dnode->dn_object != obj->oo_db->db_object)
			continue;
		/* this object is part of the transaction already
		 * we don't need to declare bonus again */
		found = true;
		break;
	}
	if (!found)
		dmu_tx_hold_bonus(oh->ot_tx, obj->oo_db->db_object);
	if (oh->ot_tx->tx_err != 0)
		GOTO(out, rc = -oh->ot_tx->tx_err);

	if (attr && attr->la_valid & LA_FLAGS) {
		/* LMA is usually a part of bonus, no need to declare
		 * anything else */
	}

	if (attr && (attr->la_valid & (LA_UID | LA_GID))) {
		sa_object_size(obj->oo_sa_hdl, &blksize, &bspace);
		bspace = toqb(bspace * blksize);
	}

	if (attr && attr->la_valid & LA_UID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, FALSE, NULL);

		/* quota enforcement for user */
		if (attr->la_uid != obj->oo_attr.la_uid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, USRQUOTA,
					  obj->oo_attr.la_uid, attr->la_uid,
					  bspace, &info->oti_qi);
			if (rc)
				GOTO(out, rc);
		}
	}
	if (attr && attr->la_valid & LA_GID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, FALSE, NULL);

		/* quota enforcement for group */
		if (attr->la_gid != obj->oo_attr.la_gid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, GRPQUOTA,
					  obj->oo_attr.la_gid, attr->la_gid,
					  bspace, &info->oti_qi);
			if (rc)
				GOTO(out, rc);
		}
	}

out:
	up_read(&obj->oo_guard);
	RETURN(rc);
}
Пример #16
0
static int osd_declare_attr_set(const struct lu_env *env,
				struct dt_object *dt,
				const struct lu_attr *attr,
				struct thandle *handle)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	char			*buf = osd_oti_get(env)->oti_str;
	struct osd_object	*obj = osd_dt_obj(dt);
	struct osd_device	*osd = osd_obj2dev(obj);
	struct osd_thandle	*oh;
	uint64_t		 bspace;
	uint32_t		 blksize;
	int			 rc = 0;
	ENTRY;


	LASSERT(handle != NULL);
	LASSERT(osd_invariant(obj));

	oh = container_of0(handle, struct osd_thandle, ot_super);

	down_read(&obj->oo_guard);
	if (unlikely(!dt_object_exists(dt) || obj->oo_destroyed))
		GOTO(out, rc = 0);

	LASSERT(obj->oo_sa_hdl != NULL);
	LASSERT(oh->ot_tx != NULL);
	dmu_tx_hold_sa(oh->ot_tx, obj->oo_sa_hdl, 0);
	if (oh->ot_tx->tx_err != 0)
		GOTO(out, rc = -oh->ot_tx->tx_err);

	sa_object_size(obj->oo_sa_hdl, &blksize, &bspace);
	bspace = toqb(bspace * blksize);

	__osd_xattr_declare_set(env, obj, sizeof(struct lustre_mdt_attrs),
				XATTR_NAME_LMA, oh);

	if (attr && attr->la_valid & LA_UID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid);
		dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, TRUE, buf);

		/* quota enforcement for user */
		if (attr->la_uid != obj->oo_attr.la_uid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, USRQUOTA,
					  obj->oo_attr.la_uid, attr->la_uid,
					  bspace, &info->oti_qi);
			if (rc)
				GOTO(out, rc);
		}
	}
	if (attr && attr->la_valid & LA_GID) {
		/* account for user inode tracking ZAP update */
		dmu_tx_hold_bonus(oh->ot_tx, osd->od_igrp_oid);
		dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, TRUE, buf);

		/* quota enforcement for group */
		if (attr->la_gid != obj->oo_attr.la_gid) {
			rc = qsd_transfer(env, osd->od_quota_slave,
					  &oh->ot_quota_trans, GRPQUOTA,
					  obj->oo_attr.la_gid, attr->la_gid,
					  bspace, &info->oti_qi);
			if (rc)
				GOTO(out, rc);
		}
	}

out:
	up_read(&obj->oo_guard);
	RETURN(rc);
}