Whamcloud - gitweb
LU-16977 utils: access_log_reader accesses beyond batch array
[fs/lustre-release.git] / lustre / utils / liblustreapi_pcc.c
index 8d23bf4..47192e5 100644 (file)
  * Fetch and attach a file to readwrite PCC.
  *
  */
-static int llapi_readwrite_pcc_attach(const char *path, __u32 archive_id)
+static int llapi_readwrite_pcc_attach_fd(int fd, __u32 archive_id)
 {
-       int fd;
        int rc;
        struct ll_ioc_lease *data;
 
-       fd = open(path, O_RDWR | O_NONBLOCK);
-       if (fd < 0) {
-               rc = -errno;
-               llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'",
-                           path);
-               return rc;
-       }
-
        rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
        if (rc < 0) {
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "cannot get lease for '%s'", path);
-               goto out_close;
+               llapi_error(LLAPI_MSG_ERROR, rc, "cannot get lease");
+               return rc;
        }
 
        data = malloc(offsetof(typeof(*data), lil_ids[1]));
@@ -71,7 +61,7 @@ static int llapi_readwrite_pcc_attach(const char *path, __u32 archive_id)
                rc = -ENOMEM;
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "failed to allocate memory");
-               goto out_close;
+               return rc;
        }
 
        data->lil_mode = LL_LEASE_UNLCK;
@@ -83,14 +73,30 @@ static int llapi_readwrite_pcc_attach(const char *path, __u32 archive_id)
                if (rc == 0) /* lost lease lock */
                        rc = -EBUSY;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "cannot attach '%s' with ID: %u",
-                            path, archive_id);
+                           "cannot attach with ID: %u", archive_id);
        } else {
                rc = 0;
        }
 
        free(data);
-out_close:
+       return rc;
+}
+
+static int llapi_readwrite_pcc_attach(const char *path, __u32 archive_id)
+{
+       int fd;
+       int rc;
+
+       fd = open(path, O_RDWR | O_NONBLOCK);
+       if (fd < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'",
+                           path);
+               return rc;
+       }
+
+       rc = llapi_readwrite_pcc_attach_fd(fd, archive_id);
+
        close(fd);
        return rc;
 }
@@ -99,7 +105,7 @@ int llapi_pcc_attach(const char *path, __u32 id, enum lu_pcc_type type)
 {
        int rc;
 
-       switch (type) {
+       switch (type & LU_PCC_TYPE_MASK) {
        case LU_PCC_READWRITE:
                rc = llapi_readwrite_pcc_attach(path, id);
                break;
@@ -110,74 +116,140 @@ int llapi_pcc_attach(const char *path, __u32 id, enum lu_pcc_type type)
        return rc;
 }
 
+static int llapi_readwrite_pcc_attach_fid(const char *mntpath,
+                                         const struct lu_fid *fid,
+                                         __u32 id)
+{
+       int rc;
+       int fd;
+
+       fd = llapi_open_by_fid(mntpath, fid, O_RDWR | O_NONBLOCK);
+       if (fd < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "llapi_open_by_fid for " DFID "failed",
+                           PFID(fid));
+               return rc;
+       }
+
+       rc = llapi_readwrite_pcc_attach_fd(fd, id);
+
+       close(fd);
+       return rc;
+}
+
+int llapi_pcc_attach_fid(const char *mntpath, const struct lu_fid *fid,
+                        __u32 id, enum lu_pcc_type type)
+{
+       int rc;
+
+       switch (type & LU_PCC_TYPE_MASK) {
+       case LU_PCC_READWRITE:
+               rc = llapi_readwrite_pcc_attach_fid(mntpath, fid, id);
+               break;
+       default:
+               rc = -EINVAL;
+               break;
+       }
+       return rc;
+}
+
+
+int llapi_pcc_attach_fid_str(const char *mntpath, const char *fidstr,
+                            __u32 id, enum lu_pcc_type type)
+{
+       int rc;
+       struct lu_fid fid;
+       const char *fidstr_orig = fidstr;
+
+       while (*fidstr == '[')
+               fidstr++;
+       rc = sscanf(fidstr, SFID, RFID(&fid));
+       if (rc != 3) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "bad FID format '%s', should be [seq:oid:ver]"
+                                 " (e.g. "DFID")\n", fidstr_orig,
+                                 (unsigned long long)FID_SEQ_NORMAL, 2, 0);
+               return -EINVAL;
+       }
+
+       rc = llapi_pcc_attach_fid(mntpath, &fid, id, type);
+
+       return rc;
+}
 
 /**
- * detach PCC cache of a file by an ioctl on the dir fd (usually a mount
- * point fd that the copytool already has open).
+ * detach PCC cache of a file by using fd.
  *
- * If the file is being used, the detaching will return -EBUSY immediately.
- * Thus, if a PCC-attached file is kept open for a long time, the restore
- * request will always return failure.
- *
- * \param fd           Directory file descriptor.
- * \param fid          FID of the file.
+ * \param fd           File handle.
+ * \param option       Detach option
  *
  * \return 0 on success, an error code otherwise.
  */
-int llapi_pcc_detach_fid_fd(int fd, const struct lu_fid *fid)
+int llapi_pcc_detach_fd(int fd, __u32 option)
 {
-       int rc;
        struct lu_pcc_detach detach;
+       int rc;
 
-       detach.pccd_fid = *fid;
+       detach.pccd_opt = option;
        rc = ioctl(fd, LL_IOC_PCC_DETACH, &detach);
-       if (rc == -EAGAIN)
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "FID "DFID" may be in the attaching state, "
-                           "or you may need to re-run the pcc_attach "
-                           "to finish the attach process.", PFID(fid));
-       else if (rc)
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "cannot detach FID "DFID" from PCC", PFID(fid));
+       /* If error, save errno value */
+       rc = rc ? -errno : 0;
 
        return rc;
 }
 
 /**
- * detach PCC cache of a file.
+ * detach PCC cache of a file via FID.
  *
  * \param mntpath      Fullpath to the client mount point.
  * \param fid          FID of the file.
+ * \param option       Detach option.
  *
  * \return 0 on success, an error code otherwise.
  */
-int llapi_pcc_detach_fid(const char *mntpath, const struct lu_fid *fid)
+int llapi_pcc_detach_fid(const char *mntpath, const struct lu_fid *fid,
+                        __u32 option)
 {
        int rc;
        int fd;
+       struct lu_pcc_detach_fid detach;
 
-       rc = get_root_path(WANT_FD, NULL, &fd, (char *)mntpath, -1);
+       rc = llapi_root_path_open(mntpath, &fd);
        if (rc) {
                llapi_error(LLAPI_MSG_ERROR, rc, "cannot get root path: %s",
                            mntpath);
                return rc;
        }
 
-       rc = llapi_pcc_detach_fid_fd(fd, fid);
+       /*
+        * PCC prefetching algorithm scans Lustre OPEN/CLOSE changelogs
+        * to determine the candidate files needing to prefetch into
+        * PCC. To avoid generattion of unnecessary open/close changelogs,
+        * we implement a new dir ioctl LL_IOC_PCC_DETACH_BY_FID to detach
+        * files.
+        */
+       detach.pccd_fid = *fid;
+       detach.pccd_opt = option;
+
+       rc = ioctl(fd, LL_IOC_PCC_DETACH_BY_FID, &detach);
+       rc = rc ? -errno : 0;
 
        close(fd);
        return rc;
 }
 
 /**
- * detach PCC cache of a file.
+ * detach PCC cache of a file via FID.
  *
  * \param mntpath      Fullpath to the client mount point.
- * \param fid          FID string of the file.
+ * \param fidstr       FID string of the file.
+ * \param option       Detach option.
  *
  * \return 0 on success, an error code otherwise.
  */
-int llapi_pcc_detach_fid_str(const char *mntpath, const char *fidstr)
+int llapi_pcc_detach_fid_str(const char *mntpath, const char *fidstr,
+                            __u32 option)
 {
        int rc;
        struct lu_fid fid;
@@ -194,7 +266,7 @@ int llapi_pcc_detach_fid_str(const char *mntpath, const char *fidstr)
                return -EINVAL;
        }
 
-       rc = llapi_pcc_detach_fid(mntpath, &fid);
+       rc = llapi_pcc_detach_fid(mntpath, &fid, option);
 
        return rc;
 }
@@ -202,23 +274,26 @@ int llapi_pcc_detach_fid_str(const char *mntpath, const char *fidstr)
 /**
  * detach PCC cache of a file.
  *
- * \param path   Fullpath to the file to operate on.
+ * \param path         Fullpath to the file to operate on.
+ * \param option       Detach option.
  *
  * \return 0 on success, an error code otherwise.
  */
-int llapi_pcc_detach_file(const char *path)
+int llapi_pcc_detach_file(const char *path, __u32 option)
 {
        int rc;
-       lustre_fid fid;
+       int fd;
 
-       rc = llapi_path2fid(path, &fid);
-       if (rc) {
-               llapi_error(LLAPI_MSG_ERROR, rc, "cannot get FID of '%s'",
+       fd = open(path, O_RDWR | O_NONBLOCK);
+       if (fd < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'",
                            path);
                return rc;
        }
 
-       rc = llapi_pcc_detach_fid(path, &fid);
+       rc = llapi_pcc_detach_fd(fd, option);
+       close(fd);
        return rc;
 }
 
@@ -275,7 +350,7 @@ int llapi_pccdev_set(const char *mntpath, const char *cmd)
        rc = llapi_getname(mntpath, buf, sizeof(buf));
        if (rc < 0) {
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "cannot get name for '%s'\n", mntpath);
+                           "cannot get name for '%s'", mntpath);
                return rc;
        }
 
@@ -296,12 +371,12 @@ int llapi_pccdev_set(const char *mntpath, const char *cmd)
                rc = errno;
                if (errno != EIO)
                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                   "error: setting llite.%s.pcc=\"%s\"\n",
+                                   "error: setting llite.%s.pcc='%s'",
                                    buf, cmd);
        } else if (count < strlen(cmd)) { /* Truncate case */
                rc = -EINVAL;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "setting llite.%s.pcc=\"%s\": wrote only %zd\n",
+                           "setting llite.%s.pcc='%s': wrote only %zd",
                            buf, cmd, count);
        }
        close(fd);
@@ -325,7 +400,7 @@ int llapi_pccdev_get(const char *mntpath)
        rc = llapi_getname(mntpath, pathbuf, sizeof(pathbuf));
        if (rc < 0) {
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "cannot get name for '%s'\n", mntpath);
+                           "cannot get name for '%s'", mntpath);
                return rc;
        }
 
@@ -338,7 +413,7 @@ int llapi_pccdev_get(const char *mntpath)
        if (fd < 0) {
                rc = -errno;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: pccdev_get: opening '%s'\n",
+                           "error: pccdev_get: opening '%s'",
                            path.gl_pathv[0]);
                goto out_free_param;
        }
@@ -347,7 +422,7 @@ int llapi_pccdev_get(const char *mntpath)
        if (buf == NULL) {
                rc = -ENOMEM;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: pccdev_get: allocating '%s' buffer\n",
+                           "error: pccdev_get: allocating '%s' buffer",
                            path.gl_pathv[0]);
                goto out_close;
        }
@@ -361,8 +436,7 @@ int llapi_pccdev_get(const char *mntpath)
                        rc = -errno;
                        if (errno != EIO) {
                                llapi_error(LLAPI_MSG_ERROR, rc,
-                                           "error: pccdev_get: "
-                                           "reading failed\n");
+                                          "error: pccdev_get: reading failed");
                        }
                        break;
                }
@@ -370,7 +444,7 @@ int llapi_pccdev_get(const char *mntpath)
                if (fwrite(buf, 1, count, stdout) != count) {
                        rc = -errno;
                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                   "error: get_param: write to stdout\n");
+                                   "error: get_param: write to stdout");
                        break;
                }
        }