Messages in this thread Patch in this message | | | Date | Wed, 23 Jun 1999 14:29:52 +0200 | From | Janos Farkas <> | Subject | [patch] 2.3.8 romfs update |
| |
Hi!
With a bit guidance from Alexander Viro, here's a (tested) update of romfs for the 2.3.7+ (in fact some newer 2.2.x -- need to backport them) VFS changes, highlights (as an overview for what needs to be done for other fs'es, but just as a beginning):
- romfs_lookup() returns a negative dentry for non-existent filenames; instead of a "real" error. It seems to me, this is the most correct way to handle the traditional ENOENT case; although it should only matter for writable filesystems - romfs_readpage() updated to the new semantics, it's mostly straightforward, hopefully the lock_kernel()/unlock_kernel() is ok too. (AFAICS, readpage is at a much lower level that "normal" filesystems don't need to care about, but I do). The page->owner hack possibly can go away once the debugging is resolved? - 2.3.7+ inode_ops reorganization - romfs_read_inode() is a bit streamlined, and now uses the all new init_special_inode to create fifo/socket/device inodes, as per hints of Alexander. (Also the possibly finally correct way to generate a device number; maybe not, but it's working as one would expect).
The careful observer might note a few hundred bytes obesity in romfs resulting from this patch (although none of the changes should warrant bloat), and in general with 2.2/2.3 itself too. Perusal of the generated assembly however showed that the fat is coming only from the few new debugging hooks/printks, and the strings used by them, related to wait queues, and (page) locking. Once they get removed, we can talk about fat again :)
"Sadly", most of the page/buffer cache issues won't matter in this fs, so I can't provide another example of doing it :) BTW, it's mostly because of the "no page boundary" policy; which is not necessarily true, a future optimization of the user-space tool will lay out data differently, I guess I'll still need an special readpage to cope with the partial pages; the question is, how crazy is a scheme which allows the tail end of the file "float" to blocks reserved for slack, and even move when extending the file :)
BTW, modular loop.c needs __mark_buffer_dirty exported in (possibly) kernel/ksyms.c; and there are a lot of compile errors caused by locks hidden behind __SMP__ around the masquerading code, but used nevertheless..
diff -urpN linux-2.3.8-3-pre/fs/romfs/inode.c linux/fs/romfs/inode.c --- linux-2.3.8-3-pre/fs/romfs/inode.c Thu Jun 10 07:01:55 1999 +++ linux/fs/romfs/inode.c Wed Jun 23 06:24:25 1999 @@ -1,7 +1,7 @@ /* * ROMFS file system, Linux implementation * - * Copyright (C) 1997 Janos Farkas <chexum@shadow.banki.hu> + * Copyright (C) 1997-1999 Janos Farkas <chexum@shadow.banki.hu> * * Using parts of the minix filesystem * Copyright (C) 1991, 1992 Linus Torvalds @@ -57,6 +57,7 @@ #include <linux/fs.h> #include <linux/locks.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -320,7 +321,7 @@ romfs_lookup(struct inode *dir, struct d const char *name; /* got from dentry */ int len; - res = 0; /* instead of ENOENT */ + res = -EACCES; /* placeholder for "no data here" */ offset = dir->i_ino & ROMFH_MASK; if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) goto out; @@ -335,8 +336,9 @@ romfs_lookup(struct inode *dir, struct d len = dentry->d_name.len; for(;;) { - if (!offset || offset >= maxoff - || romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) + if (!offset || offset >= maxoff) + goto out0; + if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) goto out; /* try to match the first 16 bytes of name */ @@ -365,19 +367,28 @@ romfs_lookup(struct inode *dir, struct d if ((ntohl(ri.next) & ROMFH_TYPE) == ROMFH_HRD) offset = ntohl(ri.spec) & ROMFH_MASK; - if ((inode = iget(dir->i_sb, offset))==NULL) { - res = -EACCES; - } else { - d_add(dentry, inode); - } + if ((inode = iget(dir->i_sb, offset))) + goto outi; -out: - return ERR_PTR(res); + /* + * it's a bit funky, _lookup needs to return an error code + * (negative) or a NULL, both as a dentry. ENOENT should not + * be returned, instead we need to create a negative dentry by + * d_add(dentry, NULL); and return 0 as no error. + * (Although as I see, it only matters on writable file + * systems). + */ + +out0: inode = NULL; +outi: res = 0; + d_add (dentry, inode); + +out: return ERR_PTR(res); } /* * Ok, we do readpage, to be able to execute programs. Unfortunately, - * we can't use bmap, since we have looser alignments. + * we can't use bmap, since we may have looser alignments. */ static int @@ -389,12 +400,13 @@ romfs_readpage(struct file * file, struc unsigned long offset, avail, readlen; int result = -EIO; - atomic_inc(&page->count); - set_bit(PG_locked, &page->flags); - + lock_kernel(); + get_page(page); buf = page_address(page); - clear_bit(PG_uptodate, &page->flags); - clear_bit(PG_error, &page->flags); + + /* hack? */ + page->owner = (int)current; + offset = page->offset; if (offset < inode->i_size) { avail = inode->i_size-offset; @@ -403,18 +415,19 @@ romfs_readpage(struct file * file, struc if (readlen < PAGE_SIZE) { memset((void *)(buf+readlen),0,PAGE_SIZE-readlen); } - set_bit(PG_uptodate, &page->flags); + SetPageUptodate(page); result = 0; } } if (result) { - set_bit(PG_error, &page->flags); memset((void *)buf, 0, PAGE_SIZE); + SetPageError(page); } - clear_bit(PG_locked, &page->flags); - wake_up(&page->wait); + UnlockPage(page); + free_page(buf); + unlock_kernel(); return result; } @@ -508,12 +521,16 @@ static struct inode_operations romfs_fil NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ + + NULL, /* bmap -- not really */ romfs_readpage, /* readpage */ NULL, /* writepage */ - NULL, /* bmap -- not really */ + NULL, /* flushpage */ + NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* revalidate */ }; static struct file_operations romfs_dir_operations = { @@ -550,12 +567,16 @@ static struct inode_operations romfs_dir NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ + + NULL, /* bmap */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ + NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* revalidate */ }; static struct inode_operations romfs_link_inode_operations = { @@ -571,18 +592,22 @@ static struct inode_operations romfs_lin NULL, /* rename */ romfs_readlink, /* readlink */ romfs_follow_link, /* follow_link */ + + NULL, /* bmap */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ + NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ + NULL, /* revalidate */ }; static mode_t romfs_modemap[] = { - 0, S_IFDIR, S_IFREG, S_IFLNK+0777, - S_IFBLK, S_IFCHR, S_IFSOCK, S_IFIFO + 0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777, + S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644 }; static struct inode_operations *romfs_inoops[] = @@ -591,10 +616,10 @@ static struct inode_operations *romfs_in &romfs_dir_inode_operations, &romfs_file_inode_operations, &romfs_link_inode_operations, - &blkdev_inode_operations, /* standard handlers */ - &chrdev_inode_operations, - NULL, /* socket */ - NULL, /* fifo */ + NULL, /* device/fifo/socket nodes, */ + NULL, /* set by init_special_inode */ + NULL, + NULL, }; static void @@ -627,34 +652,30 @@ romfs_read_inode(struct inode *i) i->i_mtime = i->i_atime = i->i_ctime = 0; i->i_uid = i->i_gid = 0; - i->i_op = romfs_inoops[nextfh & ROMFH_TYPE]; - - /* Precalculate the data offset */ - ino = romfs_strnlen(i, ino+ROMFH_SIZE, ROMFS_MAXFN); - if (ino >= 0) - ino = ((ROMFH_SIZE+ino+1+ROMFH_PAD)&ROMFH_MASK); - else - ino = 0; - - i->u.romfs_i.i_metasize = ino; - i->u.romfs_i.i_dataoffset = ino+(i->i_ino&ROMFH_MASK); - - /* Compute permissions */ - ino = S_IRUGO|S_IWUSR; - ino |= romfs_modemap[nextfh & ROMFH_TYPE]; - if (nextfh & ROMFH_EXEC) { - ino |= S_IXUGO; - } - i->i_mode = ino; - - if (S_ISFIFO(ino)) - init_fifo(i); - else if (S_ISDIR(ino)) - i->i_size = i->u.romfs_i.i_metasize; - else if (S_ISBLK(ino) || S_ISCHR(ino)) { - i->i_mode &= ~(S_IRWXG|S_IRWXO); - ino = ntohl(ri.spec); - i->i_rdev = MKDEV(ino>>16,ino&0xffff); + /* Precalculate the data offset */ + ino = romfs_strnlen(i, ino+ROMFH_SIZE, ROMFS_MAXFN); + if (ino >= 0) + ino = ((ROMFH_SIZE+ino+1+ROMFH_PAD)&ROMFH_MASK); + else + ino = 0; + + i->u.romfs_i.i_metasize = ino; + i->u.romfs_i.i_dataoffset = ino+(i->i_ino&ROMFH_MASK); + + /* Compute permissions */ + ino = romfs_modemap[nextfh & ROMFH_TYPE]; + /* only "normal" files have ops */ + if ((i->i_op = romfs_inoops[nextfh & ROMFH_TYPE])) { + if (nextfh & ROMFH_EXEC) + ino |= S_IXUGO; + i->i_mode = ino; + if (S_ISDIR(ino)) + i->i_size = i->u.romfs_i.i_metasize; + } else { + /* depending on MBZ for sock/fifos */ + nextfh = ntohl(ri.spec); + nextfh = kdev_t_to_nr(MKDEV(nextfh>>16,nextfh&0xffff)); + init_special_inode(i, ino, nextfh); } } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |