diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/freevxfs/vxfs.h | 7 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_extern.h | 1 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_inode.c | 215 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_inode.h | 7 | ||||
| -rw-r--r-- | fs/freevxfs/vxfs_super.c | 28 |
5 files changed, 116 insertions, 142 deletions
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h index 4b561ded5eb1..f52f259aacb3 100644 --- a/fs/freevxfs/vxfs.h +++ b/fs/freevxfs/vxfs.h | |||
| @@ -272,13 +272,6 @@ enum { | |||
| 272 | #define VXFS_ISIMMED(ip) VXFS_IS_ORG((ip), VXFS_ORG_IMMED) | 272 | #define VXFS_ISIMMED(ip) VXFS_IS_ORG((ip), VXFS_ORG_IMMED) |
| 273 | #define VXFS_ISTYPED(ip) VXFS_IS_ORG((ip), VXFS_ORG_TYPED) | 273 | #define VXFS_ISTYPED(ip) VXFS_IS_ORG((ip), VXFS_ORG_TYPED) |
| 274 | 274 | ||
| 275 | |||
| 276 | /* | ||
| 277 | * Get filesystem private data from VFS inode. | ||
| 278 | */ | ||
| 279 | #define VXFS_INO(ip) \ | ||
| 280 | ((struct vxfs_inode_info *)(ip)->i_private) | ||
| 281 | |||
| 282 | /* | 275 | /* |
| 283 | * Get filesystem private data from VFS superblock. | 276 | * Get filesystem private data from VFS superblock. |
| 284 | */ | 277 | */ |
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h index 2ec8c0f27865..f5c428e21024 100644 --- a/fs/freevxfs/vxfs_extern.h +++ b/fs/freevxfs/vxfs_extern.h | |||
| @@ -52,7 +52,6 @@ extern int vxfs_read_fshead(struct super_block *); | |||
| 52 | 52 | ||
| 53 | /* vxfs_inode.c */ | 53 | /* vxfs_inode.c */ |
| 54 | extern const struct address_space_operations vxfs_immed_aops; | 54 | extern const struct address_space_operations vxfs_immed_aops; |
| 55 | extern struct kmem_cache *vxfs_inode_cachep; | ||
| 56 | extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t); | 55 | extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t); |
| 57 | extern struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t); | 56 | extern struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t); |
| 58 | extern struct inode *vxfs_stiget(struct super_block *, ino_t); | 57 | extern struct inode *vxfs_stiget(struct super_block *, ino_t); |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 7b5de83405f2..b718d0ff2e45 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
| @@ -42,11 +42,6 @@ | |||
| 42 | #include "vxfs_extern.h" | 42 | #include "vxfs_extern.h" |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | struct kmem_cache *vxfs_inode_cachep; | ||
| 46 | |||
| 47 | static struct inode * vxfs_get_fake_inode(struct super_block *, | ||
| 48 | struct vxfs_inode_info *); | ||
| 49 | |||
| 50 | #ifdef DIAGNOSTIC | 45 | #ifdef DIAGNOSTIC |
| 51 | /* | 46 | /* |
| 52 | * Dump inode contents (partially). | 47 | * Dump inode contents (partially). |
| @@ -70,9 +65,42 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) | |||
| 70 | } | 65 | } |
| 71 | #endif | 66 | #endif |
| 72 | 67 | ||
| 68 | /** | ||
| 69 | * vxfs_transmod - mode for a VxFS inode | ||
| 70 | * @vip: VxFS inode | ||
| 71 | * | ||
| 72 | * Description: | ||
| 73 | * vxfs_transmod returns a Linux mode_t for a given | ||
| 74 | * VxFS inode structure. | ||
| 75 | */ | ||
| 76 | static __inline__ umode_t | ||
| 77 | vxfs_transmod(struct vxfs_inode_info *vip) | ||
| 78 | { | ||
| 79 | umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; | ||
| 80 | |||
| 81 | if (VXFS_ISFIFO(vip)) | ||
| 82 | ret |= S_IFIFO; | ||
| 83 | if (VXFS_ISCHR(vip)) | ||
| 84 | ret |= S_IFCHR; | ||
| 85 | if (VXFS_ISDIR(vip)) | ||
| 86 | ret |= S_IFDIR; | ||
| 87 | if (VXFS_ISBLK(vip)) | ||
| 88 | ret |= S_IFBLK; | ||
| 89 | if (VXFS_ISLNK(vip)) | ||
| 90 | ret |= S_IFLNK; | ||
| 91 | if (VXFS_ISREG(vip)) | ||
| 92 | ret |= S_IFREG; | ||
| 93 | if (VXFS_ISSOC(vip)) | ||
| 94 | ret |= S_IFSOCK; | ||
| 95 | |||
| 96 | return (ret); | ||
| 97 | } | ||
| 98 | |||
| 73 | static inline void dip2vip_cpy(struct vxfs_sb_info *sbi, | 99 | static inline void dip2vip_cpy(struct vxfs_sb_info *sbi, |
| 74 | struct vxfs_inode_info *vip, struct vxfs_dinode *dip) | 100 | struct vxfs_inode_info *vip, struct vxfs_dinode *dip) |
| 75 | { | 101 | { |
| 102 | struct inode *inode = &vip->vfs_inode; | ||
| 103 | |||
| 76 | vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode); | 104 | vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode); |
| 77 | vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink); | 105 | vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink); |
| 78 | vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid); | 106 | vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid); |
| @@ -96,6 +124,23 @@ static inline void dip2vip_cpy(struct vxfs_sb_info *sbi, | |||
| 96 | 124 | ||
| 97 | /* don't endian swap the fields that differ by orgtype */ | 125 | /* don't endian swap the fields that differ by orgtype */ |
| 98 | memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org)); | 126 | memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org)); |
| 127 | |||
| 128 | inode->i_mode = vxfs_transmod(vip); | ||
| 129 | i_uid_write(inode, (uid_t)vip->vii_uid); | ||
| 130 | i_gid_write(inode, (gid_t)vip->vii_gid); | ||
| 131 | |||
| 132 | set_nlink(inode, vip->vii_nlink); | ||
| 133 | inode->i_size = vip->vii_size; | ||
| 134 | |||
| 135 | inode->i_atime.tv_sec = vip->vii_atime; | ||
| 136 | inode->i_ctime.tv_sec = vip->vii_ctime; | ||
| 137 | inode->i_mtime.tv_sec = vip->vii_mtime; | ||
| 138 | inode->i_atime.tv_nsec = 0; | ||
| 139 | inode->i_ctime.tv_nsec = 0; | ||
| 140 | inode->i_mtime.tv_nsec = 0; | ||
| 141 | |||
| 142 | inode->i_blocks = vip->vii_blocks; | ||
| 143 | inode->i_generation = vip->vii_gen; | ||
| 99 | } | 144 | } |
| 100 | 145 | ||
| 101 | /** | 146 | /** |
| @@ -121,48 +166,48 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) | |||
| 121 | struct inode *inode; | 166 | struct inode *inode; |
| 122 | u_long block, offset; | 167 | u_long block, offset; |
| 123 | 168 | ||
| 169 | inode = new_inode(sbp); | ||
| 170 | if (!inode) | ||
| 171 | return NULL; | ||
| 172 | inode->i_ino = get_next_ino(); | ||
| 173 | |||
| 124 | block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize); | 174 | block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize); |
| 125 | offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); | 175 | offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); |
| 126 | bp = sb_bread(sbp, block); | 176 | bp = sb_bread(sbp, block); |
| 127 | 177 | ||
| 128 | if (bp && buffer_mapped(bp)) { | 178 | if (bp && buffer_mapped(bp)) { |
| 129 | struct vxfs_inode_info *vip; | 179 | struct vxfs_inode_info *vip = VXFS_INO(inode); |
| 130 | struct vxfs_dinode *dip; | 180 | struct vxfs_dinode *dip; |
| 131 | 181 | ||
| 132 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) | ||
| 133 | goto fail; | ||
| 134 | dip = (struct vxfs_dinode *)(bp->b_data + offset); | 182 | dip = (struct vxfs_dinode *)(bp->b_data + offset); |
| 135 | dip2vip_cpy(VXFS_SBI(sbp), vip, dip); | 183 | dip2vip_cpy(VXFS_SBI(sbp), vip, dip); |
| 184 | vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; | ||
| 136 | #ifdef DIAGNOSTIC | 185 | #ifdef DIAGNOSTIC |
| 137 | vxfs_dumpi(vip, ino); | 186 | vxfs_dumpi(vip, ino); |
| 138 | #endif | 187 | #endif |
| 139 | brelse(bp); | 188 | brelse(bp); |
| 140 | |||
| 141 | inode = vxfs_get_fake_inode(sbp, vip); | ||
| 142 | if (!inode) | ||
| 143 | kmem_cache_free(vxfs_inode_cachep, vip); | ||
| 144 | return inode; | 189 | return inode; |
| 145 | } | 190 | } |
| 146 | 191 | ||
| 147 | fail: | ||
| 148 | printk(KERN_WARNING "vxfs: unable to read block %ld\n", block); | 192 | printk(KERN_WARNING "vxfs: unable to read block %ld\n", block); |
| 149 | brelse(bp); | 193 | brelse(bp); |
| 194 | iput(inode); | ||
| 150 | return NULL; | 195 | return NULL; |
| 151 | } | 196 | } |
| 152 | 197 | ||
| 153 | /** | 198 | /** |
| 154 | * __vxfs_iget - generic find inode facility | 199 | * __vxfs_iget - generic find inode facility |
| 155 | * @sbp: VFS superblock | ||
| 156 | * @ino: inode number | ||
| 157 | * @ilistp: inode list | 200 | * @ilistp: inode list |
| 201 | * @vip: VxFS inode to fill in | ||
| 202 | * @ino: inode number | ||
| 158 | * | 203 | * |
| 159 | * Description: | 204 | * Description: |
| 160 | * Search the for inode number @ino in the filesystem | 205 | * Search the for inode number @ino in the filesystem |
| 161 | * described by @sbp. Use the specified inode table (@ilistp). | 206 | * described by @sbp. Use the specified inode table (@ilistp). |
| 162 | * Returns the matching inode on success, else an error code. | 207 | * Returns the matching inode on success, else an error code. |
| 163 | */ | 208 | */ |
| 164 | static struct vxfs_inode_info * | 209 | static int |
| 165 | __vxfs_iget(ino_t ino, struct inode *ilistp) | 210 | __vxfs_iget(struct inode *ilistp, struct vxfs_inode_info *vip, ino_t ino) |
| 166 | { | 211 | { |
| 167 | struct page *pp; | 212 | struct page *pp; |
| 168 | u_long offset; | 213 | u_long offset; |
| @@ -171,28 +216,22 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) | |||
| 171 | pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE); | 216 | pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE); |
| 172 | 217 | ||
| 173 | if (!IS_ERR(pp)) { | 218 | if (!IS_ERR(pp)) { |
| 174 | struct vxfs_inode_info *vip; | ||
| 175 | struct vxfs_dinode *dip; | 219 | struct vxfs_dinode *dip; |
| 176 | caddr_t kaddr = (char *)page_address(pp); | 220 | caddr_t kaddr = (char *)page_address(pp); |
| 177 | 221 | ||
| 178 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) | ||
| 179 | goto fail; | ||
| 180 | dip = (struct vxfs_dinode *)(kaddr + offset); | 222 | dip = (struct vxfs_dinode *)(kaddr + offset); |
| 181 | dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip); | 223 | dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip); |
| 224 | vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; | ||
| 182 | #ifdef DIAGNOSTIC | 225 | #ifdef DIAGNOSTIC |
| 183 | vxfs_dumpi(vip, ino); | 226 | vxfs_dumpi(vip, ino); |
| 184 | #endif | 227 | #endif |
| 185 | vxfs_put_page(pp); | 228 | vxfs_put_page(pp); |
| 186 | return (vip); | 229 | return 0; |
| 187 | } | 230 | } |
| 188 | 231 | ||
| 189 | printk(KERN_WARNING "vxfs: error on page %p\n", pp); | 232 | printk(KERN_WARNING "vxfs: error on page 0x%p for inode %ld\n", |
| 190 | return ERR_CAST(pp); | 233 | pp, (unsigned long)ino); |
| 191 | 234 | return PTR_ERR(pp); | |
| 192 | fail: | ||
| 193 | printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino); | ||
| 194 | vxfs_put_page(pp); | ||
| 195 | return ERR_PTR(-ENOMEM); | ||
| 196 | } | 235 | } |
| 197 | 236 | ||
| 198 | /** | 237 | /** |
| @@ -208,104 +247,21 @@ fail: | |||
| 208 | struct inode * | 247 | struct inode * |
| 209 | vxfs_stiget(struct super_block *sbp, ino_t ino) | 248 | vxfs_stiget(struct super_block *sbp, ino_t ino) |
| 210 | { | 249 | { |
| 211 | struct vxfs_inode_info *vip; | ||
| 212 | struct inode *inode; | 250 | struct inode *inode; |
| 251 | int error; | ||
| 213 | 252 | ||
| 214 | vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist); | 253 | inode = new_inode(sbp); |
| 215 | if (IS_ERR(vip)) | ||
| 216 | return NULL; | ||
| 217 | inode = vxfs_get_fake_inode(sbp, vip); | ||
| 218 | if (!inode) | 254 | if (!inode) |
| 219 | kmem_cache_free(vxfs_inode_cachep, vip); | 255 | return NULL; |
| 220 | return inode; | 256 | inode->i_ino = get_next_ino(); |
| 221 | } | ||
| 222 | |||
| 223 | /** | ||
| 224 | * vxfs_transmod - mode for a VxFS inode | ||
| 225 | * @vip: VxFS inode | ||
| 226 | * | ||
| 227 | * Description: | ||
| 228 | * vxfs_transmod returns a Linux mode_t for a given | ||
| 229 | * VxFS inode structure. | ||
| 230 | */ | ||
| 231 | static __inline__ umode_t | ||
| 232 | vxfs_transmod(struct vxfs_inode_info *vip) | ||
| 233 | { | ||
| 234 | umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; | ||
| 235 | |||
| 236 | if (VXFS_ISFIFO(vip)) | ||
| 237 | ret |= S_IFIFO; | ||
| 238 | if (VXFS_ISCHR(vip)) | ||
| 239 | ret |= S_IFCHR; | ||
| 240 | if (VXFS_ISDIR(vip)) | ||
| 241 | ret |= S_IFDIR; | ||
| 242 | if (VXFS_ISBLK(vip)) | ||
| 243 | ret |= S_IFBLK; | ||
| 244 | if (VXFS_ISLNK(vip)) | ||
| 245 | ret |= S_IFLNK; | ||
| 246 | if (VXFS_ISREG(vip)) | ||
| 247 | ret |= S_IFREG; | ||
| 248 | if (VXFS_ISSOC(vip)) | ||
| 249 | ret |= S_IFSOCK; | ||
| 250 | |||
| 251 | return (ret); | ||
| 252 | } | ||
| 253 | |||
| 254 | /** | ||
| 255 | * vxfs_iinit- helper to fill inode fields | ||
| 256 | * @ip: VFS inode | ||
| 257 | * @vip: VxFS inode | ||
| 258 | * | ||
| 259 | * Description: | ||
| 260 | * vxfs_instino is a helper function to fill in all relevant | ||
| 261 | * fields in @ip from @vip. | ||
| 262 | */ | ||
| 263 | static void | ||
| 264 | vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip) | ||
| 265 | { | ||
| 266 | |||
| 267 | ip->i_mode = vxfs_transmod(vip); | ||
| 268 | i_uid_write(ip, (uid_t)vip->vii_uid); | ||
| 269 | i_gid_write(ip, (gid_t)vip->vii_gid); | ||
| 270 | |||
| 271 | set_nlink(ip, vip->vii_nlink); | ||
| 272 | ip->i_size = vip->vii_size; | ||
| 273 | |||
| 274 | ip->i_atime.tv_sec = vip->vii_atime; | ||
| 275 | ip->i_ctime.tv_sec = vip->vii_ctime; | ||
| 276 | ip->i_mtime.tv_sec = vip->vii_mtime; | ||
| 277 | ip->i_atime.tv_nsec = 0; | ||
| 278 | ip->i_ctime.tv_nsec = 0; | ||
| 279 | ip->i_mtime.tv_nsec = 0; | ||
| 280 | |||
| 281 | ip->i_blocks = vip->vii_blocks; | ||
| 282 | ip->i_generation = vip->vii_gen; | ||
| 283 | |||
| 284 | ip->i_private = vip; | ||
| 285 | |||
| 286 | } | ||
| 287 | |||
| 288 | /** | ||
| 289 | * vxfs_get_fake_inode - get fake inode structure | ||
| 290 | * @sbp: filesystem superblock | ||
| 291 | * @vip: fspriv inode | ||
| 292 | * | ||
| 293 | * Description: | ||
| 294 | * vxfs_fake_inode gets a fake inode (not in the inode hash) for a | ||
| 295 | * superblock, vxfs_inode pair. | ||
| 296 | * Returns the filled VFS inode. | ||
| 297 | */ | ||
| 298 | static struct inode * | ||
| 299 | vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip) | ||
| 300 | { | ||
| 301 | struct inode *ip = NULL; | ||
| 302 | 257 | ||
| 303 | if ((ip = new_inode(sbp))) { | 258 | error = __vxfs_iget(VXFS_SBI(sbp)->vsi_stilist, VXFS_INO(inode), ino); |
| 304 | ip->i_ino = get_next_ino(); | 259 | if (error) { |
| 305 | vxfs_iinit(ip, vip); | 260 | iput(inode); |
| 306 | ip->i_mapping->a_ops = &vxfs_aops; | 261 | return NULL; |
| 307 | } | 262 | } |
| 308 | return (ip); | 263 | |
| 264 | return inode; | ||
| 309 | } | 265 | } |
| 310 | 266 | ||
| 311 | /** | 267 | /** |
| @@ -323,6 +279,7 @@ vxfs_iget(struct super_block *sbp, ino_t ino) | |||
| 323 | struct vxfs_inode_info *vip; | 279 | struct vxfs_inode_info *vip; |
| 324 | const struct address_space_operations *aops; | 280 | const struct address_space_operations *aops; |
| 325 | struct inode *ip; | 281 | struct inode *ip; |
| 282 | int error; | ||
| 326 | 283 | ||
| 327 | ip = iget_locked(sbp, ino); | 284 | ip = iget_locked(sbp, ino); |
| 328 | if (!ip) | 285 | if (!ip) |
| @@ -330,14 +287,13 @@ vxfs_iget(struct super_block *sbp, ino_t ino) | |||
| 330 | if (!(ip->i_state & I_NEW)) | 287 | if (!(ip->i_state & I_NEW)) |
| 331 | return ip; | 288 | return ip; |
| 332 | 289 | ||
| 333 | vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist); | 290 | vip = VXFS_INO(ip); |
| 334 | if (IS_ERR(vip)) { | 291 | error = __vxfs_iget(VXFS_SBI(sbp)->vsi_ilist, vip, ino); |
| 292 | if (error) { | ||
| 335 | iget_failed(ip); | 293 | iget_failed(ip); |
| 336 | return ERR_CAST(vip); | 294 | return ERR_PTR(error); |
| 337 | } | 295 | } |
| 338 | 296 | ||
| 339 | vxfs_iinit(ip, vip); | ||
| 340 | |||
| 341 | if (VXFS_ISIMMED(vip)) | 297 | if (VXFS_ISIMMED(vip)) |
| 342 | aops = &vxfs_immed_aops; | 298 | aops = &vxfs_immed_aops; |
| 343 | else | 299 | else |
| @@ -368,12 +324,6 @@ vxfs_iget(struct super_block *sbp, ino_t ino) | |||
| 368 | return ip; | 324 | return ip; |
| 369 | } | 325 | } |
| 370 | 326 | ||
| 371 | static void vxfs_i_callback(struct rcu_head *head) | ||
| 372 | { | ||
| 373 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
| 374 | kmem_cache_free(vxfs_inode_cachep, inode->i_private); | ||
| 375 | } | ||
| 376 | |||
| 377 | /** | 327 | /** |
| 378 | * vxfs_evict_inode - remove inode from main memory | 328 | * vxfs_evict_inode - remove inode from main memory |
| 379 | * @ip: inode to discard. | 329 | * @ip: inode to discard. |
| @@ -387,5 +337,4 @@ vxfs_evict_inode(struct inode *ip) | |||
| 387 | { | 337 | { |
| 388 | truncate_inode_pages_final(&ip->i_data); | 338 | truncate_inode_pages_final(&ip->i_data); |
| 389 | clear_inode(ip); | 339 | clear_inode(ip); |
| 390 | call_rcu(&ip->i_rcu, vxfs_i_callback); | ||
| 391 | } | 340 | } |
diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h index 93d01148e5db..ad6b77c0ebcc 100644 --- a/fs/freevxfs/vxfs_inode.h +++ b/fs/freevxfs/vxfs_inode.h | |||
| @@ -151,6 +151,8 @@ struct vxfs_dinode { | |||
| 151 | * The inode as represented in the main memory. | 151 | * The inode as represented in the main memory. |
| 152 | */ | 152 | */ |
| 153 | struct vxfs_inode_info { | 153 | struct vxfs_inode_info { |
| 154 | struct inode vfs_inode; | ||
| 155 | |||
| 154 | __u32 vii_mode; | 156 | __u32 vii_mode; |
| 155 | __u32 vii_nlink; /* Link count */ | 157 | __u32 vii_nlink; /* Link count */ |
| 156 | __u32 vii_uid; /* UID */ | 158 | __u32 vii_uid; /* UID */ |
| @@ -183,4 +185,9 @@ struct vxfs_inode_info { | |||
| 183 | #define vii_ext4 vii_org.ext4 | 185 | #define vii_ext4 vii_org.ext4 |
| 184 | #define vii_typed vii_org.typed | 186 | #define vii_typed vii_org.typed |
| 185 | 187 | ||
| 188 | static inline struct vxfs_inode_info *VXFS_INO(struct inode *inode) | ||
| 189 | { | ||
| 190 | return container_of(inode, struct vxfs_inode_info, vfs_inode); | ||
| 191 | } | ||
| 192 | |||
| 186 | #endif /* _VXFS_INODE_H_ */ | 193 | #endif /* _VXFS_INODE_H_ */ |
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 40125cc825f2..dfa775ef4d1d 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c | |||
| @@ -52,6 +52,8 @@ MODULE_AUTHOR("Christoph Hellwig"); | |||
| 52 | MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver"); | 52 | MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver"); |
| 53 | MODULE_LICENSE("Dual BSD/GPL"); | 53 | MODULE_LICENSE("Dual BSD/GPL"); |
| 54 | 54 | ||
| 55 | static struct kmem_cache *vxfs_inode_cachep; | ||
| 56 | |||
| 55 | /** | 57 | /** |
| 56 | * vxfs_put_super - free superblock resources | 58 | * vxfs_put_super - free superblock resources |
| 57 | * @sbp: VFS superblock. | 59 | * @sbp: VFS superblock. |
| @@ -117,7 +119,31 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 117 | return 0; | 119 | return 0; |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 122 | static struct inode *vxfs_alloc_inode(struct super_block *sb) | ||
| 123 | { | ||
| 124 | struct vxfs_inode_info *vi; | ||
| 125 | |||
| 126 | vi = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL); | ||
| 127 | if (!vi) | ||
| 128 | return NULL; | ||
| 129 | return &vi->vfs_inode; | ||
| 130 | } | ||
| 131 | |||
| 132 | static void vxfs_i_callback(struct rcu_head *head) | ||
| 133 | { | ||
| 134 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
| 135 | |||
| 136 | kmem_cache_free(vxfs_inode_cachep, VXFS_INO(inode)); | ||
| 137 | } | ||
| 138 | |||
| 139 | static void vxfs_destroy_inode(struct inode *inode) | ||
| 140 | { | ||
| 141 | call_rcu(&inode->i_rcu, vxfs_i_callback); | ||
| 142 | } | ||
| 143 | |||
| 120 | static const struct super_operations vxfs_super_ops = { | 144 | static const struct super_operations vxfs_super_ops = { |
| 145 | .alloc_inode = vxfs_alloc_inode, | ||
| 146 | .destroy_inode = vxfs_destroy_inode, | ||
| 121 | .evict_inode = vxfs_evict_inode, | 147 | .evict_inode = vxfs_evict_inode, |
| 122 | .put_super = vxfs_put_super, | 148 | .put_super = vxfs_put_super, |
| 123 | .statfs = vxfs_statfs, | 149 | .statfs = vxfs_statfs, |
| @@ -206,6 +232,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) | |||
| 206 | goto out; | 232 | goto out; |
| 207 | } | 233 | } |
| 208 | 234 | ||
| 235 | sbp->s_op = &vxfs_super_ops; | ||
| 209 | sbp->s_fs_info = infp; | 236 | sbp->s_fs_info = infp; |
| 210 | 237 | ||
| 211 | if (!vxfs_try_sb_magic(sbp, silent, 1, | 238 | if (!vxfs_try_sb_magic(sbp, silent, 1, |
| @@ -256,7 +283,6 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) | |||
| 256 | goto out; | 283 | goto out; |
| 257 | } | 284 | } |
| 258 | 285 | ||
| 259 | sbp->s_op = &vxfs_super_ops; | ||
| 260 | root = vxfs_iget(sbp, VXFS_ROOT_INO); | 286 | root = vxfs_iget(sbp, VXFS_ROOT_INO); |
| 261 | if (IS_ERR(root)) { | 287 | if (IS_ERR(root)) { |
| 262 | ret = PTR_ERR(root); | 288 | ret = PTR_ERR(root); |
