Whamcloud - gitweb
LU-1866 misc: fix some issues found during LFSCK
[fs/lustre-release.git] / lustre / mdd / mdd_dir.c
index b4994b4..5f210b8 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2011, 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -345,31 +345,31 @@ int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj,
  * VTX feature has been checked already, no need check again.
  */
 static inline int mdd_is_sticky(const struct lu_env *env,
-                                struct mdd_object *pobj,
-                                struct mdd_object *cobj)
+                               struct mdd_object *pobj,
+                               struct mdd_object *cobj)
 {
-        struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
-        struct md_ucred *uc = md_ucred(env);
-        int rc;
+       struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
+       struct lu_ucred *uc = lu_ucred_assert(env);
+       int rc;
 
-        if (pobj) {
-                rc = mdd_la_get(env, pobj, tmp_la, BYPASS_CAPA);
-                if (rc)
-                        return rc;
+       if (pobj) {
+               rc = mdd_la_get(env, pobj, tmp_la, BYPASS_CAPA);
+               if (rc)
+                       return rc;
 
-                if (!(tmp_la->la_mode & S_ISVTX) ||
-                     (tmp_la->la_uid == uc->mu_fsuid))
-                        return 0;
-        }
+               if (!(tmp_la->la_mode & S_ISVTX) ||
+                   (tmp_la->la_uid == uc->uc_fsuid))
+                       return 0;
+       }
 
-        rc = mdd_la_get(env, cobj, tmp_la, BYPASS_CAPA);
-        if (rc)
-                return rc;
+       rc = mdd_la_get(env, cobj, tmp_la, BYPASS_CAPA);
+       if (rc)
+               return rc;
 
-        if (tmp_la->la_uid == uc->mu_fsuid)
-                return 0;
+       if (tmp_la->la_uid == uc->uc_fsuid)
+               return 0;
 
-        return !mdd_capable(uc, CFS_CAP_FOWNER);
+       return !mdd_capable(uc, CFS_CAP_FOWNER);
 }
 
 /*
@@ -499,27 +499,28 @@ static int __mdd_index_delete_only(const struct lu_env *env, struct mdd_object *
 }
 
 static int __mdd_index_insert_only(const struct lu_env *env,
-                                   struct mdd_object *pobj,
-                                   const struct lu_fid *lf, const char *name,
-                                   struct thandle *handle,
-                                   struct lustre_capa *capa)
+                                  struct mdd_object *pobj,
+                                  const struct lu_fid *lf, const char *name,
+                                  struct thandle *handle,
+                                  struct lustre_capa *capa)
 {
-        struct dt_object *next = mdd_object_child(pobj);
-        int               rc;
-        ENTRY;
+       struct dt_object *next = mdd_object_child(pobj);
+       int               rc;
+       ENTRY;
 
-        if (dt_try_as_dir(env, next)) {
-                struct md_ucred  *uc = md_ucred(env);
+       if (dt_try_as_dir(env, next)) {
+               struct lu_ucred  *uc = lu_ucred_check(env);
+               int ignore_quota;
 
-                rc = next->do_index_ops->dio_insert(env, next,
-                                                    (struct dt_rec*)lf,
-                                                    (const struct dt_key *)name,
-                                                    handle, capa, uc->mu_cap &
-                                                    CFS_CAP_SYS_RESOURCE_MASK);
-        } else {
-                rc = -ENOTDIR;
-        }
-        RETURN(rc);
+               ignore_quota = uc ? uc->uc_cap & CFS_CAP_SYS_RESOURCE_MASK : 1;
+               rc = next->do_index_ops->dio_insert(env, next,
+                                                   (struct dt_rec*)lf,
+                                                   (const struct dt_key *)name,
+                                                   handle, capa, ignore_quota);
+       } else {
+               rc = -ENOTDIR;
+       }
+       RETURN(rc);
 }
 
 /* insert named index, add reference if isdir */
@@ -703,12 +704,12 @@ int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd,
        rec->cr_hdr.lrh_type = CHANGELOG_REC;
        rec->cr.cr_time = cl_time();
 
-       cfs_spin_lock(&mdd->mdd_cl.mc_lock);
+       spin_lock(&mdd->mdd_cl.mc_lock);
        /* NB: I suppose it's possible llog_add adds out of order wrt cr_index,
         * but as long as the MDD transactions are ordered correctly for e.g.
         * rename conflicts, I don't think this should matter. */
        rec->cr.cr_index = ++mdd->mdd_cl.mc_index;
-       cfs_spin_unlock(&mdd->mdd_cl.mc_lock);
+       spin_unlock(&mdd->mdd_cl.mc_lock);
 
        ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
        if (ctxt == NULL)
@@ -741,12 +742,12 @@ int mdd_changelog_ext_store(const struct lu_env *env, struct mdd_device *mdd,
        rec->cr_hdr.lrh_type = CHANGELOG_REC;
        rec->cr.cr_time = cl_time();
 
-       cfs_spin_lock(&mdd->mdd_cl.mc_lock);
+       spin_lock(&mdd->mdd_cl.mc_lock);
        /* NB: I suppose it's possible llog_add adds out of order wrt cr_index,
         * but as long as the MDD transactions are ordered correctly for e.g.
         * rename conflicts, I don't think this should matter. */
        rec->cr.cr_index = ++mdd->mdd_cl.mc_index;
-       cfs_spin_unlock(&mdd->mdd_cl.mc_lock);
+       spin_unlock(&mdd->mdd_cl.mc_lock);
 
        ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
        if (ctxt == NULL)
@@ -877,7 +878,6 @@ static int mdd_changelog_ext_ns_store(const struct lu_env  *env,
        rec->cr.cr_namelen = tname->ln_namelen;
        memcpy(rec->cr.cr_name, tname->ln_name, tname->ln_namelen);
        if (sname) {
-               LASSERT(sfid != NULL);
                rec->cr.cr_name[tname->ln_namelen] = '\0';
                memcpy(rec->cr.cr_name + tname->ln_namelen + 1, sname->ln_name,
                        sname->ln_namelen);
@@ -970,17 +970,17 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
         if (rc)
                 GOTO(out_unlock, rc);
 
-        rc = __mdd_index_insert_only(env, mdd_tobj, mdo2fid(mdd_sobj),
-                                     name, handle,
-                                     mdd_object_capa(env, mdd_tobj));
-        if (rc)
-                GOTO(out_unlock, rc);
-
        rc = mdo_ref_add(env, mdd_sobj, handle);
+       if (rc)
+               GOTO(out_unlock, rc);
+
+
+       rc = __mdd_index_insert_only(env, mdd_tobj, mdo2fid(mdd_sobj),
+                                    name, handle,
+                                    mdd_object_capa(env, mdd_tobj));
        if (rc != 0) {
-               __mdd_index_delete_only(env, mdd_tobj, name, handle,
-                                       mdd_object_capa(env, mdd_tobj));
-                GOTO(out_unlock, rc);
+               mdo_ref_del(env, mdd_sobj, handle);
+               GOTO(out_unlock, rc);
        }
 
         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
@@ -1013,15 +1013,15 @@ out_pending:
 }
 
 int mdd_declare_finish_unlink(const struct lu_env *env,
-                              struct mdd_object *obj,
-                              struct md_attr *ma,
-                              struct thandle *handle)
+                             struct mdd_object *obj,
+                             struct md_attr *ma,
+                             struct thandle *handle)
 {
-        int rc;
+       int     rc;
 
-        rc = orph_declare_index_insert(env, obj, handle);
-        if (rc)
-                return rc;
+       rc = orph_declare_index_insert(env, obj, mdd_object_type(obj), handle);
+       if (rc)
+               return rc;
 
        return mdo_declare_destroy(env, obj, handle);
 }
@@ -1168,6 +1168,11 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
         if (rc)
                 GOTO(cleanup, rc);
 
+       rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle,
+                               mdd_object_capa(env, mdd_pobj));
+       if (rc)
+               GOTO(cleanup, rc);
+
        rc = mdo_ref_del(env, mdd_cobj, handle);
        if (rc != 0) {
                __mdd_index_insert_only(env, mdd_pobj, mdo2fid(mdd_cobj),
@@ -1176,11 +1181,6 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
                GOTO(cleanup, rc);
        }
 
-       rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle,
-                               mdd_object_capa(env, mdd_pobj));
-       if (rc)
-               GOTO(cleanup, rc);
-
         if (is_dir)
                 /* unlink dot */
                 mdo_ref_del(env, mdd_cobj, handle);
@@ -1315,21 +1315,12 @@ static int mdd_create_data(const struct lu_env *env, struct md_object *pobj,
               spec->u.sp_ea.eadata, spec->u.sp_ea.eadatalen,
               spec->sp_cr_flags, spec->no_create);
 
-       if (spec->no_create) {
-               /* replay case */
+       if (spec->no_create || spec->sp_cr_flags & MDS_OPEN_HAS_EA) {
+               /* replay case or lfs setstripe */
                buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
                                        spec->u.sp_ea.eadatalen);
-       } else  if (!(spec->sp_cr_flags & MDS_OPEN_HAS_OBJS)) {
-               if (spec->sp_cr_flags & MDS_OPEN_HAS_EA) {
-                       /* lfs setstripe */
-                       buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
-                                               spec->u.sp_ea.eadatalen);
-               } else {
-                       buf = &LU_BUF_NULL;
-               }
        } else {
-               /* MDS_OPEN_HAS_OBJS is not used anymore ? */
-               LBUG();
+               buf = &LU_BUF_NULL;
        }
 
        rc = dt_declare_xattr_set(env, mdd_object_child(son), buf,
@@ -1406,7 +1397,16 @@ int mdd_declare_object_initialize(const struct lu_env *env,
 {
         int rc;
 
+       /*
+        * inode mode has been set in creation time, and it's based on umask,
+        * la_mode and acl, don't set here again! (which will go wrong
+        * because below function doesn't consider umask).
+        * I'd suggest set all object attributes in creation time, see above.
+        */
+       LASSERT(attr->la_valid & (LA_MODE | LA_TYPE));
+       attr->la_valid &= ~(LA_MODE | LA_TYPE);
        rc = mdo_declare_attr_set(env, child, attr, handle);
+       attr->la_valid |= LA_MODE | LA_TYPE;
        if (rc == 0 && S_ISDIR(attr->la_mode)) {
                rc = mdo_declare_index_insert(env, child, mdo2fid(child),
                                              dot, handle);
@@ -1442,10 +1442,13 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid,
         * because below function doesn't consider umask).
         * I'd suggest set all object attributes in creation time, see above.
         */
-       attr->la_valid &= ~LA_MODE;
+       LASSERT(attr->la_valid & (LA_MODE | LA_TYPE));
+       attr->la_valid &= ~(LA_MODE | LA_TYPE);
        rc = mdd_attr_set_internal(env, child, attr, handle, 0);
-        if (rc != 0)
-                RETURN(rc);
+       /* arguments are supposed to stay the same */
+       attr->la_valid |= LA_MODE | LA_TYPE;
+       if (rc != 0)
+               RETURN(rc);
 
        if (S_ISDIR(attr->la_mode)) {
                 /* Add "." and ".." for newly created dir */
@@ -1477,7 +1480,6 @@ static int mdd_create_sanity_check(const struct lu_env *env,
         struct lu_fid     *fid       = &info->mti_fid;
         struct mdd_object *obj       = md2mdd_obj(pobj);
         struct mdd_device *m         = mdo2mdd(pobj);
-        int lookup                   = spec->sp_cr_lookup;
         int rc;
         ENTRY;
 
@@ -1485,12 +1487,12 @@ static int mdd_create_sanity_check(const struct lu_env *env,
         if (mdd_is_dead_obj(obj))
                 RETURN(-ENOENT);
 
-        /*
+       /*
          * In some cases this lookup is not needed - we know before if name
          * exists or not because MDT performs lookup for it.
          * name length check is done in lookup.
          */
-        if (lookup) {
+       if (spec->sp_cr_lookup) {
                 /*
                  * Check if the name already exist, though it will be checked in
                  * _index_insert also, for avoiding rolling back if exists
@@ -1553,8 +1555,7 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd,
                              struct thandle *handle,
                              const struct md_op_spec *spec)
 {
-       struct mdd_thread_info *info = mdd_env_info(env);
-        int            rc = 0;
+       int rc;
 
        rc = mdd_declare_object_create_internal(env, p, c, attr, handle, spec);
         if (rc)
@@ -1574,7 +1575,7 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd,
                                GOTO(out, rc);
                }
 
-               rc = mdo_declare_attr_set(env, c, &info->mti_pattr, handle);
+               rc = mdo_declare_attr_set(env, c, attr, handle);
                if (rc)
                        GOTO(out, rc);
 
@@ -1592,13 +1593,16 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd,
         }
 
        rc = mdd_declare_object_initialize(env, c, attr, handle);
-        if (rc)
-                GOTO(out, rc);
+       if (rc)
+               GOTO(out, rc);
 
-        rc = mdo_declare_index_insert(env, p, mdo2fid(c),
-                                      name->ln_name, handle);
-        if (rc)
-                GOTO(out, rc);
+       if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+               rc = orph_declare_index_insert(env, c, attr->la_mode, handle);
+       else
+               rc = mdo_declare_index_insert(env, p, mdo2fid(c),
+                                             name->ln_name, handle);
+       if (rc)
+               GOTO(out, rc);
 
        /* replay case, create LOV EA from client data */
        if (spec->no_create || (spec->sp_cr_flags & MDS_OPEN_HAS_EA)) {
@@ -1620,9 +1624,11 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd,
                         GOTO(out, rc);
         }
 
-       rc = mdo_declare_attr_set(env, p, attr, handle);
-        if (rc)
-                return rc;
+       if (!(spec->sp_cr_flags & MDS_OPEN_VOLATILE)) {
+               rc = mdo_declare_attr_set(env, p, attr, handle);
+               if (rc)
+                       return rc;
+       }
 
         rc = mdd_declare_changelog_store(env, mdd, name, handle);
         if (rc)
@@ -1640,19 +1646,19 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
                      const struct lu_name *lname, struct md_object *child,
                      struct md_op_spec *spec, struct md_attr* ma)
 {
-        struct mdd_thread_info *info = mdd_env_info(env);
-        struct lu_attr         *la = &info->mti_la_for_fix;
-        struct mdd_object      *mdd_pobj = md2mdd_obj(pobj);
-        struct mdd_object      *son = md2mdd_obj(child);
-        struct mdd_device      *mdd = mdo2mdd(pobj);
-        struct lu_attr         *attr = &ma->ma_attr;
-        struct thandle         *handle;
-       struct lu_attr         *pattr = &info->mti_pattr;
-        struct dynlock_handle  *dlh;
-        const char             *name = lname->ln_name;
-       int rc, created = 0, initialized = 0, inserted = 0;
-        int got_def_acl = 0;
-        ENTRY;
+       struct mdd_thread_info  *info = mdd_env_info(env);
+       struct lu_attr          *la = &info->mti_la_for_fix;
+       struct mdd_object       *mdd_pobj = md2mdd_obj(pobj);
+       struct mdd_object       *son = md2mdd_obj(child);
+       struct mdd_device       *mdd = mdo2mdd(pobj);
+       struct lu_attr          *attr = &ma->ma_attr;
+       struct thandle          *handle;
+       struct lu_attr          *pattr = &info->mti_pattr;
+       struct dynlock_handle   *dlh;
+       const char              *name = lname->ln_name;
+       int                      rc, created = 0, initialized = 0, inserted = 0;
+       int                      got_def_acl = 0;
+       ENTRY;
 
         /*
          * Two operations have to be performed:
@@ -1732,21 +1738,21 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
         if (rc)
                 GOTO(out_stop, rc);
 
-        dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
-        if (dlh == NULL)
-                GOTO(out_trans, rc = -ENOMEM);
+       dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
+       if (dlh == NULL)
+               GOTO(out_trans, rc = -ENOMEM);
 
-        mdd_write_lock(env, son, MOR_TGT_CHILD);
-       rc = mdd_object_create_internal(env, mdd_pobj, son, attr, handle, spec);
-        if (rc) {
-                mdd_write_unlock(env, son);
-                GOTO(cleanup, rc);
-        }
+       mdd_write_lock(env, son, MOR_TGT_CHILD);
+       rc = mdd_object_create_internal(env, NULL, son, attr, handle, spec);
+       if (rc) {
+               mdd_write_unlock(env, son);
+               GOTO(cleanup, rc);
+       }
 
-        created = 1;
+       created = 1;
 
 #ifdef CONFIG_FS_POSIX_ACL
-        if (got_def_acl) {
+       if (got_def_acl) {
                struct lu_buf *acl_buf;
 
                acl_buf = mdd_buf_get(env, info->mti_xattr_buf, got_def_acl);
@@ -1755,10 +1761,10 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
                        mdd_write_unlock(env, son);
                        GOTO(cleanup, rc);
                }
-        }
+       }
 #endif
 
-        rc = mdd_object_initialize(env, mdo2fid(mdd_pobj), lname,
+       rc = mdd_object_initialize(env, mdo2fid(mdd_pobj), lname,
                                   son, attr, handle, spec);
 
        /*
@@ -1767,8 +1773,8 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
         *      MDT calls this xattr_set(LOV) in a different transaction.
         *      probably this way we code can be made better.
         */
-       if (rc == 0 &&
-                       (spec->no_create || (spec->sp_cr_flags & MDS_OPEN_HAS_EA))) {
+       if (rc == 0 && (spec->no_create ||
+                       (spec->sp_cr_flags & MDS_OPEN_HAS_EA))) {
                const struct lu_buf *buf;
 
                buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
@@ -1776,26 +1782,33 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
                rc = mdo_xattr_set(env, son, buf, XATTR_NAME_LOV, 0, handle,
                                BYPASS_CAPA);
        }
-        mdd_write_unlock(env, son);
-        if (rc)
-                /*
-                 * Object has no links, so it will be destroyed when last
-                 * reference is released. (XXX not now.)
-                 */
-                GOTO(cleanup, rc);
 
-        initialized = 1;
+       if (rc == 0 && spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+               rc = __mdd_orphan_add(env, son, handle);
 
-        rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son),
-                                name, S_ISDIR(attr->la_mode), handle,
-                                mdd_object_capa(env, mdd_pobj));
-        if (rc)
-                GOTO(cleanup, rc);
+       mdd_write_unlock(env, son);
+
+       if (rc != 0)
+               /*
+                * Object has no links, so it will be destroyed when last
+                * reference is released. (XXX not now.)
+                */
+               GOTO(cleanup, rc);
+
+       initialized = 1;
+
+       if (!(spec->sp_cr_flags & MDS_OPEN_VOLATILE))
+               rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son),
+                                       name, S_ISDIR(attr->la_mode), handle,
+                                       mdd_object_capa(env, mdd_pobj));
+
+       if (rc != 0)
+               GOTO(cleanup, rc);
 
-        inserted = 1;
+       inserted = 1;
 
         if (S_ISLNK(attr->la_mode)) {
-                struct md_ucred  *uc = md_ucred(env);
+               struct lu_ucred  *uc = lu_ucred_assert(env);
                 struct dt_object *dt = mdd_object_child(son);
                 const char *target_name = spec->u.sp_symname;
                 int sym_len = strlen(target_name);
@@ -1803,10 +1816,10 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
                 loff_t pos = 0;
 
                 buf = mdd_buf_get_const(env, target_name, sym_len);
-                rc = dt->do_body_ops->dbo_write(env, dt, buf, &pos, handle,
-                                                mdd_object_capa(env, son),
-                                                uc->mu_cap &
-                                                CFS_CAP_SYS_RESOURCE_MASK);
+               rc = dt->do_body_ops->dbo_write(env, dt, buf, &pos, handle,
+                                               mdd_object_capa(env, son),
+                                               uc->uc_cap &
+                                               CFS_CAP_SYS_RESOURCE_MASK);
 
                 if (rc == sym_len)
                         rc = 0;
@@ -1814,11 +1827,16 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
                         GOTO(cleanup, rc = -EFAULT);
         }
 
+       /* volatile file creation does not update parent directory times */
+       if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+               GOTO(cleanup, rc = 0);
+
+       /* update parent directory mtime/ctime */
        *la = *attr;
-        la->la_valid = LA_CTIME | LA_MTIME;
+       la->la_valid = LA_CTIME | LA_MTIME;
        rc = mdd_attr_check_set_internal(env, mdd_pobj, la, handle, 0);
-        if (rc)
-                GOTO(cleanup, rc);
+       if (rc)
+               GOTO(cleanup, rc);
 
         EXIT;
 cleanup:
@@ -1826,9 +1844,12 @@ cleanup:
                int rc2;
 
                if (inserted != 0) {
-                       rc2 = __mdd_index_delete(env, mdd_pobj, name,
-                                                S_ISDIR(attr->la_mode),
-                                                handle, BYPASS_CAPA);
+                       if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+                               rc2 = __mdd_orphan_del(env, son, handle);
+                       else
+                               rc2 = __mdd_index_delete(env, mdd_pobj, name,
+                                                        S_ISDIR(attr->la_mode),
+                                                        handle, BYPASS_CAPA);
                        if (rc2 != 0)
                                goto out_stop;
                }
@@ -1867,7 +1888,7 @@ out_stop:
 out_free:
         /* The child object shouldn't be cached anymore */
         if (rc)
-                cfs_set_bit(LU_OBJECT_HEARD_BANSHEE,
+               set_bit(LU_OBJECT_HEARD_BANSHEE,
                             &child->mo_lu.lo_header->loh_flags);
         return rc;
 }
@@ -2744,16 +2765,22 @@ out:
        if (rc == 0)
                rc = rc2;
        if (rc) {
+               int error = 1;
+               if (rc == -EOVERFLOW || rc == - ENOENT)
+                       error = 0;
                if (oldpfid == NULL)
-                       CERROR("link_ea add '%.*s' failed %d "DFID"\n",
+                       CDEBUG(error ? D_ERROR : D_OTHER,
+                              "link_ea add '%.*s' failed %d "DFID"\n",
                               newlname->ln_namelen, newlname->ln_name,
                               rc, PFID(mdd_object_fid(mdd_obj)));
                else if (newpfid == NULL)
-                       CERROR("link_ea del '%.*s' failed %d "DFID"\n",
+                       CDEBUG(error ? D_ERROR : D_OTHER,
+                              "link_ea del '%.*s' failed %d "DFID"\n",
                               oldlname->ln_namelen, oldlname->ln_name,
                               rc, PFID(mdd_object_fid(mdd_obj)));
                else
-                       CERROR("link_ea rename '%.*s'->'%.*s' failed %d "
+                       CDEBUG(error ? D_ERROR : D_OTHER,
+                              "link_ea rename '%.*s'->'%.*s' failed %d "
                               DFID"\n",
                               oldlname->ln_namelen, oldlname->ln_name,
                               newlname->ln_namelen, newlname->ln_name,