0001
0002
0003
0004
0005
0006 #include <linux/fs.h>
0007 #include <linux/quotaops.h>
0008 #include "jfs_incore.h"
0009 #include "jfs_inode.h"
0010 #include "jfs_superblock.h"
0011 #include "jfs_dmap.h"
0012 #include "jfs_extent.h"
0013 #include "jfs_debug.h"
0014
0015
0016
0017
0018 static int extBalloc(struct inode *, s64, s64 *, s64 *);
0019 static s64 extRoundDown(s64 nb);
0020
0021 #define DPD(a) (printk("(a): %d\n",(a)))
0022 #define DPC(a) (printk("(a): %c\n",(a)))
0023 #define DPL1(a) \
0024 { \
0025 if ((a) >> 32) \
0026 printk("(a): %x%08x ",(a)); \
0027 else \
0028 printk("(a): %x ",(a) << 32); \
0029 }
0030 #define DPL(a) \
0031 { \
0032 if ((a) >> 32) \
0033 printk("(a): %x%08x\n",(a)); \
0034 else \
0035 printk("(a): %x\n",(a) << 32); \
0036 }
0037
0038 #define DPD1(a) (printk("(a): %d ",(a)))
0039 #define DPX(a) (printk("(a): %08x\n",(a)))
0040 #define DPX1(a) (printk("(a): %08x ",(a)))
0041 #define DPS(a) (printk("%s\n",(a)))
0042 #define DPE(a) (printk("\nENTERING: %s\n",(a)))
0043 #define DPE1(a) (printk("\nENTERING: %s",(a)))
0044 #define DPS1(a) (printk(" %s ",(a)))
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 int
0070 extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
0071 {
0072 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
0073 s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
0074 int rc;
0075 int xflag;
0076
0077
0078 txBeginAnon(ip->i_sb);
0079
0080
0081 mutex_lock(&JFS_IP(ip)->commit_mutex);
0082
0083
0084 if (xlen > MAXXLEN)
0085 xlen = MAXXLEN;
0086
0087
0088 xoff = pno << sbi->l2nbperpage;
0089
0090
0091 if ((hint = addressXAD(xp))) {
0092
0093 nxlen = lengthXAD(xp);
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 if (offsetXAD(xp) + nxlen == xoff &&
0104 abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false))
0105 xaddr = hint + nxlen;
0106
0107
0108 hint += (nxlen - 1);
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 nxlen = xlen;
0122 if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
0123 mutex_unlock(&JFS_IP(ip)->commit_mutex);
0124 return (rc);
0125 }
0126
0127
0128 rc = dquot_alloc_block(ip, nxlen);
0129 if (rc) {
0130 dbFree(ip, nxaddr, (s64) nxlen);
0131 mutex_unlock(&JFS_IP(ip)->commit_mutex);
0132 return rc;
0133 }
0134
0135
0136 xflag = abnr ? XAD_NOTRECORDED : 0;
0137
0138
0139
0140
0141
0142 if (xaddr && xaddr == nxaddr)
0143 rc = xtExtend(0, ip, xoff, (int) nxlen, 0);
0144 else
0145 rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
0146
0147
0148
0149
0150 if (rc) {
0151 dbFree(ip, nxaddr, nxlen);
0152 dquot_free_block(ip, nxlen);
0153 mutex_unlock(&JFS_IP(ip)->commit_mutex);
0154 return (rc);
0155 }
0156
0157
0158 XADaddress(xp, nxaddr);
0159 XADlength(xp, nxlen);
0160 XADoffset(xp, xoff);
0161 xp->flag = xflag;
0162
0163 mark_inode_dirty(ip);
0164
0165 mutex_unlock(&JFS_IP(ip)->commit_mutex);
0166
0167
0168
0169
0170
0171 if (test_and_clear_cflag(COMMIT_Synclist,ip))
0172 jfs_commit_inode(ip, 0);
0173
0174 return (0);
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 int extHint(struct inode *ip, s64 offset, xad_t * xp)
0193 {
0194 struct super_block *sb = ip->i_sb;
0195 int nbperpage = JFS_SBI(sb)->nbperpage;
0196 s64 prev;
0197 int rc = 0;
0198 s64 xaddr;
0199 int xlen;
0200 int xflag;
0201
0202
0203 XADaddress(xp, 0);
0204
0205
0206
0207
0208 prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
0209
0210
0211
0212 if (prev < 0)
0213 goto out;
0214
0215 rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0);
0216
0217 if ((rc == 0) && xlen) {
0218 if (xlen != nbperpage) {
0219 jfs_error(ip->i_sb, "corrupt xtree\n");
0220 rc = -EIO;
0221 }
0222 XADaddress(xp, xaddr);
0223 XADlength(xp, xlen);
0224 XADoffset(xp, prev);
0225
0226
0227
0228
0229 xp->flag = xflag & XAD_NOTRECORDED;
0230 } else
0231 rc = 0;
0232
0233 out:
0234 return (rc);
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 int extRecord(struct inode *ip, xad_t * xp)
0253 {
0254 int rc;
0255
0256 txBeginAnon(ip->i_sb);
0257
0258 mutex_lock(&JFS_IP(ip)->commit_mutex);
0259
0260
0261 rc = xtUpdate(0, ip, xp);
0262
0263 mutex_unlock(&JFS_IP(ip)->commit_mutex);
0264 return rc;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298 static int
0299 extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
0300 {
0301 struct jfs_inode_info *ji = JFS_IP(ip);
0302 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
0303 s64 nb, nblks, daddr, max;
0304 int rc, nbperpage = sbi->nbperpage;
0305 struct bmap *bmp = sbi->bmap;
0306 int ag;
0307
0308
0309
0310
0311
0312
0313
0314 max = (s64) 1 << bmp->db_maxfreebud;
0315 if (*nblocks >= max && *nblocks > nbperpage)
0316 nb = nblks = (max > nbperpage) ? max : nbperpage;
0317 else
0318 nb = nblks = *nblocks;
0319
0320
0321 while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) {
0322
0323
0324
0325 if (rc != -ENOSPC)
0326 return (rc);
0327
0328
0329 nb = min(nblks, extRoundDown(nb));
0330
0331
0332 if (nb < nbperpage)
0333 return (rc);
0334 }
0335
0336 *nblocks = nb;
0337 *blkno = daddr;
0338
0339 if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) {
0340 ag = BLKTOAG(daddr, sbi);
0341 spin_lock_irq(&ji->ag_lock);
0342 if (ji->active_ag == -1) {
0343 atomic_inc(&bmp->db_active[ag]);
0344 ji->active_ag = ag;
0345 } else if (ji->active_ag != ag) {
0346 atomic_dec(&bmp->db_active[ji->active_ag]);
0347 atomic_inc(&bmp->db_active[ag]);
0348 ji->active_ag = ag;
0349 }
0350 spin_unlock_irq(&ji->ag_lock);
0351 }
0352
0353 return (0);
0354 }
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368 static s64 extRoundDown(s64 nb)
0369 {
0370 int i;
0371 u64 m, k;
0372
0373 for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) {
0374 if (m & nb)
0375 break;
0376 }
0377
0378 i = 63 - i;
0379 k = (u64) 1 << i;
0380 k = ((k - 1) & nb) ? k : k >> 1;
0381
0382 return (k);
0383 }