return rc;
}
-/* TODO: Set the project ID for PCC copy */
-int pcc_inode_store_ugpid(struct dentry *dentry, kuid_t uid, kgid_t gid)
+/*
+ * Reset uid, gid or size for the PCC copy masked by @valid.
+ * TODO: Set the project ID for PCC copy.
+ */
+int pcc_inode_reset_iattr(struct dentry *dentry, unsigned int valid,
+ kuid_t uid, kgid_t gid, loff_t size)
{
struct inode *inode = dentry->d_inode;
struct iattr attr;
ENTRY;
- attr.ia_valid = ATTR_UID | ATTR_GID;
+ attr.ia_valid = valid;
attr.ia_uid = uid;
attr.ia_gid = gid;
+ attr.ia_size = size;
inode_lock(inode);
rc = notify_change(dentry, &attr, NULL);
if (pcci == NULL)
GOTO(out_put, rc = -ENOMEM);
- rc = pcc_inode_store_ugpid(pcc_dentry, old_cred->suid,
- old_cred->sgid);
+ rc = pcc_inode_reset_iattr(pcc_dentry, ATTR_UID | ATTR_GID,
+ old_cred->suid, old_cred->sgid, 0);
if (rc)
GOTO(out_put, rc);
return 0;
}
-static int pcc_copy_data(struct file *src, struct file *dst)
+static ssize_t pcc_copy_data(struct file *src, struct file *dst)
{
- int rc = 0;
+ ssize_t rc = 0;
ssize_t rc2;
loff_t pos, offset = 0;
size_t buf_len = 1048576;
RETURN(-ENOMEM);
while (1) {
+ if (signal_pending(current))
+ GOTO(out_free, rc = -EINTR);
+
pos = offset;
rc2 = cfs_kernel_read(src, buf, buf_len, &pos);
if (rc2 < 0)
offset += rc2;
}
+ rc = offset;
out_free:
OBD_FREE_LARGE(buf, buf_len);
RETURN(rc);
struct dentry *dentry;
struct file *pcc_filp;
struct path path;
+ ssize_t ret;
int rc;
ENTRY;
old_cred = override_creds(pcc_super_cred(inode->i_sb));
rc = __pcc_inode_create(dataset, &lli->lli_fid, &dentry);
- if (rc) {
- revert_creds(old_cred);
+ if (rc)
GOTO(out_dataset_put, rc);
- }
path.mnt = dataset->pccd_path.mnt;
path.dentry = dentry;
#ifdef HAVE_DENTRY_OPEN_USE_PATH
- pcc_filp = dentry_open(&path, O_TRUNC | O_WRONLY | O_LARGEFILE,
- current_cred());
+ pcc_filp = dentry_open(&path, O_WRONLY | O_LARGEFILE, current_cred());
#else
- pcc_filp = dentry_open(path.dentry, path.mnt,
- O_TRUNC | O_WRONLY | O_LARGEFILE,
+ pcc_filp = dentry_open(path.dentry, path.mnt, O_WRONLY | O_LARGEFILE,
current_cred());
#endif
if (IS_ERR_OR_NULL(pcc_filp)) {
rc = pcc_filp == NULL ? -EINVAL : PTR_ERR(pcc_filp);
- revert_creds(old_cred);
GOTO(out_dentry, rc);
}
- rc = pcc_inode_store_ugpid(dentry, old_cred->uid, old_cred->gid);
- revert_creds(old_cred);
+ rc = pcc_inode_reset_iattr(dentry, ATTR_UID | ATTR_GID,
+ old_cred->uid, old_cred->gid, 0);
if (rc)
GOTO(out_fput, rc);
- rc = pcc_copy_data(file, pcc_filp);
+ ret = pcc_copy_data(file, pcc_filp);
+ if (ret < 0)
+ GOTO(out_fput, rc = ret);
+
+ /*
+ * It must to truncate the PCC copy to the same size of the Lustre
+ * copy after copy data. Otherwise, it may get wrong file size after
+ * re-attach a file. See LU-13023 for details.
+ */
+ rc = pcc_inode_reset_iattr(dentry, ATTR_SIZE, KUIDT_INIT(0),
+ KGIDT_INIT(0), ret);
if (rc)
GOTO(out_fput, rc);
fput(pcc_filp);
out_dentry:
if (rc) {
- old_cred = override_creds(pcc_super_cred(inode->i_sb));
(void) pcc_inode_remove(inode, dentry);
- revert_creds(old_cred);
dput(dentry);
}
out_dataset_put:
pcc_dataset_put(dataset);
+ revert_creds(old_cred);
+
RETURN(rc);
}