mfs: restore readonly mounting
. use dirty marking hooks to check and warn when inodes/bufs are marked dirty on a readonly mounted fs . add readonly mount checks to restore readonly mounting Signed-off-by: Ben Gras <ben@minix3.org>
This commit is contained in:
parent
9b7d357ca1
commit
9a664b4984
@ -2,7 +2,7 @@
|
||||
#ifndef _MFS_CLEAN_H
|
||||
#define _MFS_CLEAN_H 1
|
||||
|
||||
#define MARKDIRTY(b) ((b)->b_dirt = BP_DIRTY)
|
||||
#define MARKDIRTY(b) do { if(superblock.s_dev == (b)->b_dev && superblock.s_rd_only) { printf("%s:%d: dirty block on rofs! ", __FILE__, __LINE__); util_stacktrace(); } else { (b)->b_dirt = BP_DIRTY; } } while(0)
|
||||
#define MARKCLEAN(b) ((b)->b_dirt = BP_CLEAN)
|
||||
|
||||
#define ISDIRTY(b) ((b)->b_dirt == BP_DIRTY)
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include "super.h"
|
||||
|
||||
EXTERN struct inode {
|
||||
u16_t i_mode; /* file type, protection, etc. */
|
||||
u16_t i_nlinks; /* how many links to this file */
|
||||
@ -63,7 +65,7 @@ EXTERN unsigned int inode_cache_miss;
|
||||
#define ISEEK 1 /* i_seek = ISEEK if last op was SEEK */
|
||||
|
||||
#define IN_MARKCLEAN(i) i->i_dirt = IN_CLEAN
|
||||
#define IN_MARKDIRTY(i) i->i_dirt = IN_DIRTY
|
||||
#define IN_MARKDIRTY(i) do { if(i->i_sp->s_rd_only) { printf("%s:%d: dirty inode on rofs ", __FILE__, __LINE__); util_stacktrace(); } else { i->i_dirt = IN_DIRTY; } } while(0)
|
||||
|
||||
#define IN_ISCLEAN(i) i->i_dirt == IN_CLEAN
|
||||
#define IN_ISDIRTY(i) i->i_dirt == IN_DIRTY
|
||||
|
@ -148,8 +148,10 @@ PUBLIC int fs_unlink()
|
||||
return(r);
|
||||
}
|
||||
|
||||
if(rip->i_sp->s_rd_only) {
|
||||
r = EROFS;
|
||||
} else if(fs_m_in.m_type == REQ_UNLINK) {
|
||||
/* Now test if the call is allowed, separately for unlink() and rmdir(). */
|
||||
if(fs_m_in.m_type == REQ_UNLINK) {
|
||||
/* Only the su may unlink directories, but the su can unlink any
|
||||
* dir.*/
|
||||
if( (rip->i_mode & I_TYPE) == I_DIRECTORY) r = EPERM;
|
||||
@ -496,14 +498,18 @@ PUBLIC int fs_ftrunc(void)
|
||||
if( (rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
start = fs_m_in.REQ_TRC_START_LO;
|
||||
end = fs_m_in.REQ_TRC_END_LO;
|
||||
if(rip->i_sp->s_rd_only) {
|
||||
r = EROFS;
|
||||
} else {
|
||||
start = fs_m_in.REQ_TRC_START_LO;
|
||||
end = fs_m_in.REQ_TRC_END_LO;
|
||||
|
||||
if (end == 0)
|
||||
if (end == 0)
|
||||
r = truncate_inode(rip, start);
|
||||
else
|
||||
else
|
||||
r = freesp_inode(rip, start, end);
|
||||
|
||||
}
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
@ -494,6 +494,9 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||
if ( (ldir_ptr->i_mode & I_TYPE) != I_DIRECTORY) {
|
||||
return(ENOTDIR);
|
||||
}
|
||||
|
||||
if((flag == DELETE || flag == ENTER) && ldir_ptr->i_sp->s_rd_only)
|
||||
return EROFS;
|
||||
|
||||
r = OK;
|
||||
|
||||
|
@ -21,6 +21,11 @@ PUBLIC int fs_chmod()
|
||||
/* Temporarily open the file. */
|
||||
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
if(rip->i_sp->s_rd_only) {
|
||||
put_inode(rip);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
/* Now make the change. Clear setgid bit if file is not in caller's grp */
|
||||
rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
|
||||
|
@ -62,7 +62,11 @@ PUBLIC int fs_readwrite(void)
|
||||
|
||||
rdwt_err = OK; /* set to EIO if disk error occurs */
|
||||
|
||||
/* If this is file i/o, check we can write */
|
||||
if (rw_flag == WRITING && !block_spec) {
|
||||
if(rip->i_sp->s_rd_only)
|
||||
return EROFS;
|
||||
|
||||
/* Check in advance to see if file will grow too big. */
|
||||
if (position > (off_t) (rip->i_sp->s_max_size - nrbytes))
|
||||
return(EFBIG);
|
||||
@ -73,6 +77,11 @@ PUBLIC int fs_readwrite(void)
|
||||
*/
|
||||
if(position > f_size) clear_zone(rip, f_size, 0);
|
||||
}
|
||||
|
||||
/* If this is block i/o, check we can write */
|
||||
if(block_spec && rw_flag == WRITING &&
|
||||
(dev_t) rip->i_zone[0] == superblock.s_dev && superblock.s_rd_only)
|
||||
return EROFS;
|
||||
|
||||
cum_io = 0;
|
||||
/* Split the transfer into chunks that don't span two blocks. */
|
||||
@ -114,7 +123,10 @@ PUBLIC int fs_readwrite(void)
|
||||
if (rdwt_err != OK) r = rdwt_err; /* check for disk error */
|
||||
if (rdwt_err == END_OF_FILE) r = OK;
|
||||
|
||||
if (r == OK) {
|
||||
/* even on a ROFS, writing to a device node on it is fine,
|
||||
* just don't update the inode stats for it. And dito for reading.
|
||||
*/
|
||||
if (r == OK && !rip->i_sp->s_rd_only) {
|
||||
if (rw_flag == READING) rip->i_update |= ATIME;
|
||||
if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
|
||||
IN_MARKDIRTY(rip); /* inode is thus now dirty */
|
||||
@ -136,11 +148,14 @@ PUBLIC int fs_breadwrite(void)
|
||||
u64_t position;
|
||||
unsigned int off, cum_io, chunk, block_size;
|
||||
size_t nrbytes;
|
||||
dev_t target_dev;
|
||||
|
||||
/* Pseudo inode for rw_chunk */
|
||||
struct inode rip;
|
||||
|
||||
r = OK;
|
||||
|
||||
target_dev = (dev_t) fs_m_in.REQ_DEV2;
|
||||
|
||||
/* Get the values from the request message */
|
||||
rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
|
||||
@ -149,9 +164,13 @@ PUBLIC int fs_breadwrite(void)
|
||||
(unsigned long) fs_m_in.REQ_SEEK_POS_HI);
|
||||
nrbytes = (size_t) fs_m_in.REQ_NBYTES;
|
||||
|
||||
block_size = get_block_size( (dev_t) fs_m_in.REQ_DEV2);
|
||||
block_size = get_block_size(target_dev);
|
||||
|
||||
rip.i_zone[0] = (zone_t) fs_m_in.REQ_DEV2;
|
||||
/* Don't block-write to a RO-mounted filesystem. */
|
||||
if(superblock.s_dev == target_dev && superblock.s_rd_only)
|
||||
return EROFS;
|
||||
|
||||
rip.i_zone[0] = (zone_t) target_dev;
|
||||
rip.i_mode = I_BLOCK_SPECIAL;
|
||||
rip.i_size = 0;
|
||||
|
||||
@ -642,8 +661,10 @@ PUBLIC int fs_getdents(void)
|
||||
else {
|
||||
fs_m_out.RES_NBYTES = userbuf_off;
|
||||
fs_m_out.RES_SEEK_POS_LO = new_pos;
|
||||
rip->i_update |= ATIME;
|
||||
IN_MARKDIRTY(rip);
|
||||
if(!rip->i_sp->s_rd_only) {
|
||||
rip->i_update |= ATIME;
|
||||
IN_MARKDIRTY(rip);
|
||||
}
|
||||
r = OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user