Whamcloud - gitweb
LU-1301 mgs: OSD based class_dentry_readdir()
authorAlex Zhuravlev <bzzz@whamcloud.com>
Tue, 14 Aug 2012 20:34:04 +0000 (00:34 +0400)
committerOleg Drokin <green@whamcloud.com>
Mon, 24 Sep 2012 19:46:09 +0000 (15:46 -0400)
class_dentry_readdir() now uses OSD API to list the logs.

Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Change-Id: I376fb8d53ffb6d0aaee27ed981a8243def4d85df
Reviewed-on: http://review.whamcloud.com/3677
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mike Pershin <tappro@whamcloud.com>
lustre/mgs/lproc_mgs.c
lustre/mgs/mgs_internal.h
lustre/mgs/mgs_llog.c

index fef6baa..691ad12 100644 (file)
@@ -67,8 +67,8 @@ static int mgs_fs_seq_show(struct seq_file *seq, void *v)
 {
         struct obd_device *obd = seq->private;
        struct mgs_device *mgs;
 {
         struct obd_device *obd = seq->private;
        struct mgs_device *mgs;
-        cfs_list_t dentry_list;
-        struct l_linux_dirent *dirent, *n;
+       cfs_list_t list;
+       struct mgs_direntry *dirent, *n;
        struct lu_env env;
         int rc, len;
         ENTRY;
        struct lu_env env;
         int rc, len;
         ENTRY;
@@ -81,19 +81,18 @@ static int mgs_fs_seq_show(struct seq_file *seq, void *v)
        if (rc)
                RETURN(rc);
 
        if (rc)
                RETURN(rc);
 
-       rc = class_dentry_readdir(&env, mgs, &dentry_list);
+       rc = class_dentry_readdir(&env, mgs, &list);
         if (rc) {
                 CERROR("Can't read config dir\n");
                GOTO(out, rc);
         }
         if (rc) {
                 CERROR("Can't read config dir\n");
                GOTO(out, rc);
         }
-        cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
-                cfs_list_del(&dirent->lld_list);
-                len = strlen(dirent->lld_name);
-                if ((len > 7) && (strncmp(dirent->lld_name + len - 7, "-client",
-                                          len) == 0)) {
-                        seq_printf(seq, "%.*s\n", len - 7, dirent->lld_name);
-                }
-                OBD_FREE(dirent, sizeof(*dirent));
+       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
+               cfs_list_del(&dirent->list);
+               len = strlen(dirent->name);
+               if (len > 7 &&
+                   strncmp(dirent->name + len - 7, "-client", len) == 0)
+                       seq_printf(seq, "%.*s\n", len - 7, dirent->name);
+               mgs_direntry_free(dirent);
         }
 
 out:
         }
 
 out:
index 84fe7d2..099f62c 100644 (file)
@@ -364,5 +364,38 @@ static inline struct dt_object *dt_object_child(struct dt_object *o)
        return container_of0(lu_object_next(&(o)->do_lu),
                             struct dt_object, do_lu);
 }
        return container_of0(lu_object_next(&(o)->do_lu),
                             struct dt_object, do_lu);
 }
+struct mgs_direntry {
+       cfs_list_t  list;
+       char       *name;
+       int         len;
+};
+
+static inline void mgs_direntry_free(struct mgs_direntry *de)
+{
+       if (de) {
+               LASSERT(de->len);
+               OBD_FREE(de->name, de->len);
+               OBD_FREE_PTR(de);
+       }
+}
+
+static inline struct mgs_direntry *mgs_direntry_alloc(int len)
+{
+       struct mgs_direntry *de;
+
+       OBD_ALLOC_PTR(de);
+       if (de == NULL)
+               return NULL;
+
+       OBD_ALLOC(de->name, len);
+       if (de->name == NULL) {
+               OBD_FREE_PTR(de);
+               return NULL;
+       }
+
+       de->len = len;
+
+       return de;
+}
 
 #endif /* _MGS_INTERNAL_H */
 
 #endif /* _MGS_INTERNAL_H */
index 79ee0e8..969547b 100644 (file)
@@ -38,6 +38,8 @@
  * Lustre Management Server (mgs) config llog creation
  *
  * Author: Nathan Rutman <nathan@clusterfs.com>
  * Lustre Management Server (mgs) config llog creation
  *
  * Author: Nathan Rutman <nathan@clusterfs.com>
+ * Author: Alex Zhuravlev <bzzz@whamcloud.com>
+ * Author: Mikhail Pershin <tappro@whamcloud.com>
  */
 
 #define DEBUG_SUBSYSTEM S_MGS
  */
 
 #define DEBUG_SUBSYSTEM S_MGS
 
 /********************** Class functions ********************/
 
 
 /********************** Class functions ********************/
 
-/* Caller must list_del and OBD_FREE each dentry from the list */
+/* Caller must list_del and mgs_dirent_free() each dentry from the list */
 int class_dentry_readdir(const struct lu_env *env,
 int class_dentry_readdir(const struct lu_env *env,
-                        struct mgs_device *mgs, cfs_list_t *dentry_list)
-{
-        /* see mds_cleanup_pending */
-        struct lvfs_run_ctxt saved;
-        struct file *file;
-        struct dentry *dentry;
-        struct vfsmount *mnt;
-        int rc = 0;
-        ENTRY;
+                        struct mgs_device *mgs, cfs_list_t *list)
+{
+       struct dt_object    *dir = mgs->mgs_configs_dir;
+       const struct dt_it_ops *iops;
+       struct dt_it        *it;
+       struct mgs_direntry *de;
+       char                *key;
+       int                  rc, key_sz;
+
+       CFS_INIT_LIST_HEAD(list);
+
+       if (!dt_try_as_dir(env, dir))
+               GOTO(out, rc = -ENOTDIR);
+
+       LASSERT(dir);
+       LASSERT(dir->do_index_ops);
+
+       iops = &dir->do_index_ops->dio_it;
+       it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
+       if (IS_ERR(it))
+               RETURN(PTR_ERR(it));
+
+       rc = iops->load(env, it, 0);
+       if (rc <= 0)
+               GOTO(fini, rc = 0);
+
+       /* main cycle */
+       do {
+               key = (void *)iops->key(env, it);
+               if (IS_ERR(key)) {
+                       CERROR("%s: key failed when listing %s: rc = %d\n",
+                              mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
+                              (int) PTR_ERR(key));
+                       goto next;
+               }
+               key_sz = iops->key_size(env, it);
+               LASSERT(key_sz > 0);
+
+               /* filter out "." and ".." entries */
+               if (key[0] == '.') {
+                       if (key_sz == 1)
+                               goto next;
+                       if (key_sz == 2 && key[1] == '.')
+                               goto next;
+               }
 
 
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       dentry = dget(mgs->mgs_configs_dir_old);
-        if (IS_ERR(dentry))
-                GOTO(out_pop, rc = PTR_ERR(dentry));
-       mnt = mntget(mgs->mgs_vfsmnt);
-        if (IS_ERR(mnt)) {
-                l_dput(dentry);
-                GOTO(out_pop, rc = PTR_ERR(mnt));
-        }
+               de = mgs_direntry_alloc(key_sz + 1);
+               if (de == NULL) {
+                       rc = -ENOMEM;
+                       break;
+               }
 
 
-        file = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred());
-        if (IS_ERR(file))
-                /* dentry_open_it() drops the dentry, mnt refs */
-                GOTO(out_pop, rc = PTR_ERR(file));
+               memcpy(de->name, key, key_sz);
+               de->name[key_sz] = 0;
 
 
-        CFS_INIT_LIST_HEAD(dentry_list);
-        rc = l_readdir(file, dentry_list);
-        filp_close(file, 0);
-        /*  filp_close->fput() drops the dentry, mnt refs */
+               cfs_list_add(&de->list, list);
 
 
-out_pop:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-        RETURN(rc);
+next:
+               rc = iops->next(env, it);
+       } while (rc == 0);
+       rc = 0;
+
+       iops->put(env, it);
+
+fini:
+       iops->fini(env, it);
+out:
+       if (rc)
+               CERROR("%s: key failed when listing %s: rc = %d\n",
+                      mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
+       RETURN(rc);
 }
 
 /******************** DB functions *********************/
 }
 
 /******************** DB functions *********************/
@@ -995,8 +1035,8 @@ int mgs_write_log_direct_all(const struct lu_env *env,
                             char *devname, char *comment,
                             int server_only)
 {
                             char *devname, char *comment,
                             int server_only)
 {
-        cfs_list_t dentry_list;
-        struct l_linux_dirent *dirent, *n;
+       cfs_list_t list;
+       struct mgs_direntry *dirent, *n;
         char *fsname = mti->mti_fsname;
         char *logname;
         int rc = 0, len = strlen(fsname);
         char *fsname = mti->mti_fsname;
         char *logname;
         int rc = 0, len = strlen(fsname);
@@ -1019,41 +1059,43 @@ int mgs_write_log_direct_all(const struct lu_env *env,
                 RETURN(rc);
 
         /* Find all the logs in the CONFIGS directory */
                 RETURN(rc);
 
         /* Find all the logs in the CONFIGS directory */
-       rc = class_dentry_readdir(env, mgs, &dentry_list);
-        if (rc) {
-                CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
+       rc = class_dentry_readdir(env, mgs, &list);
+       if (rc)
                 RETURN(rc);
                 RETURN(rc);
-        }
 
         /* Could use fsdb index maps instead of directory listing */
 
         /* Could use fsdb index maps instead of directory listing */
-        cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
-                cfs_list_del(&dirent->lld_list);
+       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
+               cfs_list_del(&dirent->list);
                 /* don't write to sptlrpc rule log */
                 /* don't write to sptlrpc rule log */
-               if (strstr(dirent->lld_name, "-sptlrpc") != NULL)
+               if (strstr(dirent->name, "-sptlrpc") != NULL)
                        goto next;
 
                /* caller wants write server logs only */
                        goto next;
 
                /* caller wants write server logs only */
-               if (server_only && strstr(dirent->lld_name, "-client") != NULL)
+               if (server_only && strstr(dirent->name, "-client") != NULL)
                        goto next;
 
                        goto next;
 
-               if (strncmp(fsname, dirent->lld_name, len) == 0) {
-                        CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
+               if (strncmp(fsname, dirent->name, len) == 0) {
+                       CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
                         /* Erase any old settings of this same parameter */
                         /* Erase any old settings of this same parameter */
-                       mgs_modify(env, mgs, fsdb, mti, dirent->lld_name,
-                                  devname, comment, CM_SKIP);
+                       rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
+                                       devname, comment, CM_SKIP);
+                       if (rc < 0)
+                               CERROR("%s: Can't modify llog %s: rc = %d\n",
+                                      mgs->mgs_obd->obd_name, dirent->name,rc);
                         /* Write the new one */
                         if (lcfg) {
                                rc = mgs_write_log_direct(env, mgs, fsdb,
                         /* Write the new one */
                         if (lcfg) {
                                rc = mgs_write_log_direct(env, mgs, fsdb,
-                                                          dirent->lld_name,
-                                                          lcfg, devname,
-                                                          comment);
+                                                         dirent->name,
+                                                         lcfg, devname,
+                                                         comment);
                                 if (rc)
                                 if (rc)
-                                        CERROR("err %d writing log %s\n", rc,
-                                               dirent->lld_name);
+                                       CERROR("%s: writing log %s: rc = %d\n",
+                                              mgs->mgs_obd->obd_name,
+                                              dirent->name, rc);
                         }
                 }
 next:
                         }
                 }
 next:
-                OBD_FREE(dirent, sizeof(*dirent));
+               mgs_direntry_free(dirent);
         }
 
         RETURN(rc);
         }
 
         RETURN(rc);
@@ -3087,19 +3129,17 @@ int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
 /* erase all logs for the given fs */
 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
 {
 /* erase all logs for the given fs */
 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
 {
-        struct fs_db *fsdb;
-        cfs_list_t dentry_list;
-        struct l_linux_dirent *dirent, *n;
-        int rc, len = strlen(fsname);
-        char *suffix;
-        ENTRY;
+       struct fs_db *fsdb;
+       cfs_list_t list;
+       struct mgs_direntry *dirent, *n;
+       int rc, len = strlen(fsname);
+       char *suffix;
+       ENTRY;
 
 
-        /* Find all the logs in the CONFIGS directory */
-       rc = class_dentry_readdir(env, mgs, &dentry_list);
-        if (rc) {
-                CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
-                RETURN(rc);
-        }
+       /* Find all the logs in the CONFIGS directory */
+       rc = class_dentry_readdir(env, mgs, &list);
+       if (rc)
+               RETURN(rc);
 
         cfs_mutex_lock(&mgs->mgs_mutex);
 
 
         cfs_mutex_lock(&mgs->mgs_mutex);
 
@@ -3108,22 +3148,22 @@ int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsnam
         if (fsdb)
                mgs_free_fsdb(mgs, fsdb);
 
         if (fsdb)
                mgs_free_fsdb(mgs, fsdb);
 
-        cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
-                cfs_list_del(&dirent->lld_list);
-                suffix = strrchr(dirent->lld_name, '-');
-                if (suffix != NULL) {
-                        if ((len == suffix - dirent->lld_name) &&
-                            (strncmp(fsname, dirent->lld_name, len) == 0)) {
-                                CDEBUG(D_MGS, "Removing log %s\n",
-                                       dirent->lld_name);
-                               mgs_erase_log(env, mgs, dirent->lld_name);
-                        }
-                }
-                OBD_FREE(dirent, sizeof(*dirent));
-        }
-
         cfs_mutex_unlock(&mgs->mgs_mutex);
 
         cfs_mutex_unlock(&mgs->mgs_mutex);
 
+       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
+               cfs_list_del(&dirent->list);
+               suffix = strrchr(dirent->name, '-');
+               if (suffix != NULL) {
+                       if ((len == suffix - dirent->name) &&
+                           (strncmp(fsname, dirent->name, len) == 0)) {
+                               CDEBUG(D_MGS, "Removing log %s\n",
+                                      dirent->name);
+                               mgs_erase_log(env, mgs, dirent->name);
+                       }
+               }
+               mgs_direntry_free(dirent);
+       }
+
         RETURN(rc);
 }
 
         RETURN(rc);
 }