Whamcloud - gitweb
LU-3963 Revert bitops changes
[fs/lustre-release.git] / lustre / obdclass / dt_object.c
index 2465179..16312eb 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, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -215,22 +215,25 @@ EXPORT_SYMBOL(dt_lookup_dir);
 /* this differs from dt_locate by top_dev as parameter
  * but not one from lu_site */
 struct dt_object *dt_locate_at(const struct lu_env *env,
-                              struct dt_device *dev, const struct lu_fid *fid,
-                              struct lu_device *top_dev)
+                              struct dt_device *dev,
+                              const struct lu_fid *fid,
+                              struct lu_device *top_dev,
+                              const struct lu_object_conf *conf)
 {
-       struct lu_object *lo, *n;
-       ENTRY;
+       struct lu_object *lo;
+       struct lu_object *n;
 
-       lo = lu_object_find_at(env, top_dev, fid, NULL);
+       lo = lu_object_find_at(env, top_dev, fid, conf);
        if (IS_ERR(lo))
-               return (void *)lo;
+               return ERR_PTR(PTR_ERR(lo));
 
        LASSERT(lo != NULL);
 
-       cfs_list_for_each_entry(n, &lo->lo_header->loh_layers, lo_linkage) {
+       list_for_each_entry(n, &lo->lo_header->loh_layers, lo_linkage) {
                if (n->lo_dev == &dev->dd_lu_dev)
                        return container_of0(n, struct dt_object, do_lu);
        }
+
        return ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL(dt_locate_at);
@@ -286,10 +289,9 @@ int dt_path_parser(const struct lu_env *env,
         return rc;
 }
 
-static struct dt_object *dt_store_resolve(const struct lu_env *env,
-                                          struct dt_device *dt,
-                                          const char *path,
-                                          struct lu_fid *fid)
+struct dt_object *
+dt_store_resolve(const struct lu_env *env, struct dt_device *dt,
+                const char *path, struct lu_fid *fid)
 {
        struct dt_thread_info *info = dt_info(env);
        struct dt_find_hint   *dfh = &info->dti_dfh;
@@ -320,6 +322,7 @@ static struct dt_object *dt_store_resolve(const struct lu_env *env,
         }
         return obj;
 }
+EXPORT_SYMBOL(dt_store_resolve);
 
 static struct dt_object *dt_reg_open(const struct lu_env *env,
                                      struct dt_device *dt,
@@ -564,6 +567,28 @@ EXPORT_SYMBOL(dt_directory_features);
 const struct dt_index_features dt_otable_features;
 EXPORT_SYMBOL(dt_otable_features);
 
+/* lfsck orphan */
+const struct dt_index_features dt_lfsck_orphan_features = {
+       .dif_flags              = 0,
+       .dif_keysize_min        = sizeof(struct lu_fid),
+       .dif_keysize_max        = sizeof(struct lu_fid),
+       .dif_recsize_min        = sizeof(struct lu_orphan_rec),
+       .dif_recsize_max        = sizeof(struct lu_orphan_rec),
+       .dif_ptrsize            = 4
+};
+EXPORT_SYMBOL(dt_lfsck_orphan_features);
+
+/* lfsck */
+const struct dt_index_features dt_lfsck_features = {
+       .dif_flags              = DT_IND_UPDATE,
+       .dif_keysize_min        = sizeof(struct lu_fid),
+       .dif_keysize_max        = sizeof(struct lu_fid),
+       .dif_recsize_min        = sizeof(__u8),
+       .dif_recsize_max        = sizeof(__u8),
+       .dif_ptrsize            = 4
+};
+EXPORT_SYMBOL(dt_lfsck_features);
+
 /* accounting indexes */
 const struct dt_index_features dt_acct_features = {
        .dif_flags              = DT_IND_UPDATE,
@@ -616,6 +641,8 @@ static inline const struct dt_index_features *dt_index_feat_select(__u64 seq,
                        /* slave index should be a regular file */
                        return ERR_PTR(-ENOENT);
                return &dt_quota_slv_features;
+       } else if (seq == FID_SEQ_LAYOUT_RBTREE){
+               return &dt_lfsck_orphan_features;
        } else if (seq >= FID_SEQ_NORMAL) {
                /* object is part of the namespace, verify that it is a
                 * directory */
@@ -797,7 +824,7 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
                int              i;
 
                LASSERT(pageidx < rdpg->rp_npages);
-               lp = cfs_kmap(rdpg->rp_pages[pageidx]);
+               lp = kmap(rdpg->rp_pages[pageidx]);
 
                /* fill lu pages */
                for (i = 0; i < LU_PAGE_COUNT; i++, lp++, nob -= LU_PAGE_SIZE) {
@@ -811,7 +838,7 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
                                /* end of index */
                                break;
                }
-               cfs_kunmap(rdpg->rp_pages[i]);
+               kunmap(rdpg->rp_pages[i]);
        }
 
        iops->put(env, it);
@@ -839,7 +866,7 @@ EXPORT_SYMBOL(dt_index_walk);
  * \retval appropriate error otherwise.
  */
 int dt_index_read(const struct lu_env *env, struct dt_device *dev,
-                  struct idx_info *ii, const struct lu_rdpg *rdpg)
+                 struct idx_info *ii, const struct lu_rdpg *rdpg)
 {
        const struct dt_index_features  *feat;
        struct dt_object                *obj;
@@ -851,15 +878,16 @@ int dt_index_read(const struct lu_env *env, struct dt_device *dev,
        if (rdpg->rp_count <= 0 && (rdpg->rp_count & (LU_PAGE_SIZE - 1)) != 0)
                RETURN(-EFAULT);
 
-       if (fid_seq(&ii->ii_fid) < FID_SEQ_SPECIAL)
-               /* block access to local files */
-               RETURN(-EPERM);
-
        if (fid_seq(&ii->ii_fid) >= FID_SEQ_NORMAL)
                /* we don't support directory transfer via OBD_IDX_READ for the
                 * time being */
                RETURN(-EOPNOTSUPP);
 
+       if (!fid_is_quota(&ii->ii_fid) && !fid_is_layout_rbtree(&ii->ii_fid))
+               /* Block access to all local files except quota files and
+                * layout rbtree. */
+               RETURN(-EPERM);
+
        /* lookup index object subject to the transfer */
        obj = dt_locate(env, dev, &ii->ii_fid);
        if (IS_ERR(obj))
@@ -903,13 +931,16 @@ int dt_index_read(const struct lu_env *env, struct dt_device *dev,
                /* key isn't necessarily unique */
                ii->ii_flags |= II_FL_NONUNQ;
 
-       dt_read_lock(env, obj, 0);
-       /* fetch object version before walking the index */
-       ii->ii_version = dt_version_get(env, obj);
+       if (!fid_is_layout_rbtree(&ii->ii_fid)) {
+               dt_read_lock(env, obj, 0);
+               /* fetch object version before walking the index */
+               ii->ii_version = dt_version_get(env, obj);
+       }
 
        /* walk the index and fill lu_idxpages with key/record pairs */
        rc = dt_index_walk(env, obj, rdpg, dt_index_page_build ,ii);
-       dt_read_unlock(env, obj);
+       if (!fid_is_layout_rbtree(&ii->ii_fid))
+               dt_read_unlock(env, obj);
 
        if (rc == 0) {
                /* index is empty */
@@ -923,3 +954,216 @@ out:
        return rc;
 }
 EXPORT_SYMBOL(dt_index_read);
+
+#ifdef LPROCFS
+#ifndef HAVE_ONLY_PROCFS_SEQ
+int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               *eof = 1;
+               rc = snprintf(page, count, "%u\n",
+                               (unsigned) osfs.os_bsize);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_blksize);
+
+int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
+                             int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_blocks;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               *eof = 1;
+               rc = snprintf(page, count, LPU64"\n", result);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_kbytestotal);
+
+int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
+                            int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_bfree;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               *eof = 1;
+               rc = snprintf(page, count, LPU64"\n", result);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_kbytesfree);
+
+int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
+                             int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_bavail;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               *eof = 1;
+               rc = snprintf(page, count, LPU64"\n", result);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_kbytesavail);
+
+int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
+                            int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               *eof = 1;
+               rc = snprintf(page, count, LPU64"\n", osfs.os_files);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_filestotal);
+
+int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
+                           int count, int *eof, void *data)
+{
+       struct dt_device *dt = data;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               *eof = 1;
+               rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_rd_filesfree);
+#endif
+
+int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0)
+               seq_printf(m, "%u\n", (unsigned) osfs.os_bsize);
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_blksize_seq_show);
+
+int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_blocks;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               seq_printf(m, LPU64"\n", result);
+       }
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_kbytestotal_seq_show);
+
+int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_bfree;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               seq_printf(m, LPU64"\n", result);
+       }
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_kbytesfree_seq_show);
+
+int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0) {
+               __u32 blk_size = osfs.os_bsize >> 10;
+               __u64 result = osfs.os_bavail;
+
+               while (blk_size >>= 1)
+                       result <<= 1;
+
+               seq_printf(m, LPU64"\n", result);
+       }
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_kbytesavail_seq_show);
+
+int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0)
+               seq_printf(m, LPU64"\n", osfs.os_files);
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_filestotal_seq_show);
+
+int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v)
+{
+       struct dt_device *dt = m->private;
+       struct obd_statfs osfs;
+
+       int rc = dt_statfs(NULL, dt, &osfs);
+       if (rc == 0)
+               seq_printf(m, LPU64"\n", osfs.os_ffree);
+       return rc;
+}
+EXPORT_SYMBOL(lprocfs_dt_filesfree_seq_show);
+
+#endif /* LPROCFS */