/* * 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); }
/* * 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; }
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; }
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; }
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; }
/* 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; }
/* * 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; }
/* 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; }
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; }
/* 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); } }
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); }
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); }
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; }
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; }
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); }
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); }