Filesystem: Don't store lock length of Infinity

Infinity is not JSON.stringifiable and will turn into null during state
save and restore.
This commit is contained in:
Ernest Wong 2018-09-07 14:13:43 +12:00 committed by Fabian
commit 2bac2198e8

View file

@ -1745,6 +1745,24 @@ FSLockRegion.prototype.clone = function()
return new_region;
};
/**
* Handle special interpretation of length of 0.
* @return {number}
*/
FSLockRegion.prototype.get_length = function()
{
return this.length === 0 ? Infinity : this.length;
};
/**
* Handle special interpretation of length of 0.
* @param {number} length
*/
FSLockRegion.prototype.set_length = function(length)
{
this.length = length === Infinity ? 0 : length;
};
/**
* @param {FSLockRegion} region
* @return {boolean}
@ -1754,8 +1772,8 @@ FSLockRegion.prototype.conflicts_with = function(region)
if(this.proc_id === region.proc_id && this.client_id === region.client_id) return false;
if(this.type === P9_LOCK_TYPE_UNLCK || region.type === P9_LOCK_TYPE_UNLCK) return false;
if(this.type !== P9_LOCK_TYPE_WRLCK && region.type !== P9_LOCK_TYPE_WRLCK) return false;
if(this.start + this.length <= region.start) return false;
if(region.start + region.length <= this.start) return false;
if(this.start + this.get_length() <= region.start) return false;
if(region.start + region.get_length() <= this.start) return false;
return true;
};
@ -1776,7 +1794,7 @@ FSLockRegion.prototype.is_alike = function(region)
*/
FSLockRegion.prototype.may_merge_after = function(region)
{
return this.is_alike(region) && region.start + region.length === this.start;
return this.is_alike(region) && region.start + region.get_length() === this.start;
};
/**
@ -1799,8 +1817,7 @@ FS.prototype.DescribeLock = function(type, start, length, proc_id, client_id)
const lock = new FSLockRegion();
lock.type = type;
lock.start = start;
// Internally represent length of '0' as infinity.
lock.length = length === 0 ? Infinity : length;
lock.set_length(length);
lock.proc_id = proc_id;
lock.client_id = client_id;
@ -1826,10 +1843,7 @@ FS.prototype.GetLock = function(id, request)
{
if(request.conflicts_with(region))
{
const ret = region.clone();
// Convert internal representation of '0' back.
ret.length = ret.length === Infinity ? 0 : ret.length;
return ret;
return region.clone();
}
}
return null;
@ -1864,18 +1878,18 @@ FS.prototype.Lock = function(id, request, flags)
{
const region = inode.locks[i];
dbg_assert(region.length > 0,
"Filesystem: Found non-positive lock region length: " + region.length);
dbg_assert(region.get_length() > 0,
"Filesystem: Found non-positive lock region length: " + region.get_length());
dbg_assert(region.type === P9_LOCK_TYPE_RDLCK || region.type === P9_LOCK_TYPE_WRLCK,
"Filesystem: Found invalid lock type: " + region.type);
dbg_assert(!inode.locks[i-1] || inode.locks[i-1].start <= region.start,
"Filesystem: Locks should be sorted by starting offset");
// Skip to requested region.
if(region.start + region.length <= request.start) continue;
if(region.start + region.get_length() <= request.start) continue;
// Check whether we've skipped past the requested region.
if(request.start + request.length <= region.start) break;
if(request.start + request.get_length() <= region.start) break;
// Skip over locks of different owners.
if(region.proc_id !== request.proc_id || region.client_id !== request.client_id)
@ -1887,9 +1901,9 @@ FS.prototype.Lock = function(id, request, flags)
// Pretend region would be split into parts 1 and 2.
const start1 = region.start;
const start2 = request.start + request.length;
const start2 = request.start + request.get_length();
const length1 = request.start - start1;
const length2 = region.start + region.length - start2;
const length2 = region.start + region.get_length() - start2;
if(length1 > 0 && length2 > 0 && region.type === request.type)
{
@ -1901,14 +1915,14 @@ FS.prototype.Lock = function(id, request, flags)
if(length1 > 0)
{
// Shrink from right / first half of the split.
region.length = length1;
region.set_length(length1);
}
if(length1 <= 0 && length2 > 0)
{
// Shrink from left.
region.start = start2;
region.length = length2;
region.set_length(length2);
}
else if(length2 > 0)
{
@ -1942,7 +1956,7 @@ FS.prototype.Lock = function(id, request, flags)
{
if(new_region.may_merge_after(inode.locks[i]))
{
inode.locks[i].length += request.length;
inode.locks[i].set_length(inode.locks[i].get_length() + request.get_length());
new_region = inode.locks[i];
has_merged = true;
}
@ -1962,7 +1976,7 @@ FS.prototype.Lock = function(id, request, flags)
if(inode.locks[i].may_merge_after(new_region))
{
new_region.length += inode.locks[i].length;
new_region.set_length(new_region.get_length() + inode.locks[i].get_length());
inode.locks.splice(i, 1);
}