#define DOSTID LPX64":"LPU64
#define POSTID(oi) ostid_seq(oi), ostid_id(oi)
+struct ll_futimes_3 {
+ __u64 lfu_atime_sec;
+ __u64 lfu_atime_nsec;
+ __u64 lfu_mtime_sec;
+ __u64 lfu_mtime_nsec;
+ __u64 lfu_ctime_sec;
+ __u64 lfu_ctime_nsec;
+};
+
/*
* The ioctl naming rules:
* LL_* - works on the currently opened filehandle instead of parent dir
#define LL_IOC_PATH2FID _IOR ('f', 173, long)
#define LL_IOC_GET_CONNECT_FLAGS _IOWR('f', 174, __u64 *)
#define LL_IOC_GET_MDTIDX _IOR ('f', 175, int)
+#define LL_IOC_FUTIMES_3 _IOWR('f', 176, struct ll_futimes_3)
/* lustre_ioctl.h 177-210 */
#define LL_IOC_HSM_STATE_GET _IOR('f', 211, struct hsm_user_state)
#define LL_IOC_HSM_STATE_SET _IOW('f', 212, struct hsm_state_set)
#define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data)
#define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE)
#define OBD_IOC_STOP_LFSCK _IOW ('f', 231, OBD_IOC_DATA_TYPE)
-/* lustre/lustre_user.h 240-246 */
+/* lustre/lustre_user.h 240-249 */
/* LIBCFS_IOC_DEBUG_MASK 250 */
#define IOC_OSC_SET_ACTIVE _IOWR('h', 21, void *)
((fmode & FMODE_WRITE) ? LL_LEASE_WRLCK : 0);
}
+static int ll_file_futimes_3(struct file *file, const struct ll_futimes_3 *lfu)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct iattr ia = {
+ .ia_valid = ATTR_ATIME | ATTR_ATIME_SET |
+ ATTR_MTIME | ATTR_MTIME_SET |
+ ATTR_CTIME | ATTR_CTIME_SET,
+ .ia_atime = {
+ .tv_sec = lfu->lfu_atime_sec,
+ .tv_nsec = lfu->lfu_atime_nsec,
+ },
+ .ia_mtime = {
+ .tv_sec = lfu->lfu_mtime_sec,
+ .tv_nsec = lfu->lfu_mtime_nsec,
+ },
+ .ia_ctime = {
+ .tv_sec = lfu->lfu_ctime_sec,
+ .tv_nsec = lfu->lfu_ctime_nsec,
+ },
+ };
+ int rc;
+ ENTRY;
+
+ if (!capable(CAP_SYS_ADMIN))
+ RETURN(-EPERM);
+
+ if (!S_ISREG(inode->i_mode))
+ RETURN(-EINVAL);
+
+ mutex_lock(&inode->i_mutex);
+ rc = ll_setattr_raw(file->f_dentry, &ia, false);
+ mutex_unlock(&inode->i_mutex);
+
+ RETURN(rc);
+}
+
static long
ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
OBD_FREE_PTR(hui);
RETURN(rc);
}
+ case LL_IOC_FUTIMES_3: {
+ struct ll_futimes_3 lfu;
+
+ if (copy_from_user(&lfu,
+ (const struct ll_futimes_3 __user *)arg,
+ sizeof(lfu)))
+ RETURN(-EFAULT);
+ RETURN(ll_file_futimes_3(file, &lfu));
+ }
default: {
int err;
}
/* We mark all of the fields "set" so MDS/OST does not re-set them */
- if (attr->ia_valid & ATTR_CTIME) {
+ if (!(attr->ia_valid & ATTR_CTIME_SET) &&
+ (attr->ia_valid & ATTR_CTIME)) {
attr->ia_ctime = CFS_CURRENT_TIME;
attr->ia_valid |= ATTR_CTIME_SET;
}
if (attr->ia_valid & (ATTR_SIZE |
ATTR_ATIME | ATTR_ATIME_SET |
- ATTR_MTIME | ATTR_MTIME_SET)) {
+ ATTR_MTIME | ATTR_MTIME_SET |
+ ATTR_CTIME | ATTR_CTIME_SET)) {
/* For truncate and utimes sending attributes to OSTs, setting
* mtime/atime to the past will be performed under PW [0:EOF]
* extent lock (new_size:EOF for truncate). It may seem
[ $mtime0 -eq $mtime1 ] ||
error "restore changed mtime from $mtime0 to $mtime1"
- [ $ctime0 -le $ctime1 ] ||
+ [ $ctime0 -eq $ctime1 ] ||
error "restore changed ctime from $ctime0 to $ctime1"
copytool_cleanup
[ $mtime0 -eq $mtime1 ] ||
error "remount changed mtime from $mtime0 to $mtime1"
- [ $ctime0 -le $ctime1 ] ||
+ [ $ctime0 -eq $ctime1 ] ||
error "remount changed ctime from $ctime0 to $ctime1"
}
run_test 24a "Archive, release, and restore does not change a/mtime (i/o)"
}
run_test 24d "check that read-only mounts are respected"
+test_24e() {
+ copytool_setup
+
+ mkdir -p $DIR/$tdir
+
+ local f=$DIR/$tdir/$tfile
+ local fid
+
+ fid=$(make_small $f) || error "cannot create $f"
+ $LFS hsm_archive $f || error "cannot archive $f"
+ wait_request_state $fid ARCHIVE SUCCEED
+ $LFS hsm_release $f || error "cannot release $f"
+ sleep 5
+
+ tar -cf $TMP/$tfile.tar $DIR/$tdir || error "cannot tar $DIR/$tdir"
+
+ copytool_cleanup
+}
+run_test 24e "tar succeeds on HSM released files" # LU-6213
+
test_25a() {
# test needs a running copytool
copytool_setup
hai = &hcp->copy.hc_hai;
if (hai->hai_action == HSMA_RESTORE && errval == 0) {
- struct timeval tv[2];
-
- /* Set {a,m}time of volatile file to that of original. */
- tv[0].tv_sec = hcp->stat.st_atime;
- tv[0].tv_usec = 0;
- tv[1].tv_sec = hcp->stat.st_mtime;
- tv[1].tv_usec = 0;
- if (futimes(hcp->data_fd, tv) < 0) {
+ struct ll_futimes_3 lfu = {
+ .lfu_atime_sec = hcp->stat.st_atim.tv_sec,
+ .lfu_atime_nsec = hcp->stat.st_atim.tv_nsec,
+ .lfu_mtime_sec = hcp->stat.st_mtim.tv_sec,
+ .lfu_mtime_nsec = hcp->stat.st_mtim.tv_nsec,
+ .lfu_ctime_sec = hcp->stat.st_ctim.tv_sec,
+ .lfu_ctime_nsec = hcp->stat.st_ctim.tv_nsec,
+ };
+
+ /* Set {a,m,c}time of volatile file to that of original. */
+ if (ioctl(hcp->data_fd, LL_IOC_FUTIMES_3, &lfu) < 0) {
errval = -errno;
goto end;
}