Whamcloud - gitweb
LU-3363 api: HSM import uses new released pattern 36/6536/14
authorjcl <jacques-charles.lafoucriere@cea.fr>
Wed, 20 Feb 2013 10:18:23 +0000 (11:18 +0100)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 31 Jul 2013 19:49:36 +0000 (19:49 +0000)
Import creates a released file using new RAID pattern flag
Import used a new ioctl() to implement the import in the
client kernel.
Add a -L|--layout option to lfs getstripe and lfs find

Signed-off-by: JC Lafoucriere <jacques-charles.lafoucriere@cea.fr>
Change-Id: I39103e6f90bd73dc09cde49086d223d717e41cd2
Reviewed-on: http://review.whamcloud.com/6536
Tested-by: Hudson
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
15 files changed:
lustre/doc/lfs.1
lustre/doc/llapi_hsm_state_get.3
lustre/doc/llapi_hsm_state_set.3
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanity.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_hsm.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 7db5642..8a976e6 100644 (file)
@@ -23,6 +23,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
         \fB[[!] --stripe-count|-c [+-]<stripes>]
         \fB[[!] --stripe-index|-i <index,...>]
         \fB[[!] --stripe-size|-S [+-]N[kMG]]
+        \fB[[!] --layout|-L raid0,released]
         \fB[--type |-t {bcdflpsD}] [[!] --gid|-g|--group|-G <gname>|<gid>]
         \fB[[!] --uid|-u|--user|-U <uname>|<uid>] [[!] --pool <pool>]\fR
 .br
@@ -31,6 +32,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
 .B lfs getstripe [--obd|-O <uuid>] [--quiet|-q] [--verbose|-v] 
         \fB[--stripe-count|-c ] [--stripe-index|-i] [--mdt-index|-M]
         \fB[--stripe-size|-S] [--directory|-d]
+       \fB[--layout|-L]
         \fB[--pool|-p] [--recursive|-r] [--raw|-R] <dirname|filename> ...\fR
 .br
 .B lfs setstripe [--stripe-size|-S stripe_size] [--stripe-count|-c stripe_count]
@@ -110,7 +112,7 @@ output is printed in \fIh\fRuman readable format, using SI base-2 suffixes
 for \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes.
 .TP
 .B find 
-To search the directory tree rooted at the given dir/file name for the files that match the given parameters: \fB--atime\fR (file was last accessed N*24 hours ago), \fB--ctime\fR (file's status was last changed N*24 hours ago), \fB--mtime\fR (file's data was last modified N*24 hours ago), \fB--obd\fR (file has an object on a specific OST or OSTs), \fB--size\fR (file has size in bytes, or \fBk\fRilo-, \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes if a suffix is given), \fB--type\fR (file has the type: \fBb\fRlock, \fBc\fRharacter, \fBd\fRirectory, \fBp\fRipe, \fBf\fRile, sym\fBl\fRink, \fBs\fRocket, or \fBD\fRoor (Solaris)), \fB--uid\fR (file has specific numeric user ID), \fB--user\fR (file owned by specific user, numeric user ID allowed), \fB--gid\fR (file has specific group ID), \fB--group\fR (file belongs to specific group, numeric group ID allowed). The option \fB--maxdepth\fR limits find to decend at most N levels of directory tree. The options \fB--print\fR and \fB--print0\fR print full file name, followed by a newline or NUL character correspondingly.  Using \fB!\fR before an option negates its meaning (\fIfiles NOT matching the parameter\fR).  Using \fB+\fR before a numeric value means \fIfiles with the parameter OR MORE\fR, while \fB-\fR before a numeric value means \fIfiles with the parameter OR LESS\fR.
+To search the directory tree rooted at the given dir/file name for the files that match the given parameters: \fB--atime\fR (file was last accessed N*24 hours ago), \fB--ctime\fR (file's status was last changed N*24 hours ago), \fB--mtime\fR (file's data was last modified N*24 hours ago), \fB--obd\fR (file has an object on a specific OST or OSTs), \fB--size\fR (file has size in bytes, or \fBk\fRilo-, \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes if a suffix is given), \fB--type\fR (file has the type: \fBb\fRlock, \fBc\fRharacter, \fBd\fRirectory, \fBp\fRipe, \fBf\fRile, sym\fBl\fRink, \fBs\fRocket, or \fBD\fRoor (Solaris)), \fB--uid\fR (file has specific numeric user ID), \fB--user\fR (file owned by specific user, numeric user ID allowed), \fB--gid\fR (file has specific group ID), \fB--group\fR (file belongs to specific group, numeric group ID allowed), \fB--layout\fR (file has a raid0 layout or is released). The option \fB--maxdepth\fR limits find to decend at most N levels of directory tree. The options \fB--print\fR and \fB--print0\fR print full file name, followed by a newline or NUL character correspondingly.  Using \fB!\fR before an option negates its meaning (\fIfiles NOT matching the parameter\fR).  Using \fB+\fR before a numeric value means \fIfiles with the parameter OR MORE\fR, while \fB-\fR before a numeric value means \fIfiles with the parameter OR LESS\fR.
 .TP
 .B getname [-h]|[path ...]
 Report all the Lustre mount points and the corresponding Lustre filesystem
@@ -127,6 +129,7 @@ to that filesystem are displayed.
 .B getstripe [--obd|-O <uuid>] [--quiet|-q] [--verbose|-v] 
         \fB[--count | -c ] [--index | -i | --offset | -o  ]
         \fB[--pool | -p ] [--size | -s ] [--directory | -d ]
+       \fB[--layout | -L]
         \fB[--recursive | -r ] [--raw | -R ] <dirname|filename>\fR
 .br
 List the striping information for a given filename or directory tree.
@@ -136,6 +139,7 @@ only want specific striping information then the options of
 .BR --size ,
 .BR --index ,
 .BR --offset ,
+.BR --layout ,
 or
 .B --pool  
 can be used to return only the specific fields.
index 70bf405..b69c22c 100644 (file)
@@ -1,18 +1,23 @@
 .TH lustreapi 3 "2012 Dec 21" Lustre "Lustre Application Interface Library"
 .SH NAME
-llapi_hsm_state_get \- get HSM state information for a file on Lustre filesystem
+llapi_hsm_state_get llapi_hsm_state_get_fd \- get HSM state information for a file on Lustre filesystem
 .SH SYNOPSIS
 .nf
 .B #include <lustre/lustreapi.h>
 .sp
 .BI "int llapi_hsm_state_get(const char *" path ", struct hsm_user_state *" hus ");"
 .sp
+.BI "int llapi_hsm_state_get_fd(int " fd ", struct hsm_user_state *" hus ");"
+.sp
 .fi
 .SH DESCRIPTION
 .LP
 .B llapi_hsm_state_get(\|)
+.B llapi_hsm_state_get_fd(\|)
 read HSM state information like HSM flags and HSM archive ID for file pointed by
-.IR path .
+.IR path
+or
+.IR fd .
 Information is returned in
 .I hus
 which should already be allocated.
@@ -69,7 +74,8 @@ File copy in backend is not usable anymore and file could not be restore.
 .SH RETURN VALUES
 .LP
 .B llapi_hsm_state_get(\|)
-returns:
+.B llapi_hsm_state_get_fd(\|)
+return:
 .TP
 0
 on success
@@ -148,3 +154,4 @@ int main(int argc, char **argv)
 .BR lustre (7),
 .BR lustreapi (7),
 .BR llapi_hsm_state_set (3)
+.BR llapi_hsm_state_set_fd (3)
index 1d2e83c..b7b8841 100644 (file)
@@ -1,6 +1,6 @@
 .TH lustreapi 3 "2012 Dec 21" Lustre "Lustre Application Interface Library"
 .SH NAME
-llapi_hsm_state_set \- set HSM flags for a file on Lustre filesystem
+llapi_hsm_state_set llapi_hsm_state_set_fd \- set HSM flags for a file on Lustre filesystem
 .SH SYNOPSIS
 .nf
 .B #include <lustre/lustreapi.h>
@@ -8,12 +8,18 @@ llapi_hsm_state_set \- set HSM flags for a file on Lustre filesystem
 .BI "int llapi_hsm_state_set(const char *" path ", __u64 " setmask ",
 .BI "                        __u64 " clearmask ", __u32 " archive_id ");"
 .sp
+.BI "int llapi_hsm_state_set_fd(int " fd ", __u64 " setmask ",
+.BI "                           __u64 " clearmask ", __u32 " archive_id ");"
+.sp
 .fi
 .SH DESCRIPTION
 .LP
 .B llapi_hsm_state_set(\|)
+.B llapi_hsm_state_set_fd(\|)
 sets, clears HSM flags and modifies archive ID for file pointed by
-.IR path .
+.IR path
+or
+.IR fd .
 
 .TP 20
 .I setmask
@@ -33,7 +39,8 @@ for available flags.
 .SH RETURN VALUES
 .LP
 .B llapi_hsm_state_set(\|)
-returns:
+.B llapi_hsm_state_set_fd(\|)
+return:
 .TP
 0
 on success
@@ -93,3 +100,4 @@ int main(int argc, char **argv)
 .BR lustre (7),
 .BR lustreapi (7),
 .BR llapi_hsm_state_get (3)
+.BR llapi_hsm_state_get_fd (3)
index 952c264..36fbce9 100644 (file)
@@ -255,9 +255,9 @@ struct ost_id {
 #define LL_IOC_LMV_SETSTRIPE           _IOWR('f', 240, struct lmv_user_md)
 #define LL_IOC_LMV_GETSTRIPE           _IOWR('f', 241, struct lmv_user_md)
 #define LL_IOC_REMOVE_ENTRY            _IOWR('f', 242, __u64)
-
 #define LL_IOC_SET_LEASE               _IOWR('f', 243, long)
 #define LL_IOC_GET_LEASE               _IO('f', 244)
+#define LL_IOC_HSM_IMPORT              _IOWR('f', 245, struct hsm_user_import)
 
 #define LL_STATFS_LMV          1
 #define LL_STATFS_LOV          2
@@ -1141,6 +1141,21 @@ static inline int hal_size(struct hsm_action_list *hal)
        return sz;
 }
 
+/* HSM file import
+ * describe the attributes to be set on imported file
+ */
+struct hsm_user_import {
+       __u64           hui_size;
+       __u64           hui_atime;
+       __u64           hui_mtime;
+       __u32           hui_atime_ns;
+       __u32           hui_mtime_ns;
+       __u32           hui_uid;
+       __u32           hui_gid;
+       __u32           hui_mode;
+       __u32           hui_archive_id;
+};
+
 /* Copytool progress reporting */
 #define HP_FLAG_COMPLETED 0x01
 #define HP_FLAG_RETRY     0x02
index 2639733..880189d 100644 (file)
@@ -90,97 +90,110 @@ extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
 #define HAVE_LLAPI_FILE_LOOKUP
 extern int llapi_file_lookup(int dirfd, const char *name);
 
-#define VERBOSE_COUNT      0x1
-#define VERBOSE_SIZE       0x2
-#define VERBOSE_OFFSET     0x4
-#define VERBOSE_POOL       0x8
-#define VERBOSE_DETAIL     0x10
-#define VERBOSE_OBJID      0x20
-#define VERBOSE_GENERATION 0x40
-#define VERBOSE_MDTINDEX   0x80
-#define VERBOSE_ALL        (VERBOSE_COUNT | VERBOSE_SIZE | VERBOSE_OFFSET | \
-                            VERBOSE_POOL | VERBOSE_OBJID | VERBOSE_GENERATION)
+#define VERBOSE_COUNT          0x1
+#define VERBOSE_SIZE           0x2
+#define VERBOSE_OFFSET         0x4
+#define VERBOSE_POOL           0x8
+#define VERBOSE_DETAIL         0x10
+#define VERBOSE_OBJID          0x20
+#define VERBOSE_GENERATION     0x40
+#define VERBOSE_MDTINDEX       0x80
+#define VERBOSE_LAYOUT         0x100
+#define VERBOSE_ALL            (VERBOSE_COUNT | VERBOSE_SIZE | \
+                                VERBOSE_OFFSET | VERBOSE_POOL | \
+                                VERBOSE_OBJID | VERBOSE_GENERATION |\
+                                VERBOSE_LAYOUT)
 
 struct find_param {
-        unsigned int maxdepth;
-        time_t  atime;
-        time_t  mtime;
-        time_t  ctime;
-        int     asign;  /* cannot be bitfields due to using pointers to */
-        int     csign;  /* access them during argument parsing. */
-        int     msign;
-        int     type;
-        int             size_sign:2,        /* these need to be signed values */
-                        stripesize_sign:2,
-                        stripecount_sign:2;
-        unsigned long long size;
-        unsigned long long size_units;
-        uid_t uid;
-        gid_t gid;
-
-        unsigned long   zeroend:1,
-                        recursive:1,
-                        exclude_pattern:1,
-                        exclude_type:1,
-                        exclude_obd:1,
-                        exclude_mdt:1,
-                        exclude_gid:1,
-                        exclude_uid:1,
-                        check_gid:1,            /* group ID */
-                        check_uid:1,            /* user ID */
-                        check_pool:1,           /* LOV pool name */
-                        check_size:1,           /* file size */
-                        exclude_pool:1,
-                        exclude_size:1,
-                        exclude_atime:1,
-                        exclude_mtime:1,
-                        exclude_ctime:1,
-                        get_lmv:1,              /* get MDT list from LMV */
-                        raw:1,                  /* do not fill in defaults */
-                        check_stripesize:1,     /* LOV stripe size */
-                        exclude_stripesize:1,
-                        check_stripecount:1,    /* LOV stripe count */
-                        exclude_stripecount:1;
-
-        int     verbose;
-        int     quiet;
-
-        /* regular expression */
-        char   *pattern;
-
-        char   *print_fmt;
-
-        struct  obd_uuid       *obduuid;
-        int                     num_obds;
-        int                     num_alloc_obds;
-        int                     obdindex;
-        int                    *obdindexes;
-
-        struct  obd_uuid       *mdtuuid;
-        int                     num_mdts;
-        int                     num_alloc_mdts;
-        int                     mdtindex;
-        int                    *mdtindexes;
-        int                     file_mdtindex;
-
-       int     lumlen;
-       struct  lov_user_mds_data *lmd;
-
-        char poolname[LOV_MAXPOOLNAME + 1];
-
-       int                     fp_lmv_count;
+       unsigned int             maxdepth;
+       time_t                   atime;
+       time_t                   mtime;
+       time_t                   ctime;
+       /* cannot be bitfields due to using pointers to */
+       int                      asign;
+       /* access them during argument parsing. */
+       int                      csign;
+       int                      msign;
+       int                      type;
+       /* these need to be signed values */
+       int                      size_sign:2,
+                                stripesize_sign:2,
+                                stripecount_sign:2;
+       unsigned long long       size;
+       unsigned long long       size_units;
+       uid_t                    uid;
+       gid_t                    gid;
+
+       unsigned long            zeroend:1,
+                                recursive:1,
+                                exclude_pattern:1,
+                                exclude_type:1,
+                                exclude_obd:1,
+                                exclude_mdt:1,
+                                exclude_gid:1,
+                                exclude_uid:1,
+                                check_gid:1,           /* group ID */
+                                check_uid:1,           /* user ID */
+                                check_pool:1,          /* LOV pool name */
+                                check_size:1,          /* file size */
+                                exclude_pool:1,
+                                exclude_size:1,
+                                exclude_atime:1,
+                                exclude_mtime:1,
+                                exclude_ctime:1,
+                                get_lmv:1,     /* get MDT list from LMV */
+                                raw:1,         /* do not fill in defaults */
+                                check_stripesize:1,    /* LOV stripe size */
+                                exclude_stripesize:1,
+                                check_stripecount:1,   /* LOV stripe count */
+                                exclude_stripecount:1,
+                                check_layout:1,
+                                exclude_layout:1;
+
+       int                      verbose;
+       int                      quiet;
+
+       /* regular expression */
+       char                    *pattern;
+
+       char                    *print_fmt;
+
+       struct  obd_uuid        *obduuid;
+       int                      num_obds;
+       int                      num_alloc_obds;
+       int                      obdindex;
+       int                     *obdindexes;
+
+       struct  obd_uuid        *mdtuuid;
+       int                      num_mdts;
+       int                      num_alloc_mdts;
+       int                      mdtindex;
+       int                     *mdtindexes;
+       int                      file_mdtindex;
+
+       int                      lumlen;
+       struct  lov_user_mds_data       *lmd;
+
+       char                    poolname[LOV_MAXPOOLNAME + 1];
+
+       int                      fp_lmv_count;
        struct lmv_user_md      *fp_lmv_md;
 
-        unsigned long long stripesize;
-        unsigned long long stripesize_units;
-        unsigned long long stripecount;
-
-        /* In-process parameters. */
-        unsigned long   got_uuids:1,
-                        obds_printed:1,
-                        have_fileinfo:1;        /* file attrs and LOV xattr */
-        unsigned int    depth;
-        dev_t           st_dev;
+       unsigned long long       stripesize;
+       unsigned long long       stripesize_units;
+       unsigned long long       stripecount;
+       __u32                    layout;
+
+       /* In-process parameters. */
+       unsigned long            got_uuids:1,
+                                obds_printed:1,
+                                have_fileinfo:1; /* file attrs and LOV xattr */
+       unsigned int             depth;
+       dev_t                    st_dev;
+       __u64                    padding1;
+       __u64                    padding2;
+       __u64                    padding3;
+       __u64                    padding4;
 };
 
 extern int llapi_ostlist(char *path, struct find_param *param);
@@ -241,7 +254,10 @@ extern int llapi_fd2fid(const int fd, lustre_fid *fid);
 
 extern int llapi_get_version(char *buffer, int buffer_size, char **version);
 extern int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags);
+extern int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus);
 extern int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus);
+extern int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
+                                 __u32 archive_id);
 extern int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
                               __u32 archive_id);
 
@@ -294,7 +310,7 @@ extern int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy,
 extern int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy,
                              const struct hsm_progress *hp);
 extern int llapi_hsm_progress(char *mnt, struct hsm_progress *hp);
-extern int llapi_hsm_import(const char *dst, int archive, struct stat *st,
+extern int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
                            unsigned long long stripe_size, int stripe_offset,
                            int stripe_count, int stripe_pattern,
                            char *pool_name, lustre_fid *newfid);
index 361bec1..8c06a27 100644 (file)
@@ -2158,6 +2158,86 @@ free:
        RETURN(rc);
 }
 
+static int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss)
+{
+       struct md_op_data       *op_data;
+       int                      rc;
+
+       /* Non-root users are forbidden to set or clear flags which are
+        * NOT defined in HSM_USER_MASK. */
+       if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) &&
+           !cfs_capable(CFS_CAP_SYS_ADMIN))
+               RETURN(-EPERM);
+
+       op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+                                    LUSTRE_OPC_ANY, hss);
+       if (IS_ERR(op_data))
+               RETURN(PTR_ERR(op_data));
+
+       rc = obd_iocontrol(LL_IOC_HSM_STATE_SET, ll_i2mdexp(inode),
+                          sizeof(*op_data), op_data, NULL);
+
+       ll_finish_md_op_data(op_data);
+
+       RETURN(rc);
+}
+
+static int ll_hsm_import(struct inode *inode, struct file *file,
+                        struct hsm_user_import *hui)
+{
+       struct hsm_state_set    *hss = NULL;
+       struct iattr            *attr = NULL;
+       int                      rc;
+       ENTRY;
+
+       if (!S_ISREG(inode->i_mode))
+               RETURN(-EINVAL);
+
+       /* set HSM flags */
+       OBD_ALLOC_PTR(hss);
+       if (hss == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       hss->hss_valid = HSS_SETMASK | HSS_ARCHIVE_ID;
+       hss->hss_archive_id = hui->hui_archive_id;
+       hss->hss_setmask = HS_ARCHIVED | HS_EXISTS | HS_RELEASED;
+       rc = ll_hsm_state_set(inode, hss);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       OBD_ALLOC_PTR(attr);
+       if (attr == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+       attr->ia_mode |= S_IFREG;
+       attr->ia_uid = hui->hui_uid;
+       attr->ia_gid = hui->hui_gid;
+       attr->ia_size = hui->hui_size;
+       attr->ia_mtime.tv_sec = hui->hui_mtime;
+       attr->ia_mtime.tv_nsec = hui->hui_mtime_ns;
+       attr->ia_atime.tv_sec = hui->hui_atime;
+       attr->ia_atime.tv_nsec = hui->hui_atime_ns;
+
+       attr->ia_valid = ATTR_SIZE | ATTR_MODE | ATTR_FORCE |
+                        ATTR_UID | ATTR_GID |
+                        ATTR_MTIME | ATTR_MTIME_SET |
+                        ATTR_ATIME | ATTR_ATIME_SET;
+
+       rc = ll_setattr_raw(file->f_dentry, attr, true);
+       if (rc == -ENODATA)
+               rc = 0;
+
+out:
+       if (hss != NULL)
+               OBD_FREE_PTR(hss);
+
+       if (attr != NULL)
+               OBD_FREE_PTR(attr);
+
+       RETURN(rc);
+}
+
 long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct inode            *inode = file->f_dentry->d_inode;
@@ -2320,37 +2400,19 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                RETURN(rc);
        }
        case LL_IOC_HSM_STATE_SET: {
-               struct md_op_data       *op_data;
                struct hsm_state_set    *hss;
                int                      rc;
 
                OBD_ALLOC_PTR(hss);
                if (hss == NULL)
                        RETURN(-ENOMEM);
+
                if (copy_from_user(hss, (char *)arg, sizeof(*hss))) {
                        OBD_FREE_PTR(hss);
                        RETURN(-EFAULT);
                }
 
-               /* Non-root users are forbidden to set or clear flags which are
-                * NOT defined in HSM_USER_MASK. */
-               if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK)
-                   && !cfs_capable(CFS_CAP_SYS_ADMIN)) {
-                       OBD_FREE_PTR(hss);
-                       RETURN(-EPERM);
-               }
-
-               op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
-                                            LUSTRE_OPC_ANY, hss);
-               if (IS_ERR(op_data)) {
-                       OBD_FREE_PTR(hss);
-                       RETURN(PTR_ERR(op_data));
-               }
-
-               rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
-                                  op_data, NULL);
-
-               ll_finish_md_op_data(op_data);
+               rc = ll_hsm_state_set(inode, hss);
 
                OBD_FREE_PTR(hss);
                RETURN(rc);
@@ -2462,7 +2524,23 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        }
                }
                mutex_unlock(&lli->lli_och_mutex);
+               RETURN(rc);
+       }
+       case LL_IOC_HSM_IMPORT: {
+               struct hsm_user_import *hui;
+
+               OBD_ALLOC_PTR(hui);
+               if (hui == NULL)
+                       RETURN(-ENOMEM);
+
+               if (copy_from_user(hui, (void *)arg, sizeof(*hui))) {
+                       OBD_FREE_PTR(hui);
+                       RETURN(-EFAULT);
+               }
+
+               rc = ll_hsm_import(inode, file, hui);
 
+               OBD_FREE_PTR(hui);
                RETURN(rc);
        }
        default: {
index e827f01..b7113c5 100644 (file)
@@ -881,7 +881,7 @@ void ll_kill_super(struct super_block *sb);
 struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock);
 struct inode *ll_inode_from_lock(struct ldlm_lock *lock);
 void ll_clear_inode(struct inode *inode);
-int ll_setattr_raw(struct dentry *dentry, struct iattr *attr);
+int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import);
 int ll_setattr(struct dentry *de, struct iattr *attr);
 int ll_statfs(struct dentry *de, struct kstatfs *sfs);
 int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
index 1eec9a6..3623dbd 100644 (file)
@@ -1398,8 +1398,10 @@ static int ll_setattr_ost(struct inode *inode, struct iattr *attr)
  * to the OST with the punch RPC, otherwise we do an explicit setattr RPC.
  * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE
  * at the same time.
+ *
+ * In case of HSMimport, we only set attr on MDS.
  */
-int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
+int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
 {
         struct inode *inode = dentry->d_inode;
         struct ll_inode_info *lli = ll_i2info(inode);
@@ -1410,9 +1412,10 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
         ENTRY;
 
        CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, "
-               "valid %x\n", ll_get_fsname(inode->i_sb, NULL, 0), inode,
+               "valid %x, hsm_import %d\n",
+               ll_get_fsname(inode->i_sb, NULL, 0), inode,
                PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size,
-               attr->ia_valid);
+               attr->ia_valid, hsm_import);
 
        if (attr->ia_valid & ATTR_SIZE) {
                 /* Check new size against VFS/VM file size limit and rlimit */
@@ -1505,20 +1508,20 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
                ccc_inode_lsm_put(inode, lsm);
        }
 
-       /* clear size attr for released file
+       /* if not in HSM import mode, clear size attr for released file
         * we clear the attribute send to MDT in op_data, not the original
         * received from caller in attr which is used later to
         * decide return code */
-       if (file_is_released && (attr->ia_valid & ATTR_SIZE))
+       if (file_is_released && (attr->ia_valid & ATTR_SIZE) && !hsm_import)
                op_data->op_attr.ia_valid &= ~ATTR_SIZE;
 
         rc = ll_md_setattr(dentry, op_data, &mod);
         if (rc)
                 GOTO(out, rc);
 
-       /* truncate failed, others succeed */
+       /* truncate failed (only when non HSM import), others succeed */
        if (file_is_released) {
-               if (attr->ia_valid & ATTR_SIZE)
+               if ((attr->ia_valid & ATTR_SIZE) && !hsm_import)
                        GOTO(out, rc = -ENODATA);
                else
                        GOTO(out, rc = 0);
@@ -1559,7 +1562,7 @@ out:
        if (!S_ISDIR(inode->i_mode)) {
                up_write(&lli->lli_trunc_sem);
                mutex_lock(&inode->i_mutex);
-               if (attr->ia_valid & ATTR_SIZE)
+               if ((attr->ia_valid & ATTR_SIZE) && !hsm_import)
                        inode_dio_wait(inode);
        }
 
@@ -1571,30 +1574,30 @@ out:
 
 int ll_setattr(struct dentry *de, struct iattr *attr)
 {
-        int mode = de->d_inode->i_mode;
-
-        if ((attr->ia_valid & (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) ==
-                              (ATTR_CTIME|ATTR_SIZE|ATTR_MODE))
-                attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
-
-        if (((attr->ia_valid & (ATTR_MODE|ATTR_FORCE|ATTR_SIZE)) ==
-                               (ATTR_SIZE|ATTR_MODE)) &&
-            (((mode & S_ISUID) && !(attr->ia_mode & S_ISUID)) ||
-             (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
-              !(attr->ia_mode & S_ISGID))))
-                attr->ia_valid |= ATTR_FORCE;
-
-        if ((mode & S_ISUID) &&
-            !(attr->ia_mode & S_ISUID) &&
-            !(attr->ia_valid & ATTR_KILL_SUID))
-                attr->ia_valid |= ATTR_KILL_SUID;
-
-        if (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
-            !(attr->ia_mode & S_ISGID) &&
-            !(attr->ia_valid & ATTR_KILL_SGID))
-                attr->ia_valid |= ATTR_KILL_SGID;
-
-        return ll_setattr_raw(de, attr);
+       int mode = de->d_inode->i_mode;
+
+       if ((attr->ia_valid & (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) ==
+                             (ATTR_CTIME|ATTR_SIZE|ATTR_MODE))
+               attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
+
+       if (((attr->ia_valid & (ATTR_MODE|ATTR_FORCE|ATTR_SIZE)) ==
+                              (ATTR_SIZE|ATTR_MODE)) &&
+           (((mode & S_ISUID) && !(attr->ia_mode & S_ISUID)) ||
+            (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+             !(attr->ia_mode & S_ISGID))))
+               attr->ia_valid |= ATTR_FORCE;
+
+       if ((mode & S_ISUID) &&
+           !(attr->ia_mode & S_ISUID) &&
+           !(attr->ia_valid & ATTR_KILL_SUID))
+               attr->ia_valid |= ATTR_KILL_SUID;
+
+       if (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+           !(attr->ia_mode & S_ISGID) &&
+           !(attr->ia_valid & ATTR_KILL_SGID))
+               attr->ia_valid |= ATTR_KILL_SGID;
+
+       return ll_setattr_raw(de, attr, false);
 }
 
 int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
index 1eee9bc..4ee8feb 100644 (file)
@@ -4429,6 +4429,46 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_user_item) == 0, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_user_item));
 
+       /* Checks for struct hsm_user_import */
+       LASSERTF((int)sizeof(struct hsm_user_import) == 48, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_user_import));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_size) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_size));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_size) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_size));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_uid) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_uid));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_uid));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_gid) == 36, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_gid));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_gid));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mode) == 40, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mode));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mode) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mode));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_atime) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_atime));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_atime) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_atime));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_atime_ns) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_atime_ns));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_atime_ns) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_atime_ns));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mtime) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mtime));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mtime) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mtime));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mtime_ns) == 28, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mtime_ns));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mtime_ns) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mtime_ns));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_archive_id) == 44, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_archive_id));
+
        /* Checks for struct update_buf */
        LASSERTF((int)sizeof(struct update_buf) == 8, "found %lld\n",
                 (long long)(int)sizeof(struct update_buf));
index fcf5f72..3a141d9 100644 (file)
@@ -3927,8 +3927,7 @@ run_test 54e "console/tty device works in lustre ======================"
 test_56a() {   # was test_56
         rm -rf $DIR/$tdir
         $SETSTRIPE -d $DIR
-       test_mkdir $DIR/$tdir
-        test_mkdir $DIR/$tdir/dir
+        test_mkdir -p $DIR/$tdir/dir
         NUMFILES=3
         NUMFILESx2=$(($NUMFILES * 2))
         for i in `seq 1 $NUMFILES` ; do
@@ -4514,6 +4513,34 @@ test_56x() {
 }
 run_test 56x "lfs migration support"
 
+test_56y() {
+       local res=""
+
+       local dir0=$DIR/$tdir/$testnum
+       mkdir -p $dir0 || error "creating dir $dir0"
+       local f1=$dir0/file1
+       local f2=$dir0/file2
+
+       touch $f1 || error "creating std file $f1"
+       $MULTIOP $f2 H2c || error "creating released file $f2"
+
+       # a directory can be raid0, so ask only for files
+       res=$($LFIND $dir0 -L raid0 -type f | wc -l)
+       [[ $res == 2 ]] || error "search raid0: found $res files != 2"
+
+       res=$($LFIND $dir0 \! -L raid0 -type f | wc -l)
+       [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
+
+       # only files can be released, so no need to force file search
+       res=$($LFIND $dir0 -L released)
+       [[ $res == $f2 ]] || error "search released: found $res != $f2"
+
+       res=$($LFIND $dir0 \! -L released)
+       [[ $res == $f1 ]] || error "search !released: found $res != $f1"
+
+}
+run_test 56y "lfs find -L raid0|released"
+
 test_57a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
        # note test will not do anything if MDS is not local
@@ -11260,8 +11287,7 @@ test_229() { # LU-2482, LU-3448
 
        $GETSTRIPE -v $DIR/$tfile
 
-       local pattern=$($GETSTRIPE -v $DIR/$tfile |
-                       grep lmm_stripe_pattern | awk '{print $2}')
+       local pattern=$($GETSTRIPE -L $DIR/$tfile)
        [ X"$pattern" = X"80000001" ] || error "pattern error ($pattern)"
 
        local stripe_count=$($GETSTRIPE -c $DIR/$tfile) || error "getstripe"
index 582c9e7..9e85a66 100644 (file)
@@ -147,10 +147,11 @@ command_t cmdlist[] = {
         "To list the striping info for a given file or files in a\n"
         "directory or recursively for all files in a directory tree.\n"
         "usage: getstripe [--ost|-O <uuid>] [--quiet | -q] [--verbose | -v]\n"
-        "                 [--stripe-count|-c] [--stripe-index|-i]\n"
-        "                 [--pool|-p] [--stripe-size|-S] [--directory|-d]\n"
-        "                 [--mdt-index|-M] [--recursive|-r] [--raw|-R]\n"
-        "                 <directory|filename> ..."},
+        "                 [--stripe-count|-c] [--stripe-index|-i]\n"
+        "                 [--pool|-p] [--stripe-size|-S] [--directory|-d]\n"
+        "                 [--mdt-index|-M] [--recursive|-r] [--raw|-R]\n"
+        "                 [--layout|-L]\n"
+        "                 <directory|filename> ..."},
        {"setdirstripe", lfs_setdirstripe, 0,
         "To create a remote directory on a specified MDT.\n"
         "usage: setdirstripe <--index|-i mdt_index> <dir>\n"
@@ -188,6 +189,7 @@ command_t cmdlist[] = {
          "     [[!] --stripe-size|-S [+-]N[kMGT]] [[!] --type|-t <filetype>]\n"
          "     [[!] --gid|-g|--group|-G <gid>|<gname>]\n"
          "     [[!] --uid|-u|--user|-U <uid>|<uname>] [[!] --pool <pool>]\n"
+        "     [[!] --layout|-L released,raid0]\n"
          "\t !: used before an option indicates 'NOT' requested attribute\n"
          "\t -: used before a value indicates 'AT MOST' requested value\n"
          "\t +: used before a value indicates 'AT LEAST' requested value\n"},
@@ -861,6 +863,25 @@ static int id2name(char **name, unsigned int id, int type)
         return 0;
 }
 
+static int name2layout(__u32 *layout, char *name)
+{
+       char *ptr, *lyt;
+
+       *layout = 0;
+       for (ptr = name; ; ptr = NULL) {
+               lyt = strtok(ptr, ",");
+               if (lyt == NULL)
+                       break;
+               if (strcmp(lyt, "released") == 0)
+                       *layout |= LOV_PATTERN_F_RELEASED;
+               else if (strcmp(lyt, "raid0") == 0)
+                       *layout |= LOV_PATTERN_RAID0;
+               else
+                       return -1;
+       }
+       return 0;
+}
+
 #define FIND_POOL_OPT 3
 static int lfs_find(int argc, char **argv)
 {
@@ -877,6 +898,7 @@ static int lfs_find(int argc, char **argv)
                 {"group",        required_argument, 0, 'G'},
                 {"stripe-index", required_argument, 0, 'i'},
                 {"stripe_index", required_argument, 0, 'i'},
+               {"layout",       required_argument, 0, 'L'},
                 {"mdt",          required_argument, 0, 'm'},
                 {"mtime",        required_argument, 0, 'M'},
                 {"name",         required_argument, 0, 'n'},
@@ -905,11 +927,11 @@ static int lfs_find(int argc, char **argv)
 
         time(&t);
 
-        optind = 0;
-        /* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
-        while ((c = getopt_long_only(argc, argv,
-                                     "-A:c:C:D:g:G:i:m:M:n:O:Ppqrs:S:t:u:U:v",
-                                     long_opts, NULL)) >= 0) {
+       optind = 0;
+       /* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
+       while ((c = getopt_long_only(argc, argv,
+                                    "-A:c:C:D:g:G:i:L:m:M:n:O:Ppqrs:S:t:u:U:v",
+                                    long_opts, NULL)) >= 0) {
                 xtime = NULL;
                 xsign = NULL;
                 if (neg_opt)
@@ -1007,6 +1029,13 @@ static int lfs_find(int argc, char **argv)
                         param.exclude_gid = !!neg_opt;
                         param.check_gid = 1;
                         break;
+               case 'L':
+                       ret = name2layout(&param.layout, optarg);
+                       if (ret)
+                               goto err;
+                       param.exclude_layout = !!neg_opt;
+                       param.check_layout = 1;
+                       break;
                 case 'u':
                 case 'U':
                         ret = name2id(&param.uid, optarg, USER);
@@ -1203,63 +1232,64 @@ err:
 static int lfs_getstripe_internal(int argc, char **argv,
                                  struct find_param *param)
 {
-        struct option long_opts[] = {
+       struct option long_opts[] = {
 #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0)
 #warning "remove deprecated --count option"
 #else
-                /* This formerly implied "stripe-count", but was explicitly
-                 * made "stripe-count" for consistency with other options,
-                 * and to separate it from "mdt-count" when DNE arrives. */
-                {"count",        no_argument,       0, 'c'},
+               /* This formerly implied "stripe-count", but was explicitly
+                * made "stripe-count" for consistency with other options,
+                * and to separate it from "mdt-count" when DNE arrives. */
+               {"count",               no_argument,            0, 'c'},
 #endif
-                {"stripe-count", no_argument,       0, 'c'},
-                {"stripe_count", no_argument,       0, 'c'},
-                {"directory",    no_argument,       0, 'd'},
-                {"generation",   no_argument,       0, 'g'},
+               {"stripe-count",        no_argument,            0, 'c'},
+               {"stripe_count",        no_argument,            0, 'c'},
+               {"directory",           no_argument,            0, 'd'},
+               {"generation",          no_argument,            0, 'g'},
 #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0)
 #warning "remove deprecated --index option"
 #else
-                /* This formerly implied "stripe-index", but was explicitly
-                 * made "stripe-index" for consistency with other options,
-                 * and to separate it from "mdt-index" when DNE arrives. */
-                {"index",        no_argument,       0, 'i'},
+               /* This formerly implied "stripe-index", but was explicitly
+                * made "stripe-index" for consistency with other options,
+                * and to separate it from "mdt-index" when DNE arrives. */
+               {"index",               no_argument,            0, 'i'},
 #endif
-                {"stripe-index", no_argument,       0, 'i'},
-                {"stripe_index", no_argument,       0, 'i'},
-                {"mdt-index",    no_argument,       0, 'M'},
-                {"mdt_index",    no_argument,       0, 'M'},
+               {"stripe-index",        no_argument,            0, 'i'},
+               {"stripe_index",        no_argument,            0, 'i'},
+               {"layout",              no_argument,            0, 'L'},
+               {"mdt-index",           no_argument,            0, 'M'},
+               {"mdt_index",           no_argument,            0, 'M'},
 #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0)
 #warning "remove deprecated --offset option"
 #else
-                /* This formerly implied "stripe-index", but was confusing
-                 * with "file offset" (which will eventually be needed for
-                 * with different layouts by offset), so deprecate it. */
-                {"offset",       no_argument,       0, 'o'},
+               /* This formerly implied "stripe-index", but was confusing
+                * with "file offset" (which will eventually be needed for
+                * with different layouts by offset), so deprecate it. */
+               {"offset",              no_argument,            0, 'o'},
 #endif
-                {"obd",          required_argument, 0, 'O'},
-                {"ost",          required_argument, 0, 'O'},
-                {"pool",         no_argument,       0, 'p'},
-                {"quiet",        no_argument,       0, 'q'},
-                {"recursive",    no_argument,       0, 'r'},
-                {"raw",          no_argument,       0, 'R'},
+               {"obd",                 required_argument,      0, 'O'},
+               {"ost",                 required_argument,      0, 'O'},
+               {"pool",                no_argument,            0, 'p'},
+               {"quiet",               no_argument,            0, 'q'},
+               {"recursive",           no_argument,            0, 'r'},
+               {"raw",                 no_argument,            0, 'R'},
 #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0)
 #warning "remove deprecated --size option"
 #else
-                /* This formerly implied "--stripe-size", but was confusing
-                 * with "lfs find --size|-s", which means "file size", so use
-                 * the consistent "--stripe-size|-S" for all commands. */
-                {"size",         no_argument,       0, 's'},
+               /* This formerly implied "--stripe-size", but was confusing
+                * with "lfs find --size|-s", which means "file size", so use
+                * the consistent "--stripe-size|-S" for all commands. */
+               {"size",                no_argument,            0, 's'},
 #endif
-                {"stripe-size",  no_argument,       0, 'S'},
-                {"stripe_size",  no_argument,       0, 'S'},
-                {"verbose",      no_argument,       0, 'v'},
-                {0, 0, 0, 0}
-        };
-        int c, rc;
+               {"stripe-size",         no_argument,            0, 'S'},
+               {"stripe_size",         no_argument,            0, 'S'},
+               {"verbose",             no_argument,            0, 'v'},
+               {0, 0, 0, 0}
+       };
+       int c, rc;
 
        param->maxdepth = 1;
        optind = 0;
-       while ((c = getopt_long(argc, argv, "cdghiMoO:pqrRsSv",
+       while ((c = getopt_long(argc, argv, "cdghiLMoO:pqrRsSv",
                                long_opts, NULL)) != -1) {
                switch (c) {
                case 'O':
@@ -1344,6 +1374,12 @@ static int lfs_getstripe_internal(int argc, char **argv,
                                param->maxdepth = 0;
                        }
                        break;
+               case 'L':
+                       if (!(param->verbose & VERBOSE_DETAIL)) {
+                               param->verbose |= VERBOSE_LAYOUT;
+                               param->maxdepth = 0;
+                       }
+                       break;
                case 'M':
                        if (!(param->verbose & VERBOSE_DETAIL))
                                param->maxdepth = 0;
index 4a94d1b..818d54c 100644 (file)
@@ -2186,10 +2186,12 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                 }
         }
 
-        if ((verbose & VERBOSE_DETAIL) && !is_dir) {
-                llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_pattern: %x%c",
-                             lum->lmm_pattern, nl);
-        }
+       if ((verbose & VERBOSE_LAYOUT) && !is_dir) {
+               if (verbose & ~VERBOSE_LAYOUT)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%spattern:        ",
+                                    prefix);
+               llapi_printf(LLAPI_MSG_NORMAL, "%.x%c", lum->lmm_pattern, nl);
+       }
 
         if ((verbose & VERBOSE_GENERATION) && !is_dir) {
                 if (verbose & ~VERBOSE_GENERATION)
@@ -2703,11 +2705,12 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir,
 
         /* Request MDS for the stat info if some of these parameters need
          * to be compared. */
-        if (param->obduuid    || param->mdtuuid || param->check_uid ||
-            param->check_gid || param->check_pool || param->atime   ||
-            param->ctime     || param->mtime || param->check_size ||
-            param->check_stripecount || param->check_stripesize)
-                decision = 0;
+       if (param->obduuid   || param->mdtuuid || param->check_uid ||
+           param->check_gid || param->check_pool || param->atime   ||
+           param->ctime     || param->mtime || param->check_size ||
+           param->check_stripecount || param->check_stripesize ||
+           param->check_layout)
+               decision = 0;
 
         if (param->type && checked_type == 0)
                 decision = 0;
@@ -2812,6 +2815,18 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir,
                         goto decided;
         }
 
+       if (param->check_layout) {
+               __u32 found;
+
+               found = (param->lmd->lmd_lmm.lmm_pattern & param->layout);
+               if ((param->lmd->lmd_lmm.lmm_pattern == 0xFFFFFFFF) ||
+                   (found && param->exclude_layout) ||
+                   (!found && !param->exclude_layout)) {
+                       decision = -1;
+                       goto decided;
+               }
+       }
+
         /* If an OBD UUID is specified but none matches, skip this file. */
         if ((param->obduuid && param->obdindex == OBD_NOT_FOUND) ||
             (param->mdtuuid && param->mdtindex == OBD_NOT_FOUND))
index 695c0bc..5d08949 100644 (file)
@@ -397,52 +397,57 @@ int llapi_hsm_progress(char *mnt, struct hsm_progress *hp)
  *                 be used.
  * \param newfid[out] Filled with new Lustre fid.
  */
-int llapi_hsm_import(const char *dst, int archive, struct stat *st,
+int llapi_hsm_import(const char *dst, int archive, const struct stat *st,
                     unsigned long long stripe_size, int stripe_offset,
                     int stripe_count, int stripe_pattern, char *pool_name,
                     lustre_fid *newfid)
 {
-       struct utimbuf  time;
-       int             fd;
-       int             rc = 0;
+       struct hsm_user_import   hui;
+       int                      fd;
+       int                      rc = 0;
 
-       /* Create a non-striped file */
-       fd = open(dst, O_CREAT | O_EXCL | O_LOV_DELAY_CREATE | O_NONBLOCK,
-                 st->st_mode);
+       if (stripe_pattern == 0)
+               stripe_pattern = LOV_PATTERN_RAID0;
 
-       if (fd < 0)
+       /* Create a non-striped file */
+       fd = llapi_file_open_pool(dst, O_CREAT | O_WRONLY, st->st_mode,
+                                 stripe_size, stripe_offset, stripe_count,
+                                 stripe_pattern | LOV_PATTERN_F_RELEASED,
+                                 pool_name);
+       if (fd < 0) {
+               llapi_error(LLAPI_MSG_ERROR, -errno,
+                           "cannot create '%s' for import", dst);
                return -errno;
-       close(fd);
-
-       /* set size on MDT */
-       if (truncate(dst, st->st_size) != 0) {
-               rc = -errno;
-               goto out_unlink;
        }
-       /* Mark archived */
-       rc = llapi_hsm_state_set(dst, HS_EXISTS | HS_RELEASED | HS_ARCHIVED, 0,
-                                archive);
-       if (rc)
-               goto out_unlink;
 
-       /* Get the new fid in the archive. Caller needs to use this fid
+       /* Get the new fid in Lustre. Caller needs to use this fid
           from now on. */
-       rc = llapi_path2fid(dst, newfid);
-       if (rc)
+       rc = llapi_fd2fid(fd, newfid);
+       if (rc != 0) {
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "cannot get fid of '%s' for import", dst);
                goto out_unlink;
+       }
 
-       /* Copy the file attributes */
-       time.actime = st->st_atime;
-       time.modtime = st->st_mtime;
-       if (utime(dst, &time) == -1 ||
-               chmod(dst, st->st_mode) == -1 ||
-               chown(dst, st->st_uid, st->st_gid) == -1) {
-               /* we might fail here because we change perms/owner */
+       hui.hui_uid = st->st_uid;
+       hui.hui_gid = st->st_gid;
+       hui.hui_mode = st->st_mode;
+       hui.hui_size = st->st_size;
+       hui.hui_archive_id = archive;
+       hui.hui_atime = st->st_atime;
+       hui.hui_atime_ns = st->st_atim.tv_nsec;
+       hui.hui_mtime = st->st_mtime;
+       hui.hui_mtime_ns = st->st_mtim.tv_nsec;
+       rc = ioctl(fd, LL_IOC_HSM_IMPORT, &hui);
+       if (rc != 0) {
+               llapi_error(LLAPI_MSG_ERROR, rc, "cannot import '%s'", dst);
                rc = -errno;
                goto out_unlink;
        }
 
 out_unlink:
+       if (fd >= 0)
+               close(fd);
        if (rc)
                unlink(dst);
        return rc;
@@ -458,6 +463,23 @@ out_unlink:
  * \retval 0 on success.
  * \retval -errno on error.
  */
+int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus)
+{
+       int rc;
+
+       rc = ioctl(fd, LL_IOC_HSM_STATE_GET, hus);
+       /* If error, save errno value */
+       rc = rc ? -errno : 0;
+
+       return rc;
+}
+
+/**
+ * Return the current HSM states and HSM requests related to file pointed by \a
+ * path.
+ *
+ * see llapi_hsm_state_get_fd() for args use and return
+ */
 int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
 {
        int fd;
@@ -467,16 +489,14 @@ int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
        if (fd < 0)
                return -errno;
 
-       rc = ioctl(fd, LL_IOC_HSM_STATE_GET, hus);
-       /* If error, save errno value */
-       rc = rc ? -errno : 0;
+       rc = llapi_hsm_state_get_fd(fd, hus);
 
        close(fd);
        return rc;
 }
 
 /**
- * Set HSM states of file pointed by \a path.
+ * Set HSM states of file pointed by \a fd
  *
  * Using the provided bitmasks, the current HSM states for this file will be
  * changed. \a archive_id could be used to change the archive number also. Set
@@ -489,16 +509,11 @@ int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
  * \retval 0 on success.
  * \retval -errno on error.
  */
-int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
-                       __u32 archive_id)
+int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
+                          __u32 archive_id)
 {
-       struct hsm_state_set hss;
-       int fd;
-       int rc;
-
-       fd = open(path, O_WRONLY | O_LOV_DELAY_CREATE | O_NONBLOCK);
-       if (fd < 0)
-               return -errno;
+       struct hsm_state_set     hss;
+       int                      rc;
 
        hss.hss_valid = HSS_SETMASK|HSS_CLEARMASK;
        hss.hss_setmask = setmask;
@@ -513,10 +528,29 @@ int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
        /* If error, save errno value */
        rc = rc ? -errno : 0;
 
-       close(fd);
        return rc;
 }
 
+/**
+ * Set HSM states of file pointed by \a path.
+ *
+ * see llapi_hsm_state_set_fd() for args use and return
+ */
+int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
+                       __u32 archive_id)
+{
+       int fd;
+       int rc;
+
+       fd = open(path, O_WRONLY | O_LOV_DELAY_CREATE | O_NONBLOCK);
+       if (fd < 0)
+               return -errno;
+
+       rc = llapi_hsm_state_set_fd(fd, setmask, clearmask, archive_id);
+
+       close(fd);
+       return rc;
+}
 
 /**
  * Return the current HSM request related to file pointed by \a path.
index b845d0c..52155e2 100644 (file)
@@ -1951,8 +1951,7 @@ static void check_layout_intent(void)
        CHECK_VALUE(LAYOUT_INTENT_RESTORE);
 }
 
-static void
-check_hsm_state_set(void)
+static void check_hsm_state_set(void)
 {
        BLANK_LINE();
        CHECK_STRUCT(hsm_state_set);
@@ -1962,8 +1961,7 @@ check_hsm_state_set(void)
        CHECK_MEMBER(hsm_state_set, hss_clearmask);
 }
 
-static void
-check_hsm_current_action(void)
+static void check_hsm_current_action(void)
 {
        BLANK_LINE();
        CHECK_STRUCT(hsm_current_action);
@@ -1972,8 +1970,7 @@ check_hsm_current_action(void)
        CHECK_MEMBER(hsm_current_action, hca_location);
 }
 
-static void
-check_hsm_request(void)
+static void check_hsm_request(void)
 {
        BLANK_LINE();
        CHECK_STRUCT(hsm_request);
@@ -1986,8 +1983,7 @@ check_hsm_request(void)
        CHECK_VALUE_X(HSM_GHOST_COPY);
 }
 
-static void
-check_hsm_user_request(void)
+static void check_hsm_user_request(void)
 {
        BLANK_LINE();
        CHECK_STRUCT(hsm_user_request);
@@ -1995,6 +1991,21 @@ check_hsm_user_request(void)
        CHECK_MEMBER(hsm_user_request, hur_user_item);
 }
 
+static void check_hsm_user_import(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(hsm_user_import);
+       CHECK_MEMBER(hsm_user_import, hui_size);
+       CHECK_MEMBER(hsm_user_import, hui_uid);
+       CHECK_MEMBER(hsm_user_import, hui_gid);
+       CHECK_MEMBER(hsm_user_import, hui_mode);
+       CHECK_MEMBER(hsm_user_import, hui_atime);
+       CHECK_MEMBER(hsm_user_import, hui_atime_ns);
+       CHECK_MEMBER(hsm_user_import, hui_mtime);
+       CHECK_MEMBER(hsm_user_import, hui_mtime_ns);
+       CHECK_MEMBER(hsm_user_import, hui_archive_id);
+}
+
 static void check_update_buf(void)
 {
        BLANK_LINE();
@@ -2412,6 +2423,7 @@ main(int argc, char **argv)
        check_hsm_current_action();
        check_hsm_request();
        check_hsm_user_request();
+       check_hsm_user_import();
 
        check_update_buf();
        check_update_reply();
index 7b036e5..801dcd6 100644 (file)
@@ -4437,6 +4437,46 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_user_item) == 0, "found %lld\n",
                 (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_user_item));
 
+       /* Checks for struct hsm_user_import */
+       LASSERTF((int)sizeof(struct hsm_user_import) == 48, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_user_import));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_size) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_size));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_size) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_size));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_uid) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_uid));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_uid));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_gid) == 36, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_gid));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_gid));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mode) == 40, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mode));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mode) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mode));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_atime) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_atime));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_atime) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_atime));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_atime_ns) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_atime_ns));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_atime_ns) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_atime_ns));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mtime) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mtime));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mtime) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mtime));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_mtime_ns) == 28, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_mtime_ns));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_mtime_ns) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_mtime_ns));
+       LASSERTF((int)offsetof(struct hsm_user_import, hui_archive_id) == 44, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_user_import, hui_archive_id));
+       LASSERTF((int)sizeof(((struct hsm_user_import *)0)->hui_archive_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_user_import *)0)->hui_archive_id));
+
        /* Checks for struct update_buf */
        LASSERTF((int)sizeof(struct update_buf) == 8, "found %lld\n",
                 (long long)(int)sizeof(struct update_buf));