Whamcloud - gitweb
b=22190 return error on write if rdonly mode is on, don't reply if umount
[fs/lustre-release.git] / lustre / cmm / cmm_split.c
index 193a8b0..eb91f3f 100644 (file)
@@ -1,31 +1,45 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- *  lustre/cmm/cmm_split.c
- *  Lustre splitting dir
+ * GPL HEADER START
  *
- *  Copyright (c) 2006 Cluster File Systems, Inc.
- *   Author: Alex Thomas  <alex@clusterfs.com>
- *           Wang Di      <wangdi@clusterfs.com>
- *           Yury Umanets <umka@clusterfs.com>
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- *   This file is part of the Lustre file system, http://www.lustre.org
- *   Lustre is a trademark of Cluster File Systems, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
  *
- *   You may have signed or agreed to another license before downloading
- *   this software.  If so, you are bound by the terms and conditions
- *   of that agreement, and the following does not apply to you.  See the
- *   LICENSE file included with this distribution for more information.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
  *
- *   If you did not agree to a different license, then this copy of Lustre
- *   is open source software; you can redistribute it and/or modify it
- *   under the terms of version 2 of the GNU General Public License as
- *   published by the Free Software Foundation.
+ * 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
  *
- *   In either case, Lustre is distributed in the hope that it will be
- *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   license text for more details.
+ * 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.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/cmm/cmm_split.c
+ *
+ * Lustre splitting dir
+ *
+ * Author: Alex Thomas  <alex@clusterfs.com>
+ * Author: Wang Di      <wangdi@clusterfs.com>
+ * Author: Yury Umanets <umka@clusterfs.com>
  */
 
 #ifndef EXPORT_SYMTAB
@@ -227,17 +241,7 @@ struct cmm_object *cmm_object_find(const struct lu_env *env,
                                    struct cmm_device *d,
                                    const struct lu_fid *f)
 {
-        struct lu_object *o;
-        struct cmm_object *m;
-        ENTRY;
-
-        o = lu_object_find(env, d->cmm_md_dev.md_lu_dev.ld_site, f);
-        if (IS_ERR(o))
-                m = (struct cmm_object *)o;
-        else
-                m = lu2cmm_obj(lu_object_locate(o->lo_header,
-                               d->cmm_md_dev.md_lu_dev.ld_type));
-        RETURN(m);
+        return md2cmm_obj(md_object_find_slice(env, &d->cmm_md_dev, fid));
 }
 
 static inline void cmm_object_put(const struct lu_env *env,
@@ -260,18 +264,13 @@ static int cmm_split_fid_alloc(const struct lu_env *env,
 
         LASSERT(cmm != NULL && mc != NULL && fid != NULL);
 
-        down(&mc->mc_fid_sem);
+        cfs_down(&mc->mc_fid_sem);
 
         /* Alloc new fid on @mc. */
         rc = obd_fid_alloc(mc->mc_desc.cl_exp, fid, NULL);
-        if (rc > 0) {
-                /* Setup FLD for new sequenceif needed. */
-                rc = fld_client_create(cmm->cmm_fld, fid_seq(fid),
-                                       mc->mc_num, env);
-                if (rc)
-                        CERROR("Can't create fld entry, rc %d\n", rc);
-        }
-        up(&mc->mc_fid_sem);
+        if (rc > 0)
+                rc = 0;
+        cfs_up(&mc->mc_fid_sem);
 
         RETURN(rc);
 }
@@ -347,15 +346,13 @@ static int cmm_split_slaves_create(const struct lu_env *env,
         slave_lmv->mea_magic = MEA_MAGIC_HASH_SEGMENT;
         slave_lmv->mea_count = 0;
 
-        list_for_each_entry_safe(mc, tmp, &cmm->cmm_targets, mc_linkage) {
+        cfs_list_for_each_entry_safe(mc, tmp, &cmm->cmm_targets, mc_linkage) {
                 rc = cmm_split_slave_create(env, cmm, mc, &lmv->mea_ids[i],
                                             ma, slave_lmv, sizeof(*slave_lmv));
                 if (rc)
                         GOTO(cleanup, rc);
                 i++;
         }
-
-        ma->ma_valid |= MA_LMV;
         EXIT;
 cleanup:
         return rc;
@@ -381,7 +378,7 @@ static inline struct lu_name *cmm_name(const struct lu_env *env,
         cmi = cmm_env_info(env);
         lname = &cmi->cti_name;
         lname->ln_name = name;
-        /* NOT count the terminating '\0' of name for length */
+        /* do NOT count the terminating '\0' of name for length */
         lname->ln_namelen = buflen - 1;
         return lname;
 }
@@ -396,7 +393,7 @@ static int cmm_split_remove_entry(const struct lu_env *env,
 {
         struct cmm_device *cmm = cmm_obj2dev(md2cmm_obj(mo));
         struct cmm_thread_info *cmi;
-         struct md_attr *ma;
+        struct md_attr *ma;
         struct cmm_object *obj;
         int is_dir, rc;
         char *name;
@@ -420,7 +417,7 @@ static int cmm_split_remove_entry(const struct lu_env *env,
                 /*
                  * XXX: These days only cross-ref dirs are possible, so for the
                  * sake of simplicity, in split, we suppose that all cross-ref
-                 * names pint to directory and do not do additional getattr to
+                 * names point to directory and do not do additional getattr to
                  * remote MDT.
                  */
                 is_dir = 1;
@@ -456,8 +453,8 @@ static int cmm_split_remove_entry(const struct lu_env *env,
          * use highest bit of hash).
          */
         if (is_dir) {
-                ent->lde_hash = le32_to_cpu(ent->lde_hash);
-                ent->lde_hash = cpu_to_le32(ent->lde_hash | MAX_HASH_HIGHEST_BIT);
+                ent->lde_hash = le64_to_cpu(ent->lde_hash);
+                ent->lde_hash = cpu_to_le64(ent->lde_hash | MAX_HASH_HIGHEST_BIT);
         }
         EXIT;
 cleanup:
@@ -472,7 +469,7 @@ cleanup:
 static int cmm_split_remove_page(const struct lu_env *env,
                                  struct md_object *mo,
                                  struct lu_rdpg *rdpg,
-                                 __u32 hash_end, __u32 *len)
+                                 __u64 hash_end, __u32 *len)
 {
         struct lu_dirpage *dp;
         struct lu_dirent  *ent;
@@ -480,10 +477,10 @@ static int cmm_split_remove_page(const struct lu_env *env,
         ENTRY;
 
         *len = 0;
-        kmap(rdpg->rp_pages[0]);
+        cfs_kmap(rdpg->rp_pages[0]);
         dp = page_address(rdpg->rp_pages[0]);
         for (ent = lu_dirent_start(dp);
-             ent != NULL && le32_to_cpu(ent->lde_hash) < hash_end;
+             ent != NULL && le64_to_cpu(ent->lde_hash) < hash_end;
              ent = lu_dirent_next(ent)) {
                 rc = cmm_split_remove_entry(env, mo, ent);
                 if (rc) {
@@ -505,7 +502,7 @@ static int cmm_split_remove_page(const struct lu_env *env,
                 *len += sizeof(struct lu_dirpage);
         EXIT;
 unmap:
-        kunmap(rdpg->rp_pages[0]);
+        cfs_kunmap(rdpg->rp_pages[0]);
         return rc;
 }
 
@@ -551,7 +548,7 @@ static int cmm_split_process_stripe(const struct lu_env *env,
                                     struct md_object *mo,
                                     struct lu_rdpg *rdpg,
                                     struct lu_fid *lf,
-                                    __u32 end)
+                                    __u64 end)
 {
         int rc, done = 0;
         ENTRY;
@@ -584,13 +581,13 @@ static int cmm_split_process_stripe(const struct lu_env *env,
                         }
                 }
 
-                kmap(rdpg->rp_pages[0]);
+                cfs_kmap(rdpg->rp_pages[0]);
                 ldp = page_address(rdpg->rp_pages[0]);
-                if (le32_to_cpu(ldp->ldp_hash_end) >= end)
+                if (le64_to_cpu(ldp->ldp_hash_end) >= end)
                         done = 1;
 
-                rdpg->rp_hash = le32_to_cpu(ldp->ldp_hash_end);
-                kunmap(rdpg->rp_pages[0]);
+                rdpg->rp_hash = le64_to_cpu(ldp->ldp_hash_end);
+                cfs_kunmap(rdpg->rp_pages[0]);
         } while (!done);
 
         RETURN(rc);
@@ -602,7 +599,7 @@ static int cmm_split_process_dir(const struct lu_env *env,
 {
         struct cmm_device *cmm = cmm_obj2dev(md2cmm_obj(mo));
         struct lu_rdpg *rdpg = &cmm_env_info(env)->cmi_rdpg;
-        __u32 hash_segement;
+        __u64 hash_segment;
         int rc = 0, i;
         ENTRY;
 
@@ -612,28 +609,28 @@ static int cmm_split_process_dir(const struct lu_env *env,
         rdpg->rp_pages  = cmm_env_info(env)->cmi_pages;
 
         for (i = 0; i < rdpg->rp_npages; i++) {
-                rdpg->rp_pages[i] = alloc_pages(GFP_KERNEL, 0);
+                rdpg->rp_pages[i] = cfs_alloc_page(CFS_ALLOC_STD);
                 if (rdpg->rp_pages[i] == NULL)
                         GOTO(cleanup, rc = -ENOMEM);
         }
 
-        LASSERT(ma->ma_valid & MA_LMV);
-        hash_segement = MAX_HASH_SIZE / (cmm->cmm_tgt_count + 1);
+        hash_segment = MAX_HASH_SIZE;
+        do_div(hash_segment, cmm->cmm_tgt_count + 1);
         for (i = 1; i < cmm->cmm_tgt_count + 1; i++) {
                 struct lu_fid *lf;
-                __u32 hash_end;
+                __u64 hash_end;
 
                 lf = &ma->ma_lmv->mea_ids[i];
 
-                rdpg->rp_hash = i * hash_segement;
+                rdpg->rp_hash = i * hash_segment;
                 if (i == cmm->cmm_tgt_count)
                         hash_end = MAX_HASH_SIZE;
                 else
-                        hash_end = rdpg->rp_hash + hash_segement;
+                        hash_end = rdpg->rp_hash + hash_segment;
                 rc = cmm_split_process_stripe(env, mo, rdpg, lf, hash_end);
                 if (rc) {
                         CERROR("Error (rc = %d) while splitting for %d: fid="
-                               DFID", %08x:%08x\n", rc, i, PFID(lf),
+                               DFID", "LPX64":"LPX64"\n", rc, i, PFID(lf),
                                rdpg->rp_hash, hash_end);
                         GOTO(cleanup, rc);
                 }
@@ -642,7 +639,7 @@ static int cmm_split_process_dir(const struct lu_env *env,
 cleanup:
         for (i = 0; i < rdpg->rp_npages; i++)
                 if (rdpg->rp_pages[i] != NULL)
-                        __free_pages(rdpg->rp_pages[i], 0);
+                        __cfs_free_page(rdpg->rp_pages[i]);
         return rc;
 }
 
@@ -677,7 +674,7 @@ int cmm_split_dir(const struct lu_env *env, struct md_object *mo)
          * Disable transacrions for split, since there will be so many trans in
          * this one ops, conflict with current recovery design.
          */
-        rc = cmm_upcall(env, &cmm->cmm_md_dev, MD_NO_TRANS);
+        rc = cmm_upcall(env, &cmm->cmm_md_dev, MD_NO_TRANS, NULL);
         if (rc) {
                 CERROR("Can't disable trans for split, rc %d\n", rc);
                 GOTO(out, rc);
@@ -704,7 +701,6 @@ int cmm_split_dir(const struct lu_env *env, struct md_object *mo)
         }
 
         /* Step5: Set mea to the master object. */
-        LASSERT(ma->ma_valid & MA_LMV);
         buf = cmm_buf_get(env, ma->ma_lmv, ma->ma_lmv_size);
         rc = mo_xattr_set(env, md_object_next(mo), buf,
                           MDS_LMV_MD_NAME, 0);