diff options
Diffstat (limited to 'fs/freevxfs')
| -rw-r--r-- | fs/freevxfs/Kconfig | 16 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs.h | 6 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_bmap.c | 2 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_dir.h | 4 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_extern.h | 13 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_fshead.c | 14 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_immed.c | 7 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_inode.c | 96 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_lookup.c | 87 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_olt.c | 9 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_olt.h | 2 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_subr.c | 10 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_super.c | 64 |
13 files changed, 181 insertions, 149 deletions
diff --git a/fs/freevxfs/Kconfig b/fs/freevxfs/Kconfig new file mode 100644 index 00000000000..8dc1cd5c1ef --- /dev/null +++ b/fs/freevxfs/Kconfig @@ -0,0 +1,16 @@ +config VXFS_FS + tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" + depends on BLOCK + help + FreeVxFS is a file system driver that support the VERITAS VxFS(TM) + file system format. VERITAS VxFS(TM) is the standard file system + of SCO UnixWare (and possibly others) and optionally available + for Sunsoft Solaris, HP-UX and many other operating systems. + Currently only readonly access is supported. + + NOTE: the file system type as used by mount(1), mount(2) and + fstab(5) is 'vxfs' as it describes the file system format, not + the actual driver. + + To compile this as a module, choose M here: the module will be + called freevxfs. If unsure, say N. diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h index 583bd78086d..c8a92652612 100644 --- a/fs/freevxfs/vxfs.h +++ b/fs/freevxfs/vxfs.h @@ -159,11 +159,11 @@ struct vxfs_sb { * In core superblock filesystem private data for VxFS. */ struct vxfs_sb_info { - struct vxfs_sb *vsi_raw; /* raw (on disk) supeblock */ + struct vxfs_sb *vsi_raw; /* raw (on disk) superblock */ struct buffer_head *vsi_bp; /* buffer for raw superblock*/ struct inode *vsi_fship; /* fileset header inode */ struct inode *vsi_ilist; /* inode list inode */ - struct inode *vsi_stilist; /* structual inode list inode */ + struct inode *vsi_stilist; /* structural inode list inode */ u_long vsi_iext; /* initial inode list */ ino_t vsi_fshino; /* fileset header inode */ daddr_t vsi_oltext; /* OLT extent */ @@ -252,7 +252,7 @@ enum { * Get filesystem private data from VFS inode. */ #define VXFS_INO(ip) \ - ((struct vxfs_inode_info *)(ip)->u.generic_ip) + ((struct vxfs_inode_info *)(ip)->i_private) /* * Get filesystem private data from VFS superblock. diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c index 2d71128bd8d..f86fd3cacd5 100644 --- a/fs/freevxfs/vxfs_bmap.c +++ b/fs/freevxfs/vxfs_bmap.c @@ -137,7 +137,7 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) bp = sb_bread(ip->i_sb, indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb))); - if (!buffer_mapped(bp)) + if (!bp || !buffer_mapped(bp)) return 0; typ = ((struct vxfs_typed *)bp->b_data) + diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h index 8a4dfef1dda..aaf1fb09863 100644 --- a/fs/freevxfs/vxfs_dir.h +++ b/fs/freevxfs/vxfs_dir.h @@ -41,7 +41,7 @@ * VxFS directory block header. * * This entry is the head of every filesystem block in a directory. - * It is used for free space managment and additionally includes + * It is used for free space management and additionally includes * a hash for speeding up directory search (lookup). * * The hash may be empty and in fact we do not use it all in the @@ -80,7 +80,7 @@ struct vxfs_direct { * a d_name with size len. */ #define VXFS_DIRPAD 4 -#define VXFS_NAMEMIN ((int)((struct vxfs_direct *)0)->d_name) +#define VXFS_NAMEMIN offsetof(struct vxfs_direct, d_name) #define VXFS_DIRROUND(len) ((VXFS_DIRPAD + (len) - 1) & ~(VXFS_DIRPAD -1)) #define VXFS_DIRLEN(len) (VXFS_DIRROUND(VXFS_NAMEMIN + (len))) diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h index 927acf70c59..881aa3d217f 100644 --- a/fs/freevxfs/vxfs_extern.h +++ b/fs/freevxfs/vxfs_extern.h @@ -50,7 +50,11 @@ extern daddr_t vxfs_bmap1(struct inode *, long); /* vxfs_fshead.c */ extern int vxfs_read_fshead(struct super_block *); +/* vxfs_immed.c */ +extern const struct inode_operations vxfs_immed_symlink_iops; + /* vxfs_inode.c */ +extern const struct address_space_operations vxfs_immed_aops; extern struct kmem_cache *vxfs_inode_cachep; extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t); extern struct inode * vxfs_get_fake_inode(struct super_block *, @@ -58,17 +62,18 @@ extern struct inode * vxfs_get_fake_inode(struct super_block *, extern void vxfs_put_fake_inode(struct inode *); extern struct vxfs_inode_info * vxfs_blkiget(struct super_block *, u_long, ino_t); extern struct vxfs_inode_info * vxfs_stiget(struct super_block *, ino_t); -extern void vxfs_read_inode(struct inode *); -extern void vxfs_clear_inode(struct inode *); +extern struct inode * vxfs_iget(struct super_block *, ino_t); +extern void vxfs_evict_inode(struct inode *); /* vxfs_lookup.c */ -extern struct inode_operations vxfs_dir_inode_ops; -extern struct file_operations vxfs_dir_operations; +extern const struct inode_operations vxfs_dir_inode_ops; +extern const struct file_operations vxfs_dir_operations; /* vxfs_olt.c */ extern int vxfs_read_olt(struct super_block *, u_long); /* vxfs_subr.c */ +extern const struct address_space_operations vxfs_aops; extern struct page * vxfs_get_page(struct address_space *, u_long); extern void vxfs_put_page(struct page *); extern struct buffer_head * vxfs_bread(struct inode *, int); diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c index 6dee109aeea..c9a6a94e58e 100644 --- a/fs/freevxfs/vxfs_fshead.c +++ b/fs/freevxfs/vxfs_fshead.c @@ -112,7 +112,7 @@ vxfs_read_fshead(struct super_block *sbp) vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino); if (!vip) { - printk(KERN_ERR "vxfs: unabled to read fsh inode\n"); + printk(KERN_ERR "vxfs: unable to read fsh inode\n"); return -EINVAL; } if (!VXFS_ISFSH(vip)) { @@ -129,13 +129,13 @@ vxfs_read_fshead(struct super_block *sbp) infp->vsi_fship = vxfs_get_fake_inode(sbp, vip); if (!infp->vsi_fship) { - printk(KERN_ERR "vxfs: unabled to get fsh inode\n"); + printk(KERN_ERR "vxfs: unable to get fsh inode\n"); goto out_free_fship; } sfp = vxfs_getfsh(infp->vsi_fship, 0); if (!sfp) { - printk(KERN_ERR "vxfs: unabled to get structural fsh\n"); + printk(KERN_ERR "vxfs: unable to get structural fsh\n"); goto out_iput_fship; } @@ -145,7 +145,7 @@ vxfs_read_fshead(struct super_block *sbp) pfp = vxfs_getfsh(infp->vsi_fship, 1); if (!pfp) { - printk(KERN_ERR "vxfs: unabled to get primary fsh\n"); + printk(KERN_ERR "vxfs: unable to get primary fsh\n"); goto out_free_sfp; } @@ -159,12 +159,12 @@ vxfs_read_fshead(struct super_block *sbp) infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip); if (!infp->vsi_stilist) { - printk(KERN_ERR "vxfs: unabled to get structual list inode\n"); + printk(KERN_ERR "vxfs: unable to get structural list inode\n"); kfree(tip); goto out_free_pfp; } if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) { - printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n", + printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n", VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); goto out_iput_stilist; } @@ -174,7 +174,7 @@ vxfs_read_fshead(struct super_block *sbp) goto out_iput_stilist; infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip); if (!infp->vsi_ilist) { - printk(KERN_ERR "vxfs: unabled to get inode list inode\n"); + printk(KERN_ERR "vxfs: unable to get inode list inode\n"); kfree(tip); goto out_iput_stilist; } diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c index 6f5df1700e9..c36aeaf92e4 100644 --- a/fs/freevxfs/vxfs_immed.c +++ b/fs/freevxfs/vxfs_immed.c @@ -35,6 +35,7 @@ #include <linux/namei.h> #include "vxfs.h" +#include "vxfs_extern.h" #include "vxfs_inode.h" @@ -48,15 +49,15 @@ static int vxfs_immed_readpage(struct file *, struct page *); * Unliked all other operations we do not go through the pagecache, * but do all work directly on the inode. */ -struct inode_operations vxfs_immed_symlink_iops = { +const struct inode_operations vxfs_immed_symlink_iops = { .readlink = generic_readlink, .follow_link = vxfs_immed_follow_link, }; /* - * Adress space operations for immed files and directories. + * Address space operations for immed files and directories. */ -struct address_space_operations vxfs_immed_aops = { +const struct address_space_operations vxfs_immed_aops = { .readpage = vxfs_immed_readpage, }; diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index f544aae9169..363e3ae25f6 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c @@ -41,12 +41,7 @@ #include "vxfs_extern.h" -extern struct address_space_operations vxfs_aops; -extern struct address_space_operations vxfs_immed_aops; - -extern struct inode_operations vxfs_immed_symlink_iops; - -kmem_cache_t *vxfs_inode_cachep; +struct kmem_cache *vxfs_inode_cachep; #ifdef DIAGNOSTIC @@ -99,11 +94,11 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); bp = sb_bread(sbp, block); - if (buffer_mapped(bp)) { + if (bp && buffer_mapped(bp)) { struct vxfs_inode_info *vip; struct vxfs_dinode *dip; - if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) + if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) goto fail; dip = (struct vxfs_dinode *)(bp->b_data + offset); memcpy(vip, dip, sizeof(*vip)); @@ -129,7 +124,7 @@ fail: * Description: * Search the for inode number @ino in the filesystem * described by @sbp. Use the specified inode table (@ilistp). - * Returns the matching VxFS inode on success, else a NULL pointer. + * Returns the matching VxFS inode on success, else an error code. */ static struct vxfs_inode_info * __vxfs_iget(ino_t ino, struct inode *ilistp) @@ -145,7 +140,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) struct vxfs_dinode *dip; caddr_t kaddr = (char *)page_address(pp); - if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) + if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) goto fail; dip = (struct vxfs_dinode *)(kaddr + offset); memcpy(vip, dip, sizeof(*vip)); @@ -157,12 +152,12 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) } printk(KERN_WARNING "vxfs: error on page %p\n", pp); - return NULL; + return ERR_CAST(pp); fail: printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino); vxfs_put_page(pp); - return NULL; + return ERR_PTR(-ENOMEM); } /** @@ -178,7 +173,10 @@ fail: struct vxfs_inode_info * vxfs_stiget(struct super_block *sbp, ino_t ino) { - return __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist); + struct vxfs_inode_info *vip; + + vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist); + return IS_ERR(vip) ? NULL : vip; } /** @@ -189,10 +187,10 @@ vxfs_stiget(struct super_block *sbp, ino_t ino) * vxfs_transmod returns a Linux mode_t for a given * VxFS inode structure. */ -static __inline__ mode_t +static __inline__ umode_t vxfs_transmod(struct vxfs_inode_info *vip) { - mode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; + umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; if (VXFS_ISFIFO(vip)) ret |= S_IFIFO; @@ -226,10 +224,10 @@ vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip) { ip->i_mode = vxfs_transmod(vip); - ip->i_uid = (uid_t)vip->vii_uid; - ip->i_gid = (gid_t)vip->vii_gid; + i_uid_write(ip, (uid_t)vip->vii_uid); + i_gid_write(ip, (gid_t)vip->vii_gid); - ip->i_nlink = vip->vii_nlink; + set_nlink(ip, vip->vii_nlink); ip->i_size = vip->vii_size; ip->i_atime.tv_sec = vip->vii_atime; @@ -239,11 +237,10 @@ vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip) ip->i_ctime.tv_nsec = 0; ip->i_mtime.tv_nsec = 0; - ip->i_blksize = PAGE_SIZE; ip->i_blocks = vip->vii_blocks; ip->i_generation = vip->vii_gen; - ip->u.generic_ip = (void *)vip; + ip->i_private = vip; } @@ -263,6 +260,7 @@ vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip) struct inode *ip = NULL; if ((ip = new_inode(sbp))) { + ip->i_ino = get_next_ino(); vxfs_iinit(ip, vip); ip->i_mapping->a_ops = &vxfs_aops; } @@ -274,7 +272,7 @@ vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip) * *ip: VFS inode * * Description: - * vxfs_put_fake_inode frees all data asssociated with @ip. + * vxfs_put_fake_inode frees all data associated with @ip. */ void vxfs_put_fake_inode(struct inode *ip) @@ -283,23 +281,32 @@ vxfs_put_fake_inode(struct inode *ip) } /** - * vxfs_read_inode - fill in inode information - * @ip: inode pointer to fill + * vxfs_iget - get an inode + * @sbp: the superblock to get the inode for + * @ino: the number of the inode to get * * Description: - * vxfs_read_inode reads the disk inode for @ip and fills - * in all relevant fields in @ip. + * vxfs_read_inode creates an inode, reads the disk inode for @ino and fills + * in all relevant fields in the new inode. */ -void -vxfs_read_inode(struct inode *ip) +struct inode * +vxfs_iget(struct super_block *sbp, ino_t ino) { - struct super_block *sbp = ip->i_sb; struct vxfs_inode_info *vip; - struct address_space_operations *aops; - ino_t ino = ip->i_ino; - - if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist))) - return; + const struct address_space_operations *aops; + struct inode *ip; + + ip = iget_locked(sbp, ino); + if (!ip) + return ERR_PTR(-ENOMEM); + if (!(ip->i_state & I_NEW)) + return ip; + + vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist); + if (IS_ERR(vip)) { + iget_failed(ip); + return ERR_CAST(vip); + } vxfs_iinit(ip, vip); @@ -319,24 +326,35 @@ vxfs_read_inode(struct inode *ip) if (!VXFS_ISIMMED(vip)) { ip->i_op = &page_symlink_inode_operations; ip->i_mapping->a_ops = &vxfs_aops; - } else + } else { ip->i_op = &vxfs_immed_symlink_iops; + vip->vii_immed.vi_immed[ip->i_size] = '\0'; + } } else init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev)); - return; + unlock_new_inode(ip); + return ip; +} + +static void vxfs_i_callback(struct rcu_head *head) +{ + struct inode *inode = container_of(head, struct inode, i_rcu); + kmem_cache_free(vxfs_inode_cachep, inode->i_private); } /** - * vxfs_clear_inode - remove inode from main memory + * vxfs_evict_inode - remove inode from main memory * @ip: inode to discard. * * Description: - * vxfs_clear_inode() is called on the final iput and frees the private + * vxfs_evict_inode() is called on the final iput and frees the private * inode area. */ void -vxfs_clear_inode(struct inode *ip) +vxfs_evict_inode(struct inode *ip) { - kmem_cache_free(vxfs_inode_cachep, ip->u.generic_ip); + truncate_inode_pages_final(&ip->i_data); + clear_inode(ip); + call_rcu(&ip->i_rcu, vxfs_i_callback); } diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 554eb455722..99c7f0a37af 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c @@ -36,7 +36,6 @@ #include <linux/highmem.h> #include <linux/kernel.h> #include <linux/pagemap.h> -#include <linux/smp_lock.h> #include "vxfs.h" #include "vxfs_dir.h" @@ -49,15 +48,17 @@ #define VXFS_BLOCK_PER_PAGE(sbp) ((PAGE_CACHE_SIZE / (sbp)->s_blocksize)) -static struct dentry * vxfs_lookup(struct inode *, struct dentry *, struct nameidata *); -static int vxfs_readdir(struct file *, void *, filldir_t); +static struct dentry * vxfs_lookup(struct inode *, struct dentry *, unsigned int); +static int vxfs_readdir(struct file *, struct dir_context *); -struct inode_operations vxfs_dir_inode_ops = { +const struct inode_operations vxfs_dir_inode_ops = { .lookup = vxfs_lookup, }; -struct file_operations vxfs_dir_operations = { - .readdir = vxfs_readdir, +const struct file_operations vxfs_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = vxfs_readdir, }; @@ -161,7 +162,7 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp) /** * vxfs_inode_by_name - find inode number for dentry * @dip: directory to search in - * @dp: dentry we seach for + * @dp: dentry we search for * * Description: * vxfs_inode_by_name finds out the inode number of @@ -191,7 +192,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp) * vxfs_lookup - lookup pathname component * @dip: dir in which we lookup * @dp: dentry we lookup - * @nd: lookup nameidata + * @flags: lookup flags * * Description: * vxfs_lookup tries to lookup the pathname component described @@ -202,7 +203,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp) * in the return pointer. */ static struct dentry * -vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) +vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags) { struct inode *ip = NULL; ino_t ino; @@ -210,16 +211,12 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) if (dp->d_name.len > VXFS_NAMELEN) return ERR_PTR(-ENAMETOOLONG); - lock_kernel(); ino = vxfs_inode_by_name(dip, dp); if (ino) { - ip = iget(dip->i_sb, ino); - if (!ip) { - unlock_kernel(); - return ERR_PTR(-EACCES); - } + ip = vxfs_iget(dip->i_sb, ino); + if (IS_ERR(ip)) + return ERR_CAST(ip); } - unlock_kernel(); d_add(dp, ip); return NULL; } @@ -238,33 +235,28 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) * Zero. */ static int -vxfs_readdir(struct file *fp, void *retp, filldir_t filler) +vxfs_readdir(struct file *fp, struct dir_context *ctx) { - struct inode *ip = fp->f_dentry->d_inode; + struct inode *ip = file_inode(fp); struct super_block *sbp = ip->i_sb; u_long bsize = sbp->s_blocksize; u_long page, npages, block, pblocks, nblocks, offset; loff_t pos; - switch ((long)fp->f_pos) { - case 0: - if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0) - goto out; - fp->f_pos++; - /* fallthrough */ - case 1: - if (filler(retp, "..", 2, fp->f_pos, VXFS_INO(ip)->vii_dotdot, DT_DIR) < 0) - goto out; - fp->f_pos++; - /* fallthrough */ + if (ctx->pos == 0) { + if (!dir_emit_dot(fp, ctx)) + return 0; + ctx->pos = 1; } - - pos = fp->f_pos - 2; + if (ctx->pos == 1) { + if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR)) + return 0; + ctx->pos = 2; + } + pos = ctx->pos - 2; - if (pos > VXFS_DIRROUND(ip->i_size)) { - unlock_kernel(); + if (pos > VXFS_DIRROUND(ip->i_size)) return 0; - } npages = dir_pages(ip); nblocks = dir_blocks(ip); @@ -275,16 +267,16 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks; for (; page < npages; page++, block = 0) { - caddr_t kaddr; + char *kaddr; struct page *pp; pp = vxfs_get_page(ip->i_mapping, page); if (IS_ERR(pp)) continue; - kaddr = (caddr_t)page_address(pp); + kaddr = (char *)page_address(pp); for (; block <= nblocks && block <= pblocks; block++) { - caddr_t baddr, limit; + char *baddr, *limit; struct vxfs_dirblk *dbp; struct vxfs_direct *de; @@ -297,21 +289,18 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) (kaddr + offset) : (baddr + VXFS_DIRBLKOV(dbp))); - for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) { - int over; - + for (; (char *)de <= limit; de = vxfs_next_entry(de)) { if (!de->d_reclen) break; if (!de->d_ino) continue; - offset = (caddr_t)de - kaddr; - over = filler(retp, de->d_name, de->d_namelen, - ((page << PAGE_CACHE_SHIFT) | offset) + 2, - de->d_ino, DT_UNKNOWN); - if (over) { + offset = (char *)de - kaddr; + ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2; + if (!dir_emit(ctx, de->d_name, de->d_namelen, + de->d_ino, DT_UNKNOWN)) { vxfs_put_page(pp); - goto done; + return 0; } } offset = 0; @@ -319,10 +308,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) vxfs_put_page(pp); offset = 0; } - -done: - fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2; -out: - unlock_kernel(); + ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2; return 0; } diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c index 76a0708ae97..04950084790 100644 --- a/fs/freevxfs/vxfs_olt.c +++ b/fs/freevxfs/vxfs_olt.c @@ -42,24 +42,21 @@ static inline void vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) { - if (infp->vsi_fshino) - BUG(); + BUG_ON(infp->vsi_fshino); infp->vsi_fshino = fshp->olt_fsino[0]; } static inline void vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) { - if (infp->vsi_iext) - BUG(); + BUG_ON(infp->vsi_iext); infp->vsi_iext = ilistp->olt_iext[0]; } static inline u_long vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize) { - if (sbp->s_blocksize % bsize) - BUG(); + BUG_ON(sbp->s_blocksize % bsize); return (block * (sbp->s_blocksize / bsize)); } diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h index d8324296486..b7b3af50261 100644 --- a/fs/freevxfs/vxfs_olt.h +++ b/fs/freevxfs/vxfs_olt.h @@ -60,7 +60,7 @@ enum { * * The Object Location Table header is placed at the beginning of each * OLT extent. It is used to fing certain filesystem-wide metadata, e.g. - * the inital inode list, the fileset header or the device configuration. + * the initial inode list, the fileset header or the device configuration. */ struct vxfs_olt { u_int32_t olt_magic; /* magic number */ diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c index 50aae77651b..5d318c44f85 100644 --- a/fs/freevxfs/vxfs_subr.c +++ b/fs/freevxfs/vxfs_subr.c @@ -33,7 +33,6 @@ #include <linux/fs.h> #include <linux/buffer_head.h> #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/pagemap.h> #include "vxfs_extern.h" @@ -42,10 +41,9 @@ static int vxfs_readpage(struct file *, struct page *); static sector_t vxfs_bmap(struct address_space *, sector_t); -struct address_space_operations vxfs_aops = { +const struct address_space_operations vxfs_aops = { .readpage = vxfs_readpage, .bmap = vxfs_bmap, - .sync_page = block_sync_page, }; inline void @@ -71,14 +69,10 @@ vxfs_get_page(struct address_space *mapping, u_long n) { struct page * pp; - pp = read_cache_page(mapping, n, - (filler_t*)mapping->a_ops->readpage, NULL); + pp = read_mapping_page(mapping, n, NULL); if (!IS_ERR(pp)) { - wait_on_page_locked(pp); kmap(pp); - if (!PageUptodate(pp)) - goto fail; /** if (!PageChecked(pp)) **/ /** vxfs_check_page(pp); **/ if (PageError(pp)) diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 6aa6fbe4f8e..7ca8c75d50d 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -40,6 +40,7 @@ #include <linux/slab.h> #include <linux/stat.h> #include <linux/vfs.h> +#include <linux/mount.h> #include "vxfs.h" #include "vxfs_extern.h" @@ -51,16 +52,14 @@ MODULE_AUTHOR("Christoph Hellwig"); MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */ static void vxfs_put_super(struct super_block *); -static int vxfs_statfs(struct super_block *, struct kstatfs *); +static int vxfs_statfs(struct dentry *, struct kstatfs *); static int vxfs_remount(struct super_block *, int *, char *); -static struct super_operations vxfs_super_ops = { - .read_inode = vxfs_read_inode, - .clear_inode = vxfs_clear_inode, +static const struct super_operations vxfs_super_ops = { + .evict_inode = vxfs_evict_inode, .put_super = vxfs_put_super, .statfs = vxfs_statfs, .remount_fs = vxfs_remount, @@ -90,12 +89,12 @@ vxfs_put_super(struct super_block *sbp) /** * vxfs_statfs - get filesystem information - * @sbp: VFS superblock + * @dentry: VFS dentry to locate superblock * @bufp: output buffer * * Description: * vxfs_statfs fills the statfs buffer @bufp with information - * about the filesystem described by @sbp. + * about the filesystem described by @dentry. * * Returns: * Zero. @@ -107,12 +106,12 @@ vxfs_put_super(struct super_block *sbp) * This is everything but complete... */ static int -vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp) +vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp) { - struct vxfs_sb_info *infp = VXFS_SBI(sbp); + struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb); bufp->f_type = VXFS_SUPER_MAGIC; - bufp->f_bsize = sbp->s_blocksize; + bufp->f_bsize = dentry->d_sb->s_blocksize; bufp->f_blocks = infp->vsi_raw->vs_dsize; bufp->f_bfree = infp->vsi_raw->vs_free; bufp->f_bavail = 0; @@ -125,12 +124,13 @@ vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp) static int vxfs_remount(struct super_block *sb, int *flags, char *data) { + sync_filesystem(sb); *flags |= MS_RDONLY; return 0; } /** - * vxfs_read_super - read superblock into memory and initalize filesystem + * vxfs_read_super - read superblock into memory and initialize filesystem * @sbp: VFS superblock (to fill) * @dp: fs private mount data * @silent: do not complain loudly when sth is wrong @@ -143,7 +143,7 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data) * The superblock on success, else %NULL. * * Locking: - * We are under the bkl and @sbp->s_lock. + * We are under @sbp->s_lock. */ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) { @@ -152,6 +152,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) struct buffer_head *bp = NULL; u_long bsize; struct inode *root; + int ret = -EINVAL; sbp->s_flags |= MS_RDONLY; @@ -218,10 +219,13 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) } sbp->s_op = &vxfs_super_ops; - root = iget(sbp, VXFS_ROOT_INO); - sbp->s_root = d_alloc_root(root); + root = vxfs_iget(sbp, VXFS_ROOT_INO); + if (IS_ERR(root)) { + ret = PTR_ERR(root); + goto out; + } + sbp->s_root = d_make_root(root); if (!sbp->s_root) { - iput(root); printk(KERN_WARNING "vxfs: unable to get root dentry.\n"); goto out_free_ilist; } @@ -235,41 +239,53 @@ out_free_ilist: out: brelse(bp); kfree(infp); - return -EINVAL; + return ret; } /* * The usual module blurb. */ -static struct super_block *vxfs_get_sb(struct file_system_type *fs_type, +static struct dentry *vxfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super); + return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super); } static struct file_system_type vxfs_fs_type = { .owner = THIS_MODULE, .name = "vxfs", - .get_sb = vxfs_get_sb, + .mount = vxfs_mount, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */ +MODULE_ALIAS("vxfs"); static int __init vxfs_init(void) { + int rv; + vxfs_inode_cachep = kmem_cache_create("vxfs_inode", - sizeof(struct vxfs_inode_info), 0, - SLAB_RECLAIM_ACCOUNT, NULL, NULL); - if (vxfs_inode_cachep) - return register_filesystem(&vxfs_fs_type); - return -ENOMEM; + sizeof(struct vxfs_inode_info), 0, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL); + if (!vxfs_inode_cachep) + return -ENOMEM; + rv = register_filesystem(&vxfs_fs_type); + if (rv < 0) + kmem_cache_destroy(vxfs_inode_cachep); + return rv; } static void __exit vxfs_cleanup(void) { unregister_filesystem(&vxfs_fs_type); + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); kmem_cache_destroy(vxfs_inode_cachep); } |
