From: jcl Date: Wed, 20 Feb 2013 10:18:23 +0000 (+0100) Subject: LU-3363 api: HSM import uses new released pattern X-Git-Tag: 2.4.90~29 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=d39b08def6512ee6ae883a0db62cebd808646208;ds=sidebyside LU-3363 api: HSM import uses new released pattern 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 Change-Id: I39103e6f90bd73dc09cde49086d223d717e41cd2 Reviewed-on: http://review.whamcloud.com/6536 Tested-by: Hudson Reviewed-by: Andreas Dilger Reviewed-by: Jinshan Xiong Tested-by: Maloo --- diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1 index 7db5642..8a976e6 100644 --- a/lustre/doc/lfs.1 +++ b/lustre/doc/lfs.1 @@ -23,6 +23,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the \fB[[!] --stripe-count|-c [+-]] \fB[[!] --stripe-index|-i ] \fB[[!] --stripe-size|-S [+-]N[kMG]] + \fB[[!] --layout|-L raid0,released] \fB[--type |-t {bcdflpsD}] [[!] --gid|-g|--group|-G |] \fB[[!] --uid|-u|--user|-U |] [[!] --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 ] [--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] ...\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 ] [--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 ] \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. diff --git a/lustre/doc/llapi_hsm_state_get.3 b/lustre/doc/llapi_hsm_state_get.3 index 70bf4055..b69c22c 100644 --- a/lustre/doc/llapi_hsm_state_get.3 +++ b/lustre/doc/llapi_hsm_state_get.3 @@ -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 .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) diff --git a/lustre/doc/llapi_hsm_state_set.3 b/lustre/doc/llapi_hsm_state_set.3 index 1d2e83c..b7b8841 100644 --- a/lustre/doc/llapi_hsm_state_set.3 +++ b/lustre/doc/llapi_hsm_state_set.3 @@ -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 @@ -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) diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 952c264..36fbce9 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -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 diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 2639733..880189d 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -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); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 361bec1..8c06a27 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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: { diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index e827f01..b7113c5 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 1eec9a6..3623dbd 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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, diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 1eee9bc..4ee8feb 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -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)); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index fcf5f72..3a141d9 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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" diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 582c9e7..9e85a66 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -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 ] [--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" - " ..."}, + " [--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" + " ..."}, {"setdirstripe", lfs_setdirstripe, 0, "To create a remote directory on a specified MDT.\n" "usage: setdirstripe <--index|-i mdt_index> \n" @@ -188,6 +189,7 @@ command_t cmdlist[] = { " [[!] --stripe-size|-S [+-]N[kMGT]] [[!] --type|-t ]\n" " [[!] --gid|-g|--group|-G |]\n" " [[!] --uid|-u|--user|-U |] [[!] --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(¶m.layout, optarg); + if (ret) + goto err; + param.exclude_layout = !!neg_opt; + param.check_layout = 1; + break; case 'u': case 'U': ret = name2id(¶m.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; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 4a94d1b..818d54c 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -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)) diff --git a/lustre/utils/liblustreapi_hsm.c b/lustre/utils/liblustreapi_hsm.c index 695c0bc..5d08949 100644 --- a/lustre/utils/liblustreapi_hsm.c +++ b/lustre/utils/liblustreapi_hsm.c @@ -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. diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index b845d0c..52155e2 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -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(); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 7b036e5..801dcd6 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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));