Print this page
PSARC 2007/569 lofi(7D) compression support
6618343 lofi compression support

@@ -89,10 +89,14 @@
  *
  *      li.li_minor = 0;
  *      ioctl(ld, LOFI_GET_MAXMINOR, &li);
  *      maxminor = li.li_minor;
  *
+ *      strcpy(li.li_filename, "somefilename");
+ *      li.li_minor = 0;
+ *      ioctl(ld, LOFI_CHECK_COMPRESSED, &li);
+ *
  * If the 'li_force' flag is set for any of the LOFI_UNMAP_* commands, then if
  * the device is busy, the underlying vnode will be closed, and any subsequent
  * operations will fail.  It will behave as if the device had been forcibly
  * removed, so the DKIOCSTATE ioctl will return DKIO_DEV_GONE.  When the device
  * is last closed, it will be torn down.

@@ -103,11 +107,12 @@
  */
 
 struct lofi_ioctl {
         uint32_t        li_minor;
         boolean_t       li_force;
-        char    li_filename[MAXPATHLEN + 1];
+        char    li_filename[MAXPATHLEN];
+        char    li_algorithm[MAXPATHLEN];
 };
 
 #define LOFI_IOC_BASE           (('L' << 16) | ('F' << 8))
 
 #define LOFI_MAP_FILE           (LOFI_IOC_BASE | 0x01)

@@ -115,18 +120,23 @@
 #define LOFI_UNMAP_FILE         (LOFI_IOC_BASE | 0x03)
 #define LOFI_UNMAP_FILE_MINOR   (LOFI_IOC_BASE | 0x04)
 #define LOFI_GET_FILENAME       (LOFI_IOC_BASE | 0x05)
 #define LOFI_GET_MINOR          (LOFI_IOC_BASE | 0x06)
 #define LOFI_GET_MAXMINOR       (LOFI_IOC_BASE | 0x07)
+#define LOFI_CHECK_COMPRESSED   (LOFI_IOC_BASE | 0x08)
 
 /*
  * file types that might be usable with lofi, maybe. Only regular
  * files are documented though.
  */
 #define S_ISLOFIABLE(mode) \
         (S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode))
 
+#define SEGHDR          1
+#define COMPRESSED      1
+#define UNCOMPRESSED    0
+
 #if defined(_KERNEL)
 
 /*
  * We limit the maximum number of active lofi devices to 128, which seems very
  * large. You can tune this by changing lofi_max_files in /etc/system.

@@ -156,14 +166,86 @@
         kstat_t         *ls_kstat;
         kmutex_t        ls_kstat_lock;
         struct dk_geom  ls_dkg;
         struct vtoc     ls_vtoc;
         struct dk_cinfo ls_ci;
+
+        /* the following fields are required for compression support */
+
+        /*
+         * index into lofi_compress_table for the compression algorithm
+         * used
+         */
+        int             ls_comp_algorithm_index;
+        uint32_t        ls_comp_algorithm_len;
+        /* size of an uncompressed segment */
+        uint32_t        ls_uncomp_seg_sz;
+        /* number of index entries */
+        uint32_t        ls_comp_index_sz;
+        /* exponent for byte shift, power of 2 */
+        uint32_t        ls_comp_seg_shift;
+        /*
+         * size of the last uncompressed segment (the file may
+         * not be an exact multiple of the segment size ls_uncomp_seg_sz)
+         */
+        uint32_t        ls_uncomp_last_seg_sz;
+        /*
+         * the offset in the file where the header ends and the
+         * actual compressed data begins. The segment offsets in
+         * the index do not account for the header so this value must
+         * be added
+         */
+        uint64_t        ls_comp_offbase;
+        /*
+         * the array holding the segment index. This is a pointer
+         * into ls_comp_index_data
+         */
+        uint64_t        *ls_comp_seg_index;
+        /*
+         * holds the index pages loaded from the file. This is aligned
+         * on a disk block boundary so lsecomp_seg_index above is used
+         * to point to the actual array
+         */
+        caddr_t         ls_comp_index_data;
+        /* size of ls_comp_index_data */
+        uint32_t        ls_comp_index_data_sz;
+        /*
+         * incase of compressed files, ls_vp_size above is
+         * tweaked to represent the actual uncompressed file
+         * size so that fake_disk_geometry gives the correct
+         * values. However we need the actual compressed file
+         * size while faulting in pages from the compressed
+         * file in lofi_mapped_rdwr
+         */
+        u_offset_t      ls_vp_comp_size;
 };
 
-#endif
+#endif  /* _KERNEL */
 
+/*
+ * Common signature for all lofi compress functions
+ */
+typedef int lofi_compress_func_t(void *src, size_t srclen, void *dst,
+        size_t *destlen, int level);
+
+/*
+ * Information about each compression function
+ */
+typedef struct lofi_compress_info {
+        lofi_compress_func_t    *l_decompress;
+        lofi_compress_func_t    *l_compress;
+        int                     l_level;
+        char                    *l_name;        /* algorithm name */
+} lofi_compress_info_t;
+
+enum lofi_compress {
+        LOFI_COMPRESS_GZIP = 0,
+        LOFI_COMPRESS_GZIP_6 = 1,
+        LOFI_COMPRESS_GZIP_9 = 2,
+        LOFI_COMPRESS_FUNCTIONS
+};
+
 #ifdef  __cplusplus
 }
 #endif
 
 #endif  /* _SYS_LOFI_H */