+ else
+ {
+ inode_close (inode);
+ free (file);
+ return NULL;
+ }
+}
+
+/* Opens and returns a new file for the same inode as FILE.
+ Returns a null pointer if unsuccessful. */
+struct file *
+file_reopen (struct file *file)
+{
+ return file_open (inode_reopen (file->inode));
+}
+
+/* Closes FILE. */
+void
+file_close (struct file *file)
+{
+ if (file != NULL)
+ {
+ file_allow_write (file);
+ inode_close (file->inode);
+ free (file);
+ }
+}
+
+/* Returns the inode encapsulated by FILE. */
+struct inode *
+file_get_inode (struct file *file)
+{
+ return file->inode;
+}
+
+/* Reads SIZE bytes from FILE into BUFFER,
+ starting at the file's current position.
+ Returns the number of bytes actually read,
+ which may be less than SIZE if end of file is reached.
+ Advances FILE's position by the number of bytes read. */
+off_t
+file_read (struct file *file, void *buffer, off_t size)
+{
+ off_t bytes_read = inode_read_at (file->inode, buffer, size, file->pos);
+ file->pos += bytes_read;
+ return bytes_read;
+}
+
+/* Reads SIZE bytes from FILE into BUFFER,
+ starting at offset FILE_OFS in the file.
+ Returns the number of bytes actually read,
+ which may be less than SIZE if end of file is reached.
+ The file's current position is unaffected. */
+off_t
+file_read_at (struct file *file, void *buffer, off_t size, off_t file_ofs)
+{
+ return inode_read_at (file->inode, buffer, size, file_ofs);