Whamcloud - gitweb
LU-6179 llite: Implement ladvise lockahead
[fs/lustre-release.git] / lustre / utils / lfs.c
index 44ce851..dc07fb9 100644 (file)
@@ -400,8 +400,9 @@ command_t cmdlist[] = {
        {"ladvise", lfs_ladvise, 0,
         "Provide servers with advice about access patterns for a file.\n"
         "usage: ladvise [--advice|-a ADVICE] [--start|-s START[kMGT]]\n"
-        "               [--background|-b]\n"
+        "               [--background|-b] [--unset|-u]\n\n"
         "               {[--end|-e END[kMGT]] | [--length|-l LENGTH[kMGT]]}\n"
+        "               {[--mode|-m [READ,WRITE]}\n"
         "               <file> ...\n"},
        {"help", Parser_help, 0, "help"},
        {"exit", Parser_quit, 0, "quit"},
@@ -5218,6 +5219,28 @@ static int lfs_swap_layouts(int argc, char **argv)
 
 static const char *const ladvise_names[] = LU_LADVISE_NAMES;
 
+static const char *const lock_mode_names[] = LOCK_MODE_NAMES;
+
+static const char *const lockahead_results[] = {
+       [LLA_RESULT_SENT] = "Lock request sent",
+       [LLA_RESULT_DIFFERENT] = "Different matching lock found",
+       [LLA_RESULT_SAME] = "Matching lock on identical extent found",
+};
+
+int lfs_get_mode(const char *string)
+{
+       enum lock_mode_user mode;
+
+       for (mode = 0; mode < ARRAY_SIZE(lock_mode_names); mode++) {
+               if (lock_mode_names[mode] == NULL)
+                       continue;
+               if (strcmp(string, lock_mode_names[mode]) == 0)
+                       return mode;
+       }
+
+       return -EINVAL;
+}
+
 static enum lu_ladvise_type lfs_get_ladvice(const char *string)
 {
        enum lu_ladvise_type advice;
@@ -5240,9 +5263,11 @@ static int lfs_ladvise(int argc, char **argv)
        { .val = 'b',   .name = "background",   .has_arg = no_argument },
        { .val = 'e',   .name = "end",          .has_arg = required_argument },
        { .val = 'l',   .name = "length",       .has_arg = required_argument },
+       { .val = 'm',   .name = "mode",         .has_arg = required_argument },
        { .val = 's',   .name = "start",        .has_arg = required_argument },
+       { .val = 'u',   .name = "unset",        .has_arg = no_argument },
        { .name = NULL } };
-       char                     short_opts[] = "a:be:l:s:";
+       char                     short_opts[] = "a:be:l:m:s:u";
        int                      c;
        int                      rc = 0;
        const char              *path;
@@ -5254,6 +5279,7 @@ static int lfs_ladvise(int argc, char **argv)
        unsigned long long       length = 0;
        unsigned long long       size_units;
        unsigned long long       flags = 0;
+       int                      mode = 0;
 
        optind = 0;
        while ((c = getopt_long(argc, argv, short_opts,
@@ -5282,6 +5308,9 @@ static int lfs_ladvise(int argc, char **argv)
                case 'b':
                        flags |= LF_ASYNC;
                        break;
+               case 'u':
+                       flags |= LF_UNSET;
+                       break;
                case 'e':
                        size_units = 1;
                        rc = llapi_parse_size(optarg, &end,
@@ -5312,6 +5341,15 @@ static int lfs_ladvise(int argc, char **argv)
                                return CMD_HELP;
                        }
                        break;
+               case 'm':
+                       mode = lfs_get_mode(optarg);
+                       if (mode < 0) {
+                               fprintf(stderr, "%s: bad mode '%s', valid "
+                                                "modes are READ or WRITE\n",
+                                       argv[0], optarg);
+                               return CMD_HELP;
+                       }
+                       break;
                case '?':
                        return CMD_HELP;
                default:
@@ -5334,6 +5372,13 @@ static int lfs_ladvise(int argc, char **argv)
                return CMD_HELP;
        }
 
+       if (advice_type == LU_LADVISE_LOCKNOEXPAND) {
+               fprintf(stderr, "%s: Lock no expand advice is a per file "
+                                "descriptor advice, so when called from lfs, "
+                                "it does nothing.\n", argv[0]);
+               return CMD_HELP;
+       }
+
        if (argc <= optind) {
                fprintf(stderr, "%s: please give one or more file names\n",
                        argv[0]);
@@ -5355,6 +5400,18 @@ static int lfs_ladvise(int argc, char **argv)
                return CMD_HELP;
        }
 
+       if (advice_type != LU_LADVISE_LOCKAHEAD && mode != 0) {
+               fprintf(stderr, "%s: mode is only valid with lockahead\n",
+                       argv[0]);
+               return CMD_HELP;
+       }
+
+       if (advice_type == LU_LADVISE_LOCKAHEAD && mode == 0) {
+               fprintf(stderr, "%s: mode is required with lockahead\n",
+                       argv[0]);
+               return CMD_HELP;
+       }
+
        while (optind < argc) {
                int rc2;
 
@@ -5375,6 +5432,11 @@ static int lfs_ladvise(int argc, char **argv)
                advice.lla_value2 = 0;
                advice.lla_value3 = 0;
                advice.lla_value4 = 0;
+               if (advice_type == LU_LADVISE_LOCKAHEAD) {
+                       advice.lla_lockahead_mode = mode;
+                       advice.lla_peradvice_flags = flags;
+               }
+
                rc2 = llapi_ladvise(fd, flags, 1, &advice);
                close(fd);
                if (rc2 < 0) {
@@ -5382,7 +5444,10 @@ static int lfs_ladvise(int argc, char **argv)
                                "'%s': %s\n", argv[0],
                                ladvise_names[advice_type],
                                path, strerror(errno));
+
+                       goto next;
                }
+
 next:
                if (rc == 0 && rc2 < 0)
                        rc = rc2;