Whamcloud - gitweb
LU-12178 osd: do not rebalance quota under memory pressure
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index adc7b4a..41ee352 100644 (file)
@@ -2083,7 +2083,11 @@ static int osd_trans_cb_add(struct thandle *th, struct dt_txn_commit_cb *dcb)
 static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
 {
        struct osd_object *obj = osd_obj(l);
+       struct qsd_instance *qsd = osd_def_qsd(osd_obj2dev(obj));
        struct inode *inode = obj->oo_inode;
+       __u64 projid;
+       qid_t uid;
+       qid_t gid;
 
        LINVRNT(osd_invariant(obj));
 
@@ -2092,27 +2096,36 @@ static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
         */
 
        osd_index_fini(obj);
-       if (inode != NULL) {
-               struct qsd_instance *qsd = osd_def_qsd(osd_obj2dev(obj));
-               qid_t                uid = i_uid_read(inode);
-               qid_t                gid = i_gid_read(inode);
 
-               obj->oo_inode = NULL;
-               iput(inode);
-               if (!obj->oo_header && qsd) {
-                       struct osd_thread_info *info = osd_oti_get(env);
-                       struct lquota_id_info *qi = &info->oti_qi;
+       if (!inode)
+               return;
 
-                       /* Release granted quota to master if necessary */
-                       qi->lqi_id.qid_uid = uid;
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, USRQUOTA);
+       uid = i_uid_read(inode);
+       gid = i_gid_read(inode);
+       projid = i_projid_read(inode);
 
-                       qi->lqi_id.qid_uid = gid;
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+       obj->oo_inode = NULL;
+       iput(inode);
 
-                       qi->lqi_id.qid_uid = i_projid_read(inode);
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
-               }
+       /* do not rebalance quota if the caller needs to release memory
+        * otherwise qsd_refresh_usage() may went into a new ldiskfs
+        * transaction and risk to deadlock - LU-12178 */
+       if (current->flags & (PF_MEMALLOC | PF_KSWAPD))
+               return;
+
+       if (!obj->oo_header && qsd) {
+               struct osd_thread_info *info = osd_oti_get(env);
+               struct lquota_id_info *qi = &info->oti_qi;
+
+               /* Release granted quota to master if necessary */
+               qi->lqi_id.qid_uid = uid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, USRQUOTA);
+
+               qi->lqi_id.qid_uid = gid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+
+               qi->lqi_id.qid_uid = projid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
        }
 }
 
@@ -3056,13 +3069,19 @@ static struct dentry *osd_child_dentry_get(const struct lu_env *env,
 
 static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
                      umode_t mode, struct dt_allocation_hint *hint,
-                     struct thandle *th)
+                     struct thandle *th, struct lu_attr *attr)
 {
        int result;
        struct osd_device *osd = osd_obj2dev(obj);
        struct osd_thandle *oth;
        struct dt_object *parent = NULL;
        struct inode *inode;
+       uid_t owner[2] = {0, 0};
+
+       if (attr->la_valid & LA_UID)
+               owner[0] = attr->la_uid;
+       if (attr->la_valid & LA_GID)
+               owner[1] = attr->la_gid;
 
        LINVRNT(osd_invariant(obj));
        LASSERT(obj->oo_inode == NULL);
@@ -3085,7 +3104,7 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
        inode = ldiskfs_create_inode(oth->ot_handle,
                                     parent ? osd_dt_obj(parent)->oo_inode :
                                              osd_sb(osd)->s_root->d_inode,
-                                    mode);
+                                    mode, owner);
        if (!IS_ERR(inode)) {
                /* Do not update file c/mtime in ldiskfs. */
                inode->i_flags |= S_NOCMTIME;
@@ -3127,7 +3146,7 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj,
 
        oth = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oth->ot_handle->h_transaction != NULL);
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
 
        return result;
 }
@@ -3149,7 +3168,7 @@ static int osd_mk_index(struct osd_thread_info *info, struct osd_object *obj,
        oth = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oth->ot_handle->h_transaction != NULL);
 
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
        if (result == 0) {
                LASSERT(obj->oo_inode != NULL);
                if (feat->dif_flags & DT_IND_VARKEY)
@@ -3176,7 +3195,8 @@ static int osd_mkreg(struct osd_thread_info *info, struct osd_object *obj,
 {
        LASSERT(S_ISREG(attr->la_mode));
        return osd_mkfile(info, obj, (attr->la_mode &
-                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+                         attr);
 }
 
 static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
@@ -3187,7 +3207,8 @@ static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
 {
        LASSERT(S_ISLNK(attr->la_mode));
        return osd_mkfile(info, obj, (attr->la_mode &
-                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+                         attr);
 }
 
 static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
@@ -3204,7 +3225,7 @@ static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
        LASSERT(S_ISCHR(mode) || S_ISBLK(mode) ||
                S_ISFIFO(mode) || S_ISSOCK(mode));
 
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
        if (result == 0) {
                LASSERT(obj->oo_inode != NULL);
                /*
@@ -3755,7 +3776,8 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
        oh = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oh->ot_handle->h_transaction != NULL);
 
-       local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type);
+       local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type,
+                                    NULL);
        if (IS_ERR(local)) {
                CERROR("%s: create local error %d\n", osd_name(osd),
                       (int)PTR_ERR(local));