struct linkea_data *ldata,
int first, int check)
{
- int rc2 = 0;
int rc = 0;
ENTRY;
rc = mdd_links_write(env, mdd_obj, ldata, handle);
EXIT;
out:
- if (rc == 0)
- rc = rc2;
- if (rc) {
+ if (rc != 0) {
int error = 1;
if (rc == -EOVERFLOW || rc == -ENOSPC)
error = 0;
const struct lu_fid *pfid,
const struct lu_name *lname,
struct thandle *handle,
- struct linkea_data *data, int first)
+ struct linkea_data *ldata, int first)
{
return mdd_links_rename(env, mdd_obj, NULL, NULL,
- pfid, lname, handle, data, first, 0);
+ pfid, lname, handle, ldata, first, 0);
}
static inline int mdd_links_del(const struct lu_env *env,
GOTO(out, rc);
}
- if (spec->sp_cr_flags & MDS_OPEN_VOLATILE) {
+ if (unlikely(spec->sp_cr_flags & MDS_OPEN_VOLATILE)) {
rc = orph_declare_index_insert(env, c, attr->la_mode, handle);
if (rc)
GOTO(out, rc);
rc = mdo_declare_attr_set(env, p, la, handle);
if (rc)
return rc;
- }
- rc = mdd_declare_changelog_store(env, mdd, name, handle);
- if (rc)
- return rc;
+ rc = mdd_declare_changelog_store(env, mdd, name, handle);
+ if (rc)
+ return rc;
+ }
/* XXX: For remote create, it should indicate the remote RPC
* will be sent after local transaction is finished, which
if (unlikely(spec->sp_cr_flags & MDS_OPEN_VOLATILE)) {
mdd_write_lock(env, son, MOR_TGT_CHILD);
rc = __mdd_orphan_add(env, son, handle);
- mdd_write_unlock(env, son);
- if (rc != 0)
- GOTO(err_created, rc);
+ GOTO(out_volatile, rc);
} else {
rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son),
name, S_ISDIR(attr->la_mode), handle,
mdd_write_lock(env, son, MOR_TGT_CHILD);
if (S_ISDIR(attr->la_mode)) {
/* Drop the reference, no need to delete "."/"..",
- * because the object to be destroied directly. */
+ * because the object is to be destroyed directly. */
rc2 = mdo_ref_del(env, son, handle);
if (rc2 != 0) {
mdd_write_unlock(env, son);
goto out_stop;
}
}
+out_volatile:
+ /* For volatile files drop one link immediately, since there is
+ * no filename in the namespace, and save any error returned. */
rc2 = mdo_ref_del(env, son, handle);
if (rc2 != 0) {
mdd_write_unlock(env, son);
+ if (unlikely(rc == 0))
+ rc = rc2;
goto out_stop;
}
- mdo_destroy(env, son, handle);
+ /* Don't destroy the volatile object on success */
+ if (likely(rc != 0))
+ mdo_destroy(env, son, handle);
mdd_write_unlock(env, son);
- }
+ }
- if (rc == 0 && fid_is_namespace_visible(mdo2fid(son)))
+ if (rc == 0 && fid_is_namespace_visible(mdo2fid(son)) &&
+ likely((spec->sp_cr_flags & MDS_OPEN_VOLATILE) == 0))
rc = mdd_changelog_ns_store(env, mdd,
- S_ISDIR(attr->la_mode) ? CL_MKDIR :
- S_ISREG(attr->la_mode) ? CL_CREATE :
- S_ISLNK(attr->la_mode) ? CL_SOFTLINK : CL_MKNOD,
- 0, son, mdd_pobj, lname, handle);
+ S_ISDIR(attr->la_mode) ? CL_MKDIR :
+ S_ISREG(attr->la_mode) ? CL_CREATE :
+ S_ISLNK(attr->la_mode) ? CL_SOFTLINK : CL_MKNOD,
+ 0, son, mdd_pobj, lname, handle);
out_stop:
rc2 = mdd_trans_stop(env, mdd, rc, handle);
if (rc == 0)
/* if we vmalloced a large buffer drop it */
lu_buf_free(ldata->ld_buf);
- /* The child object shouldn't be cached anymore */
- if (rc)
+ /* The child object shouldn't be cached anymore */
+ if (rc)
set_bit(LU_OBJECT_HEARD_BANSHEE,
- &child->mo_lu.lo_header->loh_flags);
- return rc;
+ &child->mo_lu.lo_header->loh_flags);
+ return rc;
}
/*
}
/*
- * Create a volatile file and open it for write:
- * - file is created as a standard file in the directory
- * - file does not appears in directory and directory mtime does not change
- * - file is removed at close
- * - file modes are rw-------, if user wants another one it must use fchmod()
- * \param directory Directory where the file is created
- * \param idx MDT index on which the file is created
- * \param open_flags Standard open flags
+ * Create a file without any name open it for read/write
+ *
+ * - file is created as if it were a standard file in the given \a directory
+ * - file does not appear in \a directory and mtime does not change because
+ * the filename is handled specially by the Lustre MDS.
+ * - file is removed at final close
+ * - file modes are rw------- since it doesn't make sense to have a read-only
+ * or write-only file that cannot be opened again.
+ * - if user wants another mode it must use fchmod() on the open file, no
+ * security problems arise because it cannot be opened by another process.
+ *
+ * \param[in] directory directory from which to inherit layout/MDT idx
+ * \param[in] idx MDT index on which the file is created,
+ * \a idx == -1 means no specific MDT is requested
+ * \param[in] open_flags standard open(2) flags
*
* \retval 0 on success.
* \retval -errno on error.
fd = open(file_path, O_RDWR | O_CREAT | open_flags, S_IRUSR | S_IWUSR);
if (fd < 0) {
llapi_error(LLAPI_MSG_ERROR, errno,
- "Cannot create volatile file %s in %s\n",
+ "Cannot create volatile file '%s' in '%s'\n",
filename + LUSTRE_VOLATILE_HDR_LEN,
directory);
return -errno;
}
+ /* unlink file in case this wasn't a Lustre filesystem, and the
+ * magic volatile filename wasn't handled as intended. The effect
+ * is the same. */
+ unlink(file_path);
+
return fd;
}