Whamcloud - gitweb
LU-7845 gss: support namespace in lgss_keyring
[fs/lustre-release.git] / lustre / osd-zfs / osd_xattr.c
index 9fd2437..d3cdb9f 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -252,8 +248,8 @@ int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
        LASSERT(osd_invariant(obj));
 
        if (!osd_obj2dev(obj)->od_posix_acl &&
-           (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 ||
-            strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0))
+           (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
+            strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
                RETURN(-EOPNOTSUPP);
 
        down_read(&obj->oo_guard);
@@ -267,39 +263,18 @@ int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
        RETURN(rc);
 }
 
-void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj,
-                            int vallen, const char *name,
-                            struct osd_thandle *oh)
+/* the function is used to declare EAs when SA is not supported */
+void __osd_xattr_declare_legacy(const struct lu_env *env,
+                               struct osd_object *obj,
+                               int vallen, const char *name,
+                               struct osd_thandle *oh)
 {
        struct osd_device *osd = osd_obj2dev(obj);
-       dmu_buf_t         *db = obj->oo_db;
-       dmu_tx_t          *tx = oh->ot_tx;
-       uint64_t           xa_data_obj;
-       int                rc = 0;
-       int                here;
-
-       if (unlikely(obj->oo_destroyed))
-               return;
-
-       here = dt_object_exists(&obj->oo_dt);
-
-       /* object may be not yet created */
-       if (here) {
-               LASSERT(db);
-               LASSERT(obj->oo_sa_hdl);
-               /* we might just update SA_ZPL_DXATTR */
-               dmu_tx_hold_sa(tx, obj->oo_sa_hdl, 1);
-
-               if (obj->oo_xattr == ZFS_NO_OBJECT)
-                       rc = -ENOENT;
-       }
+       dmu_tx_t *tx = oh->ot_tx;
+       uint64_t xa_data_obj;
+       int rc;
 
-       if (!here || rc == -ENOENT) {
-               /* we'll be updating SA_ZPL_XATTR */
-               if (here) {
-                       LASSERT(obj->oo_sa_hdl);
-                       dmu_tx_hold_sa(tx, obj->oo_sa_hdl, 1);
-               }
+       if (obj->oo_xattr == ZFS_NO_OBJECT) {
                /* xattr zap + entry */
                dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, (char *) name);
                /* xattr value obj */
@@ -318,7 +293,6 @@ void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj,
                dmu_tx_hold_bonus(tx, xa_data_obj);
                dmu_tx_hold_free(tx, xa_data_obj, vallen, DMU_OBJECT_END);
                dmu_tx_hold_write(tx, xa_data_obj, 0, vallen);
-               return;
        } else if (rc == -ENOENT) {
                /*
                 * Entry doesn't exist, we need to create a new one and a new
@@ -328,11 +302,43 @@ void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj,
                dmu_tx_hold_zap(tx, obj->oo_xattr, TRUE, (char *) name);
                dmu_tx_hold_sa_create(tx, ZFS_SA_BASE_ATTR_SIZE);
                dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, vallen);
+       }
+}
+
+void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj,
+                            int vallen, const char *name,
+                            struct osd_thandle *oh)
+{
+       dmu_buf_t         *db = obj->oo_db;
+       dmu_tx_t          *tx = oh->ot_tx;
+
+       if (unlikely(obj->oo_destroyed))
+               return;
+
+       if (unlikely(!osd_obj2dev(obj)->od_xattr_in_sa)) {
+               __osd_xattr_declare_legacy(env, obj, vallen, name, oh);
                return;
        }
 
-       /* An error happened */
-       tx->tx_err = -rc;
+       /* declare EA in SA */
+       if (dt_object_exists(&obj->oo_dt)) {
+               LASSERT(obj->oo_sa_hdl);
+               /* XXX: it should be possible to skip spill
+                * declaration if specific EA is part of
+                * bonus and doesn't grow */
+               dmu_tx_hold_spill(tx, db->db_object);
+               return;
+       }
+
+       /* the object doesn't exist, but we've declared bonus
+        * in osd_declare_object_create() yet */
+       if (obj->oo_ea_in_bonus > DN_MAX_BONUSLEN) {
+               /* spill has been declared already */
+       } else if (obj->oo_ea_in_bonus + vallen > DN_MAX_BONUSLEN) {
+               /* we're about to exceed bonus, let's declare spill */
+               dmu_tx_hold_spill(tx, DMU_NEW_OBJECT);
+       }
+       obj->oo_ea_in_bonus += vallen;
 }
 
 int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
@@ -353,41 +359,6 @@ int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
        RETURN(0);
 }
 
-int __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj,
-                          struct osd_thandle *oh)
-{
-       struct lu_buf     *lb = &osd_oti_get(env)->oti_xattr_lbuf;
-       struct osd_device *osd = osd_obj2dev(obj);
-       char              *dxattr;
-       size_t             size;
-       int                rc;
-
-       obj->oo_late_xattr = 0;
-
-       /* Update the SA for additions, modifications, and removals. */
-       rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR);
-       if (rc)
-               return rc;
-
-       lu_buf_check_and_alloc(lb, size);
-       if (lb->lb_buf == NULL) {
-               CERROR("%s: can't allocate buffer for xattr update\n",
-                               osd->od_svname);
-               return -ENOMEM;
-       }
-
-       dxattr = lb->lb_buf;
-       rc = -nvlist_pack(obj->oo_sa_xattr, &dxattr, &size,
-                       NV_ENCODE_XDR, KM_SLEEP);
-       if (rc)
-               return rc;
-       LASSERT(dxattr == lb->lb_buf);
-
-       sa_update(obj->oo_sa_hdl, SA_ZPL_DXATTR(osd), dxattr, size, oh->ot_tx);
-
-       return 0;
-}
-
 /*
  * Set an extended attribute.
  * This transaction must have called udmu_xattr_declare_set() first.
@@ -396,27 +367,42 @@ int __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj,
  *
  * No locking is done here.
  */
-int __osd_sa_xattr_schedule_update(const struct lu_env *env,
-                                  struct osd_object *obj,
-                                  struct osd_thandle *oh)
+int __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj,
+                     struct osd_thandle *oh)
 {
+       struct osd_device *osd = osd_obj2dev(obj);
+       char              *dxattr;
+       size_t             sa_size;
+       int                rc;
+
        ENTRY;
        LASSERT(obj->oo_sa_hdl);
        LASSERT(obj->oo_sa_xattr);
 
-       /* schedule batched SA update in osd_object_sa_dirty_rele() */
-       obj->oo_late_xattr = 1;
-       osd_object_sa_dirty_add(obj, oh);
+       /* Update the SA for additions, modifications, and removals. */
+       rc = -nvlist_size(obj->oo_sa_xattr, &sa_size, NV_ENCODE_XDR);
+       if (rc)
+               return rc;
+
+       dxattr = osd_zio_buf_alloc(sa_size);
+       if (dxattr == NULL)
+               RETURN(-ENOMEM);
 
-       RETURN(0);
+       rc = -nvlist_pack(obj->oo_sa_xattr, &dxattr, &sa_size,
+                               NV_ENCODE_XDR, KM_SLEEP);
+       if (rc)
+               GOTO(out_free, rc);
 
+       rc = osd_object_sa_update(obj, SA_ZPL_DXATTR(osd), dxattr, sa_size, oh);
+out_free:
+       osd_zio_buf_free(dxattr, sa_size);
+       RETURN(rc);
 }
 
 int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj,
                       const struct lu_buf *buf, const char *name, int fl,
                       struct osd_thandle *oh)
 {
-       dmu_buf_impl_t *db;
        uchar_t *nv_value;
        size_t  size;
        int     nv_size;
@@ -457,7 +443,7 @@ int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj,
                                                DATA_TYPE_BYTE_ARRAY);
                        if (rc < 0)
                                return rc;
-                       rc = __osd_sa_xattr_schedule_update(env, obj, oh);
+                       rc = __osd_sa_xattr_update(env, obj, oh);
                        return rc == 0 ? -EFBIG : rc;
                }
        } else if (rc == -ENOENT) {
@@ -488,14 +474,7 @@ int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj,
        if (rc)
                return rc;
 
-       /* batch updates only for just created dnodes where we
-        * used to set number of EAs in a single transaction */
-       db = (dmu_buf_impl_t *)obj->oo_db;
-       if (DB_DNODE(db)->dn_allocated_txg == oh->ot_tx->tx_txg)
-               rc = __osd_sa_xattr_schedule_update(env, obj, oh);
-       else
-               rc = __osd_sa_xattr_update(env, obj, oh);
-
+       rc = __osd_sa_xattr_update(env, obj, oh);
        return rc;
 }
 
@@ -520,8 +499,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj,
 
                la->la_valid = LA_MODE;
                la->la_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
-               rc = __osd_zap_create(env, osd, &xa_zap_db, tx, la,
-                                     obj->oo_db->db_object, 0);
+               rc = __osd_zap_create(env, osd, &xa_zap_db, tx, la, 0);
                if (rc)
                        return rc;
 
@@ -576,8 +554,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj,
 
                la->la_valid = LA_MODE;
                la->la_mode = S_IFREG | S_IRUGO | S_IWUSR;
-               rc = __osd_object_create(env, obj, &xa_data_db, tx, la,
-                                        obj->oo_xattr);
+               rc = __osd_object_create(env, obj, &xa_data_db, tx, la);
                if (rc)
                        goto out;
                xa_data_obj = xa_data_db->db_object;
@@ -626,8 +603,8 @@ int osd_xattr_set(const struct lu_env *env, struct dt_object *dt,
        LASSERT(osd_invariant(obj));
 
        if (!osd_obj2dev(obj)->od_posix_acl &&
-           (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 ||
-            strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0))
+           (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
+            strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
                RETURN(-EOPNOTSUPP);
 
        if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LINKEA_OVERFLOW) &&
@@ -716,7 +693,7 @@ static int __osd_sa_xattr_del(const struct lu_env *env, struct osd_object *obj,
 
        rc = -nvlist_remove(obj->oo_sa_xattr, name, DATA_TYPE_BYTE_ARRAY);
        if (rc == 0)
-               rc = __osd_sa_xattr_schedule_update(env, obj, oh);
+               rc = __osd_sa_xattr_update(env, obj, oh);
        return rc;
 }
 
@@ -773,8 +750,8 @@ int osd_xattr_del(const struct lu_env *env, struct dt_object *dt,
        LASSERT(oh->ot_tx != NULL);
 
        if (!osd_obj2dev(obj)->od_posix_acl &&
-           (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 ||
-            strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0))
+           (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
+            strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
                RETURN(-EOPNOTSUPP);
 
        down_write(&obj->oo_guard);
@@ -868,7 +845,7 @@ int osd_xattrs_destroy(const struct lu_env *env,
 
        rc = -dmu_object_free(osd->od_os, obj->oo_xattr, tx);
        if (rc)
-               CERROR("%s: free xattr "LPU64" failed: rc = %d\n",
+               CERROR("%s: free xattr %llu failed: rc = %d\n",
                       osd->od_svname, obj->oo_xattr, rc);
 
        return rc;
@@ -894,8 +871,8 @@ osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj,
                const char *name = nvpair_name(nvp);
 
                if (!osd_obj2dev(obj)->od_posix_acl &&
-                   (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 ||
-                    strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0))
+                   (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
+                    strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
                        continue;
 
                len = strlen(name);
@@ -942,8 +919,8 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
 
        while ((rc = -zap_cursor_retrieve(zc, za)) == 0) {
                if (!osd_obj2dev(obj)->od_posix_acl &&
-                   (strcmp(za->za_name, POSIX_ACL_XATTR_ACCESS) == 0 ||
-                    strcmp(za->za_name, POSIX_ACL_XATTR_DEFAULT) == 0)) {
+                   (strcmp(za->za_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
+                    strcmp(za->za_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) {
                        zap_cursor_advance(zc);
                        continue;
                }