Whamcloud - gitweb
LU-1303 lod: propagate real object size on a new striping
authorAlex Zhuravlev <alexey.zhuravlev@intel.com>
Thu, 20 Sep 2012 12:00:04 +0000 (16:00 +0400)
committerAndreas Dilger <adilger@whamcloud.com>
Fri, 28 Sep 2012 22:41:54 +0000 (18:41 -0400)
it's possible to truncate file with no striping, when create
striping. in such a case lod's object create propagate actual
size down to the stack.

Signed-off-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Change-Id: Iaf4a91516892db23f11052bd1a656ee2108a7113
Reviewed-on: http://review.whamcloud.com/4059
Reviewed-by: wangdi <di.wang@whamcloud.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mike Pershin <tappro@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/lod/lod_object.c

index 24a07d6..676eb98 100644 (file)
@@ -634,6 +634,53 @@ static void lod_ah_init(const struct lu_env *env,
        EXIT;
 }
 
        EXIT;
 }
 
+#define ll_do_div64(aaa,bbb)    do_div((aaa), (bbb))
+/*
+ * this function handles a special case when truncate was done
+ * on a stripeless object and now striping is being created
+ * we can't lose that size, so we have to propagate it to newly
+ * created object
+ */
+static int lod_declare_init_size(const struct lu_env *env,
+                                struct dt_object *dt, struct thandle *th)
+{
+       struct dt_object   *next = dt_object_child(dt);
+       struct lod_object  *lo = lod_dt_obj(dt);
+       struct lu_attr     *attr = &lod_env_info(env)->lti_attr;
+       uint64_t            size, offs;
+       int                 rc, stripe;
+       ENTRY;
+
+       /* XXX: we support the simplest (RAID0) striping so far */
+       LASSERT(lo->ldo_stripe || lo->ldo_stripenr == 0);
+       LASSERT(lo->ldo_stripe_size > 0);
+
+       rc = dt_attr_get(env, next, attr, BYPASS_CAPA);
+       LASSERT(attr->la_valid & LA_SIZE);
+       if (rc)
+               RETURN(rc);
+
+       size = attr->la_size;
+       if (size == 0)
+               RETURN(0);
+
+       /* ll_do_div64(a, b) returns a % b, and a = a / b */
+       ll_do_div64(size, (__u64) lo->ldo_stripe_size);
+       stripe = ll_do_div64(size, (__u64) lo->ldo_stripenr);
+
+       size = size * lo->ldo_stripe_size;
+       offs = attr->la_size;
+       size += ll_do_div64(offs, lo->ldo_stripe_size);
+
+       attr->la_valid = LA_SIZE;
+       attr->la_size = size;
+
+       rc = dt_declare_attr_set(env, lo->ldo_stripe[stripe], attr, th);
+
+       RETURN(rc);
+}
+
+
 /**
  * Create declaration of striped object
  */
 /**
  * Create declaration of striped object
  */
@@ -673,6 +720,14 @@ int lod_declare_striped_object(const struct lu_env *env, struct dt_object *dt,
        if (rc)
                GOTO(out, rc);
 
        if (rc)
                GOTO(out, rc);
 
+       /*
+        * if striping is created with local object's size > 0,
+        * we have to propagate this size to specific object
+        * the case is possible only when local object was created previously
+        */
+       if (dt_object_exists(next))
+               rc = lod_declare_init_size(env, dt, th);
+
 out:
        RETURN(rc);
 }
 out:
        RETURN(rc);
 }