X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Flibfs.c;h=5294de1f40c41ba3c2dfcd992c725202967b0dce;hb=5351fb106a84d6ac584c2501e3b335093d38a58c;hp=7d487047dbb8814ea1d5f0a01c9e30c630d9a322;hpb=8800c0ebf5e8363dab66647512dcef5b83203dec;p=powerpc.git diff --git a/fs/libfs.c b/fs/libfs.c index 7d487047db..5294de1f40 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -159,7 +159,10 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) continue; spin_unlock(&dcache_lock); - if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0) + if (filldir(dirent, next->d_name.name, + next->d_name.len, filp->f_pos, + next->d_inode->i_ino, + dt_type(next->d_inode)) < 0) return 0; spin_lock(&dcache_lock); /* next is still alive */ @@ -190,6 +193,10 @@ const struct inode_operations simple_dir_inode_operations = { .lookup = simple_lookup, }; +static const struct super_operations simple_super_operations = { + .statfs = simple_statfs, +}; + /* * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that * will never be mountable) @@ -199,7 +206,6 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, struct vfsmount *mnt) { struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); - static const struct super_operations default_ops = {.statfs = simple_statfs}; struct dentry *dentry; struct inode *root; struct qstr d_name = {.name = name, .len = strlen(name)}; @@ -212,11 +218,17 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = magic; - s->s_op = ops ? ops : &default_ops; + s->s_op = ops ? ops : &simple_super_operations; s->s_time_gran = 1; root = new_inode(s); if (!root) goto Enomem; + /* + * since this is the first inode, make it number 1. New inodes created + * after this must take care not to collide with it (by passing + * max_reserved of 1 to iunique). + */ + root->i_ino = 1; root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; root->i_uid = root->i_gid = 0; root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; @@ -335,17 +347,18 @@ int simple_prepare_write(struct file *file, struct page *page, flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); } - SetPageUptodate(page); } return 0; } int simple_commit_write(struct file *file, struct page *page, - unsigned offset, unsigned to) + unsigned from, unsigned to) { struct inode *inode = page->mapping->host; loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + if (!PageUptodate(page)) + SetPageUptodate(page); /* * No need to use i_size_read() here, the i_size * cannot change under us because we hold the i_mutex. @@ -356,9 +369,13 @@ int simple_commit_write(struct file *file, struct page *page, return 0; } +/* + * the inodes created here are not hashed. If you use iunique to generate + * unique inode values later for this filesystem, then you must take care + * to pass it an appropriate max_reserved value to avoid collisions. + */ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) { - static struct super_operations s_ops = {.statfs = simple_statfs}; struct inode *inode; struct dentry *root; struct dentry *dentry; @@ -367,12 +384,17 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files s->s_blocksize = PAGE_CACHE_SIZE; s->s_blocksize_bits = PAGE_CACHE_SHIFT; s->s_magic = magic; - s->s_op = &s_ops; + s->s_op = &simple_super_operations; s->s_time_gran = 1; inode = new_inode(s); if (!inode) return -ENOMEM; + /* + * because the root inode is 1, the files array must not contain an + * entry at index 1 + */ + inode->i_ino = 1; inode->i_mode = S_IFDIR | 0755; inode->i_uid = inode->i_gid = 0; inode->i_blocks = 0; @@ -388,6 +410,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files for (i = 0; !files->name || files->name[0]; i++, files++) { if (!files->name) continue; + + /* warn if it tries to conflict with the root inode */ + if (unlikely(i == 1)) + printk(KERN_WARNING "%s: %s passed in a files array" + "with an index of 1!\n", __func__, + s->s_type->name); + dentry = d_alloc_name(root, files->name); if (!dentry) goto out;