/* For quota slave, check whether specified uid/gid's remaining quota
* can finish a block_write or inode_create rpc. It updates the pending
* record of block and inode, acquires quota if necessary */
- int (*quota_chkquota) (struct obd_device *, unsigned int, unsigned int,
+ int (*quota_chkquota) (struct obd_export *, unsigned int, unsigned int,
int, int [], quota_acquire,
struct obd_trans_info *, struct inode *, int);
}
static inline int lquota_chkquota(quota_interface_t *interface,
- struct obd_device *obd,
+ struct obd_export *exp,
unsigned int uid, unsigned int gid, int count,
int pending[2], struct obd_trans_info *oti,
struct inode *inode, int frags)
QUOTA_CHECK_OP(interface, chkquota);
QUOTA_CHECK_OP(interface, acquire);
- rc = QUOTA_OP(interface, chkquota)(obd, uid, gid, count, pending,
+ rc = QUOTA_OP(interface, chkquota)(exp, uid, gid, count, pending,
QUOTA_OP(interface, acquire), oti,
inode, frags);
RETURN(rc);
/* we try to get enough quota to write here, and let ldiskfs
* decide if it is out of quota or not b=14783 */
- lquota_chkquota(filter_quota_interface_ref, obd, qcids[0], qcids[1],
- quota_pages, quota_pending, oti, inode,
- obj->ioo_bufcnt);
+ rc = lquota_chkquota(filter_quota_interface_ref, exp, qcids[0],
+ qcids[1], quota_pages, quota_pending, oti,
+ inode, obj->ioo_bufcnt);
+ if (rc == -ENOTCONN)
+ GOTO(cleanup, rc);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
cleanup_phase = 2;
RETURN(rc);
}
-static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
+static int quota_chk_acq_common(struct obd_export *exp, unsigned int uid,
unsigned int gid, int count, int pending[2],
int isblk, quota_acquire acquire,
struct obd_trans_info *oti, struct inode *inode,
int frags)
{
+ struct obd_device *obd = exp->exp_obd;
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
struct timeval work_start;
struct timeval work_end;
ENTRY;
CDEBUG(D_QUOTA, "check quota for %s\n", obd->obd_name);
+ if (isblk && (exp->exp_failed || exp->exp_abort_active_req))
+ /* If the client has been evicted or if it
+ * timed out and tried to reconnect already,
+ * abort the request immediately */
+ RETURN(-ENOTCONN);
+
/* Unfortunately, if quota master is too busy to handle the
* pre-dqacq in time and quota hash on ost is used up, we
* have to wait for the completion of in flight dqacq/dqrel,
break;
}
+ if (isblk && (exp->exp_failed || exp->exp_abort_active_req))
+ /* The client has been evicted or tried to
+ * to reconnect already, abort the request */
+ RETURN(-ENOTCONN);
+
/* -EBUSY and others, wait a second and try again */
if (rc < 0) {
cfs_waitq_t waitq;
LQUOTA_WAIT_FOR_CHK_INO,
timediff);
+ if (rc > 0)
+ rc = 0;
RETURN(rc);
}
return q_set;
}
-static int filter_quota_check(struct obd_device *obd, unsigned int uid,
+static int filter_quota_check(struct obd_export *exp, unsigned int uid,
unsigned int gid, int npage, int pending[2],
quota_acquire acquire, struct obd_trans_info *oti,
struct inode *inode, int frags)
{
- return quota_is_set(obd, uid, gid, QB_SET) ?
- quota_chk_acq_common(obd, uid, gid, npage, pending,
+ return quota_is_set(exp->exp_obd, uid, gid, QB_SET) ?
+ quota_chk_acq_common(exp, uid, gid, npage, pending,
LQUOTA_FLAGS_BLK, acquire, oti, inode,
frags) : 0;
}
RETURN(0);
}
-static int mds_quota_check(struct obd_device *obd, unsigned int uid,
+static int mds_quota_check(struct obd_export *exp, unsigned int uid,
unsigned int gid, int inodes, int pending[2],
quota_acquire acquire, struct obd_trans_info *oti,
struct inode *inode, int frags)
{
- return quota_is_set(obd, uid, gid, QI_SET) ?
- quota_chk_acq_common(obd, uid, gid, inodes, pending, 0,
+ return quota_is_set(exp->exp_obd, uid, gid, QI_SET) ?
+ quota_chk_acq_common(exp, uid, gid, inodes, pending, 0,
acquire, oti, inode, frags) : 0;
}