summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-03-16 10:31:43 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-03-16 10:31:43 +0100
commit6b6af5c6dea1a6011d7e116e6e285111f033a34d (patch)
tree74a34e6b6fb4a4eb3b1cc7b21445416fa760459c
parentd2f11d48b29de49265f1a0d997548074f80fe431 (diff)
downloadpintos-6b6af5c6dea1a6011d7e116e6e285111f033a34d.tar.gz
lock inode with lock and data with rwlock
-rw-r--r--src/filesys/inode.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/filesys/inode.c b/src/filesys/inode.c
index b053019..dca5432 100644
--- a/src/filesys/inode.c
+++ b/src/filesys/inode.c
@@ -32,11 +32,14 @@ bytes_to_sectors (off_t size)
/* In-memory inode. */
struct inode
{
+ struct lock lock; /* Lock for inode metadata. */
struct list_elem elem; /* Element in inode list. */
disk_sector_t sector; /* Sector number of disk location. */
int open_cnt; /* Number of openers. */
bool removed; /* True if deleted, false otherwise. */
int deny_write_cnt; /* 0: writes ok, >0: deny writes. */
+
+ struct rwlock rwlock; /* RwLock for inode_disk data. */
struct inode_disk data; /* Inode content. */
};
@@ -141,13 +144,17 @@ inode_open (disk_sector_t sector)
}
/* Initialize. */
+ lock_init (&inode->lock);
+ lock_acquire (&inode->lock);
list_push_front (&open_inodes, &inode->elem);
+ lock_release (&open_inodes_lock);
inode->sector = sector;
inode->open_cnt = 1;
inode->deny_write_cnt = 0;
inode->removed = false;
- lock_release (&open_inodes_lock); // delayed unlock so no one can read the half-initialized inode
+ rwlock_init (&inode->rwlock);
disk_read (filesys_disk, inode->sector, &inode->data);
+ lock_release (&inode->lock);
return inode;
}
@@ -157,8 +164,10 @@ inode_reopen (struct inode *inode)
{
if (inode != NULL)
{
+ lock_acquire (&inode->lock);
ASSERT(inode->open_cnt != 0);
inode->open_cnt++;
+ lock_release (&inode->lock);
}
return inode;
}
@@ -180,9 +189,13 @@ inode_close (struct inode *inode)
if (inode == NULL)
return;
+ lock_acquire (&inode->lock);
+
/* Release resources if this was the last opener. */
- if (--inode->open_cnt == 0)
+ if (--inode->open_cnt > 0)
{
+ lock_release (&inode->lock);
+ } else {
/* Remove from inode list. */
lock_acquire (&open_inodes_lock);
list_remove (&inode->elem);
@@ -206,7 +219,9 @@ void
inode_remove (struct inode *inode)
{
ASSERT (inode != NULL);
+ lock_acquire (&inode->lock);
inode->removed = true;
+ lock_release (&inode->lock);
}
/* Reads SIZE bytes from INODE into BUFFER, starting at position OFFSET.
@@ -219,6 +234,8 @@ inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset)
off_t bytes_read = 0;
uint8_t *bounce = NULL;
+ rwlock_read_p (&inode->rwlock);
+
while (size > 0)
{
/* Disk sector to read, starting byte offset within sector. */
@@ -259,6 +276,8 @@ inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset)
offset += chunk_size;
bytes_read += chunk_size;
}
+
+ rwlock_read_v (&inode->rwlock);
free (bounce);
return bytes_read;
@@ -280,6 +299,8 @@ inode_write_at (struct inode *inode, const void *buffer_, off_t size,
if (inode->deny_write_cnt)
return 0;
+ rwlock_write_p (&inode->rwlock);
+
while (size > 0)
{
/* Sector to write, starting byte offset within sector. */
@@ -327,6 +348,8 @@ inode_write_at (struct inode *inode, const void *buffer_, off_t size,
offset += chunk_size;
bytes_written += chunk_size;
}
+
+ rwlock_write_v (&inode->rwlock);
free (bounce);
return bytes_written;
@@ -337,8 +360,10 @@ inode_write_at (struct inode *inode, const void *buffer_, off_t size,
void
inode_deny_write (struct inode *inode)
{
+ lock_acquire (&inode->lock);
inode->deny_write_cnt++;
ASSERT (inode->deny_write_cnt <= inode->open_cnt);
+ lock_release (&inode->lock);
}
/* Re-enables writes to INODE.
@@ -347,9 +372,11 @@ inode_deny_write (struct inode *inode)
void
inode_allow_write (struct inode *inode)
{
+ lock_acquire (&inode->lock);
ASSERT (inode->deny_write_cnt > 0);
ASSERT (inode->deny_write_cnt <= inode->open_cnt);
inode->deny_write_cnt--;
+ lock_release (&inode->lock);
}
/* Returns the length, in bytes, of INODE's data. */