mirror of
https://github.com/schoebel/mars
synced 2024-12-11 09:15:48 +00:00
infra: new timestamp ordering
This commit is contained in:
parent
db486fb6cd
commit
dedaa5b55f
@ -192,6 +192,11 @@ extern int mars_chmod(const char *path, mode_t mode);
|
|||||||
extern int mars_lchown(const char *path, uid_t uid);
|
extern int mars_lchown(const char *path, uid_t uid);
|
||||||
extern void mars_remaining_space(const char *fspath, loff_t *total, loff_t *remaining);
|
extern void mars_remaining_space(const char *fspath, loff_t *total, loff_t *remaining);
|
||||||
|
|
||||||
|
/* Timestamp Ordering */
|
||||||
|
|
||||||
|
extern int ordered_unlink(const char *path, const struct timespec *stamp, int serial, int mode);
|
||||||
|
extern int ordered_symlink(const char *oldpath, const char *newpath, const struct timespec *stamp, uid_t uid);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern struct mars_global *mars_global;
|
extern struct mars_global *mars_global;
|
||||||
|
@ -851,6 +851,92 @@ err: ;
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mars_remaining_space);
|
EXPORT_SYMBOL_GPL(mars_remaining_space);
|
||||||
|
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
/* Timestamp Ordering */
|
||||||
|
|
||||||
|
/* Timestamp ordering (e.g. via Lamport Clock) is easy when
|
||||||
|
* the object exists.
|
||||||
|
* When unlink() comes into play, it becomes more complex:
|
||||||
|
* where to store the timestamp of the object when it is
|
||||||
|
* currently deleted?
|
||||||
|
* This is necessary to allow permutations between _all_ operations
|
||||||
|
* on the object, including unlink().
|
||||||
|
* Idea: use a substitute object ".deleted-$object".
|
||||||
|
*/
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(ordered_lock);
|
||||||
|
|
||||||
|
int ordered_unlink(const char *path, const struct timespec *stamp, int serial, int mode)
|
||||||
|
{
|
||||||
|
struct kstat stat;
|
||||||
|
char serial_str[32];
|
||||||
|
struct timespec now;
|
||||||
|
const char *marker_path;
|
||||||
|
int marker_status;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
snprintf(serial_str, sizeof(serial_str), "%d,%d", serial, mode);
|
||||||
|
if (!stamp) {
|
||||||
|
get_lamport(&now);
|
||||||
|
stamp = &now;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&ordered_lock);
|
||||||
|
|
||||||
|
marker_path = backskip_replace(path, '/', true, "/.deleted-");
|
||||||
|
marker_status = mars_stat(marker_path, &stat, true);
|
||||||
|
if (marker_status < 0 ||
|
||||||
|
timespec_compare(stamp, &stat.mtime) >= 0) {
|
||||||
|
MARS_DBG("creating / updating marker '%s' mtime=%lu.%09lu\n",
|
||||||
|
marker_path,
|
||||||
|
stamp->tv_sec, stamp->tv_nsec);
|
||||||
|
status = mars_symlink(serial_str, marker_path, stamp, 0);
|
||||||
|
}
|
||||||
|
if (marker_status < 0 ||
|
||||||
|
timespec_compare(stamp, &stat.mtime) >= 0) {
|
||||||
|
status = mars_unlink(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&ordered_lock);
|
||||||
|
brick_string_free(marker_path);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ordered_symlink(const char *oldpath, const char *newpath, const struct timespec *stamp, uid_t uid)
|
||||||
|
{
|
||||||
|
struct kstat stat;
|
||||||
|
struct timespec now;
|
||||||
|
const char *marker_path;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
if (!stamp) {
|
||||||
|
get_lamport(&now);
|
||||||
|
stamp = &now;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&ordered_lock);
|
||||||
|
|
||||||
|
marker_path = backskip_replace(newpath, '/', true, "/.deleted-");
|
||||||
|
|
||||||
|
if (mars_stat(marker_path, &stat, true) >= 0 &&
|
||||||
|
timespec_compare(&stat.mtime, stamp) > 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (mars_stat(newpath, &stat, true) >= 0 &&
|
||||||
|
timespec_compare(&stat.mtime, stamp) > 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)mars_unlink(marker_path);
|
||||||
|
status = mars_symlink(oldpath, newpath, stamp, uid);
|
||||||
|
|
||||||
|
done:
|
||||||
|
mutex_unlock(&ordered_lock);
|
||||||
|
brick_string_free(marker_path);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// thread binding
|
// thread binding
|
||||||
|
Loading…
Reference in New Issue
Block a user