return -EPERM;
/* b10667: ignore lustre special xattr for now */
- if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
- (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
- RETURN(0);
+ if (strcmp(name, XATTR_NAME_HSM) == 0 ||
+ (xattr_type == XATTR_TRUSTED_T &&
+ strcmp(name, XATTR_NAME_LOV) == 0) ||
+ (xattr_type == XATTR_LUSTRE_T &&
+ strcmp(name, "lustre.lov") == 0))
+ RETURN(0);
/* b15587: ignore security.capability xattr for now */
if ((xattr_type == XATTR_SECURITY_T &&
RETURN(0);
}
+static int get_hsm_state(struct inode *inode, __u32 *hus_states)
+{
+ struct md_op_data *op_data;
+ struct hsm_user_state *hus;
+ int rc;
+
+ OBD_ALLOC_PTR(hus);
+ if (hus == NULL)
+ return -ENOMEM;
+
+ op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+ LUSTRE_OPC_ANY, hus);
+ if (!IS_ERR(op_data)) {
+ rc = obd_iocontrol(LL_IOC_HSM_STATE_GET, ll_i2mdexp(inode),
+ sizeof(*op_data), op_data, NULL);
+ if (rc == 0)
+ *hus_states = hus->hus_states;
+ else
+ CDEBUG(D_VFSTRACE, "obd_iocontrol failed. rc = %d\n",
+ rc);
+
+ ll_finish_md_op_data(op_data);
+ } else {
+ rc = PTR_ERR(op_data);
+ CDEBUG(D_VFSTRACE, "Could not prepare the opdata. rc = %d\n",
+ rc);
+ }
+ OBD_FREE_PTR(hus);
+ return rc;
+}
+
int ll_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
- if ((strncmp(name, XATTR_TRUSTED_PREFIX,
- sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
- (strncmp(name, XATTR_LUSTRE_PREFIX,
- sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
+ if ((strncmp(name, XATTR_TRUSTED_PREFIX,
+ sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
+ strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
+ (strncmp(name, XATTR_LUSTRE_PREFIX,
+ sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
+ strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
struct lov_user_md *lump = (struct lov_user_md *)value;
- int rc = 0;
-
- /* Attributes that are saved via getxattr will always have
- * the stripe_offset as 0. Instead, the MDS should be
- * allowed to pick the starting OST index. b=17846 */
- if (lump != NULL && lump->lmm_stripe_offset == 0)
- lump->lmm_stripe_offset = -1;
+ int rc = 0;
+
+ /* Attributes that are saved via getxattr will always have
+ * the stripe_offset as 0. Instead, the MDS should be
+ * allowed to pick the starting OST index. b=17846 */
+ if (lump != NULL && lump->lmm_stripe_offset == 0)
+ lump->lmm_stripe_offset = -1;
+ /* Avoid anyone directly setting the RELEASED flag. */
+ if (lump != NULL &&
+ (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) {
+ /* Only if we have a released flag check if the file
+ * was indeed archived. */
+ __u32 state = HS_NONE;
+ rc = get_hsm_state(inode, &state);
+ if (rc != 0)
+ RETURN(rc);
+ if (!(state & HS_ARCHIVED)) {
+ CDEBUG(D_VFSTRACE,
+ "hus_states state = %x, pattern = %x\n",
+ state, lump->lmm_pattern);
+ /* Here the state is: real file is not
+ * archived but user is requesting to set
+ * the RELEASED flag so we mask off the
+ * released flag from the request */
+ lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
+ }
+ }
if (lump != NULL && S_ISREG(inode->i_mode)) {
struct file 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
+ while ! $LFS hsm_state $f | grep released; do
+ sleep 1
+ done
tar -cf $TMP/$tfile.tar $DIR/$tdir || error "cannot tar $DIR/$tdir"
}
run_test 24e "tar succeeds on HSM released files" # LU-6213
+test_24f() {
+
+ # test needs a running copytool
+ copytool_setup
+
+ mkdir -p $DIR/$tdir/d1
+ local f=$DIR/$tdir/$tfile
+ local fid=$(copy_file /etc/hosts $f)
+ sum0=$(md5sum $f)
+ echo $sum0
+ $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
+ error "hsm_archive failed"
+ wait_request_state $fid ARCHIVE SUCCEED
+ $LFS hsm_release $f || error "cannot release $f"
+ tar --xattrs -cvf $f.tar -C $DIR/$tdir $tfile
+ rm -f $f
+ sync
+ tar --xattrs -xvf $f.tar -C $DIR/$tdir ||
+ error "Can not recover the tar contents"
+ sum1=$(md5sum $f)
+ echo "Sum0 = $sum0, sum1 = $sum1"
+ [ "$sum0" == "$sum1" ] || error "md5sum mismatch for '$tfile'"
+
+ copytool_cleanup
+}
+run_test 24f "root can archive, release, and restore tar files"
+
test_25a() {
# test needs a running copytool
copytool_setup