X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjfs%2Fjfs_imap.c;h=0c1cde98c6ade01c784baee11b1f5b0fd53bf51a;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=865334f6c8afce4e1a1685700e0e4dea5f9b21de;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 865334f6c..0c1cde98c 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -1,5 +1,5 @@ /* - * Copyright (C) International Business Machines Corp., 2000-2003 + * Copyright (C) International Business Machines Corp., 2000-2004 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include "jfs_incore.h" #include "jfs_filsys.h" @@ -130,7 +132,7 @@ int diMount(struct inode *ipimap) struct inomap *imap; struct metapage *mp; int index; - struct dinomap *dinom_le; + struct dinomap_disk *dinom_le; /* * allocate/initialize the in-memory inode map control structure @@ -153,7 +155,7 @@ int diMount(struct inode *ipimap) } /* copy the on-disk version to the in-memory version. */ - dinom_le = (struct dinomap *) mp->data; + dinom_le = (struct dinomap_disk *) mp->data; imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag); imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag); atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos)); @@ -241,7 +243,7 @@ int diUnmount(struct inode *ipimap, int mounterror) */ int diSync(struct inode *ipimap) { - struct dinomap *dinom_le; + struct dinomap_disk *dinom_le; struct inomap *imp = JFS_IP(ipimap)->i_imap; struct metapage *mp; int index; @@ -259,7 +261,7 @@ int diSync(struct inode *ipimap) } /* copy the in-memory version to the on-disk version */ - dinom_le = (struct dinomap *) mp->data; + dinom_le = (struct dinomap_disk *) mp->data; dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag); dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag); dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos)); @@ -504,6 +506,9 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) ip->i_mapping->a_ops = &jfs_aops; mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS); + /* Allocations to metadata inodes should not affect quotas */ + ip->i_flags |= S_NOQUOTA; + if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) { sbi->gengen = le32_to_cpu(dp->di_gengen); sbi->inostamp = le32_to_cpu(dp->di_inostamp); @@ -1023,7 +1028,7 @@ int diFree(struct inode *ip) */ iagp->inofreefwd = cpu_to_le32(imap->im_agctl[agno].inofree); - iagp->inofreeback = -1; + iagp->inofreeback = cpu_to_le32(-1); imap->im_agctl[agno].inofree = iagno; } IREAD_UNLOCK(ipimap); @@ -1033,7 +1038,7 @@ int diFree(struct inode *ip) * inodes (i.e., the inode being freed is the first free * inode of extent), */ - if (iagp->wmap[extno] == ONES) { + if (iagp->wmap[extno] == cpu_to_le32(ONES)) { sword = extno >> L2EXTSPERSUM; bitno = extno & (EXTSPERSUM - 1); iagp->inosmap[sword] &= @@ -1181,7 +1186,7 @@ int diFree(struct inode *ip) iagp->extfreefwd = cpu_to_le32(imap->im_agctl[agno].extfree); - iagp->extfreeback = -1; + iagp->extfreeback = cpu_to_le32(-1); imap->im_agctl[agno].extfree = iagno; } else { /* remove the iag from the ag extent list if all extents @@ -1197,7 +1202,7 @@ int diFree(struct inode *ip) imap->im_agctl[agno].extfree = le32_to_cpu(iagp->extfreefwd); - iagp->extfreefwd = iagp->extfreeback = -1; + iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1); IAGFREE_LOCK(imap); iagp->iagfree = cpu_to_le32(imap->im_freeiag); @@ -1219,7 +1224,7 @@ int diFree(struct inode *ip) imap->im_agctl[agno].inofree = le32_to_cpu(iagp->inofreefwd); - iagp->inofreefwd = iagp->inofreeback = -1; + iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1); } /* update the inode extent address and working map @@ -1280,6 +1285,7 @@ int diFree(struct inode *ip) * to be freed by the transaction; */ tid = txBegin(ipimap->i_sb, COMMIT_FORCE); + down(&JFS_IP(ipimap)->commit_sem); /* acquire tlock of the iag page of the freed ixad * to force the page NOHOMEOK (even though no data is @@ -1312,6 +1318,7 @@ int diFree(struct inode *ip) rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); txEnd(tid); + up(&JFS_IP(ipimap)->commit_sem); /* unlock the AG inode map information */ AG_UNLOCK(imap, agno); @@ -2061,7 +2068,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) { int extno, bitno, agno, sword, rc; struct metapage *amp = NULL, *bmp = NULL; - struct iag *aiagp = 0, *biagp = 0; + struct iag *aiagp = NULL, *biagp = NULL; u32 mask; /* check if this is the last free inode within the iag. @@ -2125,7 +2132,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) * allocated. if so, update the free inode summary * map to reflect this. */ - if (iagp->wmap[extno] == ONES) { + if (iagp->wmap[extno] == cpu_to_le32(ONES)) { sword = extno >> L2EXTSPERSUM; bitno = extno & (EXTSPERSUM - 1); iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno); @@ -2147,7 +2154,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) imap->im_agctl[agno].inofree = le32_to_cpu(iagp->inofreefwd); } - iagp->inofreefwd = iagp->inofreeback = -1; + iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1); } /* update the free inode count at the iag, ag, inode @@ -2207,7 +2214,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) { int agno, iagno, fwd, back, freei = 0, sword, rc; - struct iag *aiagp = 0, *biagp = 0, *ciagp = 0; + struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL; struct metapage *amp, *bmp, *cmp, *dmp; struct inode *ipimap; s64 blkno, hint; @@ -2356,7 +2363,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) imap->im_agctl[agno].extfree = le32_to_cpu(iagp->extfreefwd); - iagp->extfreefwd = iagp->extfreeback = -1; + iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1); } else { /* if the iag has all free extents (newly allocated iag), * add the iag to the ag free extent list. @@ -2366,7 +2373,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) aiagp->extfreeback = cpu_to_le32(iagno); iagp->extfreefwd = cpu_to_le32(fwd); - iagp->extfreeback = -1; + iagp->extfreeback = cpu_to_le32(-1); imap->im_agctl[agno].extfree = iagno; } } @@ -2380,7 +2387,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) iagp->inofreefwd = cpu_to_le32(imap->im_agctl[agno].inofree); - iagp->inofreeback = -1; + iagp->inofreeback = cpu_to_le32(-1); imap->im_agctl[agno].inofree = iagno; } @@ -2586,9 +2593,9 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) /* init the iag */ memset(iagp, 0, sizeof(struct iag)); iagp->iagnum = cpu_to_le32(iagno); - iagp->inofreefwd = iagp->inofreeback = -1; - iagp->extfreefwd = iagp->extfreeback = -1; - iagp->iagfree = -1; + iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1); + iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1); + iagp->iagfree = cpu_to_le32(-1); iagp->nfreeinos = 0; iagp->nfreeexts = cpu_to_le32(EXTSPERIAG); @@ -2596,36 +2603,28 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) * summary map initialization handled by bzero). */ for (i = 0; i < SMAPSZ; i++) - iagp->inosmap[i] = ONES; + iagp->inosmap[i] = cpu_to_le32(ONES); + /* + * Invalidate the page after writing and syncing it. + * After it's initialized, we access it in a different + * address space + */ + set_bit(META_discard, &mp->flag); flush_metapage(mp); -#ifdef _STILL_TO_PORT - /* synchronously write the iag page */ - if (bmWrite(bp)) { - /* Free the blocks allocated for the iag since it was - * not successfully added to the inode map - */ - dbFree(ipimap, xaddr, (s64) xlen); - - /* release the inode map lock */ - IWRITE_UNLOCK(ipimap); - - rc = -EIO; - goto out; - } - - /* Now the iag is on disk */ /* * start tyransaction of update of the inode map * addressing structure pointing to the new iag page; */ -#endif /* _STILL_TO_PORT */ tid = txBegin(sb, COMMIT_FORCE); + down(&JFS_IP(ipimap)->commit_sem); /* update the inode map addressing structure to point to it */ if ((rc = xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { + txEnd(tid); + up(&JFS_IP(ipimap)->commit_sem); /* Free the blocks allocated for the iag since it was * not successfully added to the inode map */ @@ -2639,7 +2638,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) /* update the inode map's inode to reflect the extension */ ipimap->i_size += PSIZE; - ipimap->i_blocks += LBLK2PBLK(sb, xlen); + inode_add_bytes(ipimap, PSIZE); /* * txCommit(COMMIT_FORCE) will synchronously write address @@ -2650,6 +2649,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); txEnd(tid); + up(&JFS_IP(ipimap)->commit_sem); duplicateIXtree(sb, blkno, xlen, &xaddr); @@ -2683,7 +2683,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) /* remove the iag from the iag free list */ imap->im_freeiag = le32_to_cpu(iagp->iagfree); - iagp->iagfree = -1; + iagp->iagfree = cpu_to_le32(-1); /* set the return iag number and buffer pointer */ *iagnop = iagno; @@ -2910,7 +2910,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) { int rc, rcx = 0; struct inomap *imap = JFS_IP(ipimap)->i_imap; - struct iag *iagp = 0, *hiagp = 0; + struct iag *iagp = NULL, *hiagp = NULL; struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap; struct metapage *bp, *hbp; int i, n, head; @@ -2931,8 +2931,8 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) /* init per AG control information im_agctl[] */ for (i = 0; i < MAXAG; i++) { - imap->im_agctl[i].inofree = -1; /* free inode list */ - imap->im_agctl[i].extfree = -1; /* free extent list */ + imap->im_agctl[i].inofree = -1; + imap->im_agctl[i].extfree = -1; imap->im_agctl[i].numinos = 0; /* number of backed inodes */ imap->im_agctl[i].numfree = 0; /* number of free backed inodes */ } @@ -2977,18 +2977,18 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) /* if any backed free inodes, insert at AG free inode list */ if ((int) le32_to_cpu(iagp->nfreeinos) > 0) { - if ((head = imap->im_agctl[n].inofree) == -1) - iagp->inofreefwd = iagp->inofreeback = -1; - else { + if ((head = imap->im_agctl[n].inofree) == -1) { + iagp->inofreefwd = cpu_to_le32(-1); + iagp->inofreeback = cpu_to_le32(-1); + } else { if ((rc = diIAGRead(imap, head, &hbp))) { rcx = rc; goto nextiag; } hiagp = (struct iag *) hbp->data; - hiagp->inofreeback = - le32_to_cpu(iagp->iagnum); + hiagp->inofreeback = iagp->iagnum; iagp->inofreefwd = cpu_to_le32(head); - iagp->inofreeback = -1; + iagp->inofreeback = cpu_to_le32(-1); write_metapage(hbp); } @@ -3003,9 +3003,10 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) /* if any free extents, insert at AG free extent list */ if (le32_to_cpu(iagp->nfreeexts) > 0) { - if ((head = imap->im_agctl[n].extfree) == -1) - iagp->extfreefwd = iagp->extfreeback = -1; - else { + if ((head = imap->im_agctl[n].extfree) == -1) { + iagp->extfreefwd = cpu_to_le32(-1); + iagp->extfreeback = cpu_to_le32(-1); + } else { if ((rc = diIAGRead(imap, head, &hbp))) { rcx = rc; goto nextiag; @@ -3013,7 +3014,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) hiagp = (struct iag *) hbp->data; hiagp->extfreeback = iagp->iagnum; iagp->extfreefwd = cpu_to_le32(head); - iagp->extfreeback = -1; + iagp->extfreeback = cpu_to_le32(-1); write_metapage(hbp); } @@ -3060,7 +3061,7 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, if (readSuper(sb, &bh)) return; j_sb = (struct jfs_superblock *)bh->b_data; - j_sb->s_flag |= JFS_BAD_SAIT; + j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT); mark_buffer_dirty(bh); sync_dirty_buffer(bh); @@ -3079,7 +3080,7 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, } /* update the inode map's inode to reflect the extension */ ip->i_size += PSIZE; - ip->i_blocks += LBLK2PBLK(sb, xlen); + inode_add_bytes(ip, PSIZE); txCommit(tid, 1, &ip, COMMIT_FORCE); cleanup: txEnd(tid); @@ -3098,14 +3099,21 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, static int copy_from_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; jfs_ip->fileset = le32_to_cpu(dip->di_fileset); jfs_ip->mode2 = le32_to_cpu(dip->di_mode); ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; ip->i_nlink = le32_to_cpu(dip->di_nlink); - ip->i_uid = le32_to_cpu(dip->di_uid); - ip->i_gid = le32_to_cpu(dip->di_gid); + + uid = le32_to_cpu(dip->di_uid); + gid = le32_to_cpu(dip->di_gid); + ip->i_uid = INOXID_UID(XID_TAG(ip), uid, gid); + ip->i_gid = INOXID_GID(XID_TAG(ip), uid, gid); + ip->i_xid = INOXID_XID(XID_TAG(ip), uid, gid, 0); + ip->i_size = le64_to_cpu(dip->di_size); ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); @@ -3156,6 +3164,8 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) static void copy_to_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + uid_t uid; + gid_t gid; dip->di_fileset = cpu_to_le32(jfs_ip->fileset); dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); @@ -3164,8 +3174,11 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) dip->di_size = cpu_to_le64(ip->i_size); dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); dip->di_nlink = cpu_to_le32(ip->i_nlink); - dip->di_uid = cpu_to_le32(ip->i_uid); - dip->di_gid = cpu_to_le32(ip->i_gid); + + uid = XIDINO_UID(XID_TAG(ip), ip->i_uid, ip->i_xid); + gid = XIDINO_GID(XID_TAG(ip), ip->i_gid, ip->i_xid); + dip->di_uid = cpu_to_le32(uid); + dip->di_gid = cpu_to_le32(gid); /* * mode2 is only needed for storing the higher order bits. * Trust i_mode for the lower order ones