/*
* check if layout swapping between 2 objects is allowed
* the rules are:
+ * - only normal FIDs or non-system IGIFs
* - same type of objects
* - same owner/group (so quotas are still valid)
*/
fid1 = mdo2fid(o1);
fid2 = mdo2fid(o2);
- if (!fid_is_norm(fid1) || !fid_is_norm(fid2) ||
- (mdd_object_type(o1) != mdd_object_type(o2)))
- RETURN(-EPERM);
+ if (!fid_is_norm(fid1) &&
+ (!fid_is_igif(fid1) || IS_ERR(mdd_links_get(env, o1))))
+ RETURN(-EBADF);
+
+ if (!fid_is_norm(fid2) &&
+ (!fid_is_igif(fid2) || IS_ERR(mdd_links_get(env, o2))))
+ RETURN(-EBADF);
+
+ if (mdd_object_type(o1) != mdd_object_type(o2)) {
+ if (S_ISDIR(mdd_object_type(o1)))
+ RETURN(-ENOTDIR);
+ if (S_ISREG(mdd_object_type(o1)))
+ RETURN(-EISDIR);
+ RETURN(-EBADF);
+ }
if ((attr1->la_uid != attr2->la_uid) ||
(attr1->la_gid != attr2->la_gid))
__u64 rpos, wpos, bufoff;
int gid = 0, sz;
int have_gl = 0;
+ struct stat st, stv;
/* find the right size for the IO and allocate the buffer */
lumsz = lov_user_md_size(LOV_MAX_STRIPE_COUNT, LOV_USER_MAGIC_V3);
goto free;
}
+ /* Not-owner (root?) special case.
+ * Need to set owner/group of volatile file like original.
+ * This will allow to pass related check during layout_swap.
+ */
+ rc = fstat(fd, &st);
+ if (rc != 0) {
+ rc = -errno;
+ fprintf(stderr, "cannot stat %s (%s)\n", name,
+ strerror(errno));
+ goto error;
+ }
+ rc = fstat(fdv, &stv);
+ if (rc != 0) {
+ rc = -errno;
+ fprintf(stderr, "cannot stat %s (%s)\n", volatile_file,
+ strerror(errno));
+ goto error;
+ }
+ if (st.st_uid != stv.st_uid || st.st_gid != stv.st_gid) {
+ rc = fchown(fdv, st.st_uid, st.st_gid);
+ if (rc != 0) {
+ rc = -errno;
+ fprintf(stderr, "cannot chown %s (%s)\n", name,
+ strerror(errno));
+ goto error;
+ }
+ }
+
/* get file data version */
rc = llapi_get_data_version(fd, &dv1, LL_DV_RD_FLUSH);
if (rc != 0) {