Whamcloud - gitweb
LU-6245 libcfs: create userland and kernel string operations
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index e74cf70..4694491 100644 (file)
@@ -71,6 +71,7 @@
 #endif
 #include <poll.h>
 
+#include <libcfs/util/string.h>
 #include <libcfs/libcfs.h>
 #include <lnet/lnetctl.h>
 #include <lustre/lustreapi.h>
@@ -1616,17 +1617,13 @@ static DIR *opendir_parent(char *path)
 
 static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param)
 {
-       struct lmv_user_md *lmv = (struct lmv_user_md *)param->fp_lmv_md;
-       int ret = 0;
-
-       lmv->lum_stripe_count = param->fp_lmv_stripe_count;
+       param->fp_lmv_md->lum_stripe_count = param->fp_lmv_stripe_count;
        if (param->fp_get_default_lmv)
-               lmv->lum_magic = LMV_USER_MAGIC;
+               param->fp_lmv_md->lum_magic = LMV_USER_MAGIC;
        else
-               lmv->lum_magic = LMV_MAGIC_V1;
-       ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv);
+               param->fp_lmv_md->lum_magic = LMV_MAGIC_V1;
 
-       return ret;
+       return ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, param->fp_lmv_md);
 }
 
 static int get_lmd_info(char *path, DIR *parent, DIR *dir,
@@ -1641,12 +1638,18 @@ static int get_lmd_info(char *path, DIR *parent, DIR *dir,
         if (dir) {
                 ret = ioctl(dirfd(dir), LL_IOC_MDC_GETINFO, (void *)lmd);
         } else if (parent) {
-                char *fname = strrchr(path, '/');
+               char *fname = strrchr(path, '/');
 
-                fname = (fname == NULL ? path : fname + 1);
-                /* retrieve needed file info */
+               /* To avoid opening, locking, and closing each file on the
+                * client if that is not needed. The GETFILEINFO ioctl can
+                * be done on the patent dir with a single open for all
+                * files in that directory, and it also doesn't pollute the
+                * client dcache with millions of dentries when traversing
+                * a large filesystem.  */
+               fname = (fname == NULL ? path : fname + 1);
+               /* retrieve needed file info */
                strlcpy((char *)lmd, fname, lumlen);
-                ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd);
+               ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd);
         }
 
         if (ret) {
@@ -1878,7 +1881,7 @@ enum tgt_type {
 /*
  * If uuidp is NULL, return the number of available obd uuids.
  * If uuidp is non-NULL, then it will return the uuids of the obds. If
- * there are more OSTs then allocated to uuidp, then an error is returned with
+ * there are more OSTs than allocated to uuidp, then an error is returned with
  * the ost_count set to number of available obd uuids.
  */
 static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp,
@@ -2994,49 +2997,43 @@ static int cb_find_init(char *path, DIR *parent, DIR **dirp,
        if (decision == 0) {
                ret = get_lmd_info(path, parent, dir, param->fp_lmd,
                                   param->fp_lum_size);
-                if (ret == 0) {
-                        if (dir) {
+               if (ret == 0 && param->fp_mdt_uuid != NULL) {
+                       if (dir != NULL) {
                                ret = llapi_file_fget_mdtidx(dirfd(dir),
-                                               &param->fp_file_mdt_index);
-                        } else {
-                                int fd;
-                                lstat_t tmp_st;
-
-                                ret = lstat_f(path, &tmp_st);
-                                if (ret) {
-                                        ret = -errno;
-                                        llapi_error(LLAPI_MSG_ERROR, ret,
-                                                    "error: %s: lstat failed"
-                                                    "for %s", __func__, path);
-                                        return ret;
-                                }
-                                if (S_ISREG(tmp_st.st_mode)) {
-                                        fd = open(path, O_RDONLY);
-                                        if (fd > 0) {
-                                                ret = llapi_file_fget_mdtidx(fd,
                                                     &param->fp_file_mdt_index);
-                                                close(fd);
-                                        } else {
-                                                ret = fd;
-                                        }
-                                } else {
-                                        /* For special inode, it assumes to
-                                         * reside on the same MDT with the
-                                         * parent */
-                                        fd = dirfd(parent);
+                       } else if (S_ISREG(st->st_mode)) {
+                               int fd;
+
+                               /* FIXME: we could get the MDT index from the
+                                * file's FID in lmd->lmd_lmm.lmm_oi without
+                                * opening the file, once we are sure that
+                                * LFSCK2 (2.6) has fixed up pre-2.0 LOV EAs.
+                                * That would still be an ioctl() to map the
+                                * FID to the MDT, but not an open RPC. */
+                               fd = open(path, O_RDONLY);
+                               if (fd > 0) {
                                        ret = llapi_file_fget_mdtidx(fd,
                                                     &param->fp_file_mdt_index);
-                                }
-                        }
-                }
-                if (ret) {
-                        if (ret == -ENOTTY)
-                                lustre_fs = 0;
-                        if (ret == -ENOENT)
-                                goto decided;
-                        return ret;
-                }
-        }
+                                       close(fd);
+                               } else {
+                                       ret = -errno;
+                               }
+                       } else {
+                               /* For a special file, we assume it resides on
+                                * the same MDT as the parent directory. */
+                               ret = llapi_file_fget_mdtidx(dirfd(parent),
+                                                    &param->fp_file_mdt_index);
+                       }
+               }
+               if (ret != 0) {
+                       if (ret == -ENOTTY)
+                               lustre_fs = 0;
+                       if (ret == -ENOENT)
+                               goto decided;
+
+                       return ret;
+               }
+       }
 
        if (param->fp_type && !checked_type) {
                if ((st->st_mode & S_IFMT) == param->fp_type) {
@@ -3196,26 +3193,25 @@ obd_matches:
            param->fp_lmd->lmd_lmm.lmm_stripe_count)
                 decision = 0;
 
-        while (!decision) {
+       if (param->fp_check_size && S_ISDIR(st->st_mode))
+               decision = 0;
+
+       if (!decision) {
                 /* For regular files with the stripe the decision may have not
                  * been taken yet if *time or size is to be checked. */
-                LASSERT((S_ISREG(st->st_mode) &&
-                       param->fp_lmd->lmd_lmm.lmm_stripe_count) ||
-                       param->fp_mdt_index != OBD_NOT_FOUND);
-
                if (param->fp_obd_index != OBD_NOT_FOUND)
                         print_failed_tgt(param, path, LL_STATFS_LOV);
 
                if (param->fp_mdt_index != OBD_NOT_FOUND)
                         print_failed_tgt(param, path, LL_STATFS_LMV);
 
-               if (dir) {
-                       ret = ioctl(dirfd(dir), IOC_LOV_GETINFO,
-                                   (void *)param->fp_lmd);
-               } else if (parent) {
-                       ret = ioctl(dirfd(parent), IOC_LOV_GETINFO,
-                                   (void *)param->fp_lmd);
-               }
+               if (dir != NULL)
+                       ret = fstat_f(dirfd(dir), st);
+               else if (de != NULL)
+                       ret = fstatat_f(dirfd(parent), de->d_name, st,
+                                       AT_SYMLINK_NOFOLLOW);
+               else
+                       ret = lstat_f(path, st);
 
                 if (ret) {
                         if (errno == ENOENT) {
@@ -3236,8 +3232,6 @@ obd_matches:
                 decision = find_time_check(st, param, 0);
                 if (decision == -1)
                         goto decided;
-
-                break;
         }
 
        if (param->fp_check_size)
@@ -3362,64 +3356,58 @@ int llapi_file_fget_mdtidx(int fd, int *mdtidx)
 static int cb_get_mdt_index(char *path, DIR *parent, DIR **dirp, void *data,
                            struct dirent64 *de)
 {
-        struct find_param *param = (struct find_param *)data;
+       struct find_param *param = (struct find_param *)data;
        DIR *d = dirp == NULL ? NULL : *dirp;
-        int ret = 0;
-        int mdtidx;
+       int ret;
+       int mdtidx;
 
-        LASSERT(parent != NULL || d != NULL);
+       LASSERT(parent != NULL || d != NULL);
 
-        if (d) {
-                ret = llapi_file_fget_mdtidx(dirfd(d), &mdtidx);
-        } else if (parent) {
-                int fd;
+       if (d != NULL) {
+               ret = llapi_file_fget_mdtidx(dirfd(d), &mdtidx);
+       } else /* if (parent) */ {
+               int fd;
 
-                fd = open(path, O_RDONLY);
-                if (fd > 0) {
-                        ret = llapi_file_fget_mdtidx(fd, &mdtidx);
-                        close(fd);
-                } else {
-                        ret = -errno;
-                }
-        }
+               fd = open(path, O_RDONLY | O_NOCTTY);
+               if (fd > 0) {
+                       ret = llapi_file_fget_mdtidx(fd, &mdtidx);
+                       close(fd);
+               } else {
+                       ret = -errno;
+               }
+       }
 
-        if (ret) {
-                if (ret == -ENODATA) {
+       if (ret != 0) {
+               if (ret == -ENODATA) {
                        if (!param->fp_obd_uuid)
-                                llapi_printf(LLAPI_MSG_NORMAL,
-                                             "%s has no stripe info\n", path);
-                        goto out;
-                } else if (ret == -ENOENT) {
-                        llapi_error(LLAPI_MSG_WARN, ret,
-                                    "warning: %s: %s does not exist",
-                                    __func__, path);
-                        goto out;
-                } else if (ret == -ENOTTY) {
-                        llapi_error(LLAPI_MSG_ERROR, ret,
-                                    "%s: '%s' not on a Lustre fs?",
-                                    __func__, path);
-                } else {
-                        llapi_error(LLAPI_MSG_ERROR, ret,
-                                    "error: %s: LL_IOC_GET_MDTIDX failed for %s",
-                                    __func__, path);
-                }
-                return ret;
-        }
+                               llapi_printf(LLAPI_MSG_NORMAL,
+                                            "'%s' has no stripe info\n", path);
+                       goto out;
+               } else if (ret == -ENOENT) {
+                       llapi_error(LLAPI_MSG_WARN, ret,
+                                   "warning: %s: '%s' does not exist",
+                                   __func__, path);
+                       goto out;
+               } else if (ret == -ENOTTY) {
+                       llapi_error(LLAPI_MSG_ERROR, ret,
+                                   "%s: '%s' not on a Lustre fs",
+                                   __func__, path);
+               } else {
+                       llapi_error(LLAPI_MSG_ERROR, ret,
+                                   "error: %s: '%s' failed get_mdtidx",
+                                   __func__, path);
+               }
+               return ret;
+       }
 
-       /* The 'LASSERT(parent != NULL || d != NULL);' guarantees
-        * that either 'd' or 'parent' is not null.
-        * So in all cases llapi_file_fget_mdtidx() is called,
-        * thus initializing 'mdtidx'. */
        if (param->fp_quiet || !(param->fp_verbose & VERBOSE_DETAIL))
-               /* coverity[uninit_use_in_call] */
-                llapi_printf(LLAPI_MSG_NORMAL, "%d\n", mdtidx);
-        else
-               /* coverity[uninit_use_in_call] */
-                llapi_printf(LLAPI_MSG_NORMAL, "%s\nmdt_index:\t%d\n",
-                             path, mdtidx);
+               llapi_printf(LLAPI_MSG_NORMAL, "%d\n", mdtidx);
+       else
+               llapi_printf(LLAPI_MSG_NORMAL, "%s\nmdt_index:\t%d\n",
+                            path, mdtidx);
 
 out:
-       /* Do not get down anymore? */
+       /* Do not go down anymore? */
        if (param->fp_depth == param->fp_max_depth)
                return 1;